Joao Daniel
Joao Daniel

Reputation: 36

stack frames and gdb

I'm new to reverse engeneering. I wrote the following C code to help me understand a bit more about stack frames.

#include <stdio.h>

int sum(int a, int b,int c)
{
        return(a+b+c);
}

int media(int a, int b,int c)
{
        int total;
        total = a + b + c;
        return (total/3);

}

int main ()
{
        int num1,num2,num3;
        char keypress[1];

        num1 = 5;
        num2 = 10;
        num3 = 15;

        printf ("\nCalling sum function\n");
        sum(num1,num2,num3);
        printf ("\nWaiting a keypress to call media function\n");
        scanf ("%c",keypress);
        media(num1,num2,num3);
        printf ("\nWaiting a keypress to end\n");
        scanf ("%c",keypress);
        return(0);
}

As far as I know every time you call a function a stack frame is created (see: ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_41.html). So, my goal with the above C code is to see, at least, three stack-frames.

1) main function - stack frame

2) sum function - stack frame

3) media function - stack frame

BTW: Those printfs are just to help me 'follow' the program in gdb. =)

So I guess if I compare the output of info frame after the program started with the output of info frame just after sum function is called I would get different output right? I did not got it as you can see:

Temporary breakpoint 1, main () at parastack.c:27
warning: Source file is more recent than executable.
27              num1 = 5;
(gdb) nexti
28              num2 = 10;
(gdb) info frame
Stack level 0, frame at 0x7fffffffdf00:
 rip = 0x400605 in main (parastack.c:28); saved rip = 0x7ffff7a3c790
 source language c.
 Arglist at 0x7fffffffdef0, args:
 Locals at 0x7fffffffdef0, Previous frame's sp is 0x7fffffffdf00
 Saved registers:
  rbp at 0x7fffffffdef0, rip at 0x7fffffffdef8
(gdb) nexti
29              num3 = 15;
(gdb) nexti
31              printf ("\nCalling sum function\n");
(gdb) nexti
0x0000000000400618      31              printf ("\nCalling sum function\n");
(gdb) nexti

Calling sum function
32              sum(num1,num2,num3);
(gdb) info frame
Stack level 0, frame at 0x7fffffffdf00:
 rip = 0x40061d in main (parastack.c:32); saved rip = 0x7ffff7a3c790
 source language c.
 Arglist at 0x7fffffffdef0, args:
 Locals at 0x7fffffffdef0, Previous frame's sp is 0x7fffffffdf00
 Saved registers:
  rbp at 0x7fffffffdef0, rip at 0x7fffffffdef8
(gdb) nexti
0x0000000000400620      32              sum(num1,num2,num3);
(gdb) info frame
Stack level 0, frame at 0x7fffffffdf00:
 rip = 0x400620 in main (parastack.c:32); saved rip = 0x7ffff7a3c790
 source language c.
 Arglist at 0x7fffffffdef0, args:
 Locals at 0x7fffffffdef0, Previous frame's sp is 0x7fffffffdf00
 Saved registers:
  rbp at 0x7fffffffdef0, rip at 0x7fffffffdef8

Upvotes: 2

Views: 1055

Answers (3)

Joao Daniel
Joao Daniel

Reputation: 36

Thanks for everyone that helped me. Below are the gdb session with shows that the stack-frame changed.

First I recompiled the C code: gcc -ggdb stack.c -o stack.bin

gdb stack.bin (gdb) break sum (gdb) start (gdb) info frame

Stack level 0, frame at 0x7fffffffe1a0: rip = 0x400653 in main (stack.c:26); saved rip 0x7ffff7a6fead source language c. Arglist at 0x7fffffffe190, args: Locals at 0x7fffffffe190, Previous frame's sp is 0x7fffffffe1a0 Saved registers: rbp at 0x7fffffffe190, rip at 0x7fffffffe198

(gdb) continue Continuing.

Calling sum function

Breakpoint 1, sum (a=5, b=10, c=15) at stack.c:6 6 total = a + b + c;

(gdb) info frame Stack level 0, frame at 0x7fffffffe180: rip = 0x4005dd in sum (stack.c:6); saved rip 0x400684 called by frame at 0x7fffffffe1a0 source language c. Arglist at 0x7fffffffe170, args: a=5, b=10, c=15 Locals at 0x7fffffffe170, Previous frame's sp is 0x7fffffffe180 Saved registers: rbp at 0x7fffffffe170, rip at 0x7fffffffe178

Now I will search/learn more about the information in the output.

Upvotes: 0

Employed Russian
Employed Russian

Reputation: 213887

just after sum function is called

Your problem is that you never actually stopped inside of the sum function. You stopped after you printed that you are about to call it, and then you stepped a few instructions, but you never actually landed inside (it takes a few instructions to prepare arguments, one more to actually call, and few more inside the function to set up the frame).

You should start by setting breakpoints inside sum and media, and doing info frame when these breakpoints are hit. You'll notice that the breakpoint is set a few instructions after the beginning of the function (i.e. after function prolog). The skipped instructions are exactly the ones that set up the new frame.

After you understand how that works, you should progress to using step and next commands.

And after that you can graduate to using disas, stepi and nexti commands.

Upvotes: 3

dcow
dcow

Reputation: 7985

Based on my interpretation of your prose, your understanding of stack frames is slightly off. You are correct that when a function is called a stack frame is created, however, what you're missing is that when a function returns, the stack frame is popped. The stack is in the same state is was before the function began executing except that the program counter contains the address of the first instruction of the statement immediately following the function that just finished executing. So, you should not expect to see 3 stack frames after the two functions in main execute. You will only see one since you're only one frame deep into main().

As for the gdb session, as @Employed Russian points out, you never actually step into any function when printing the stack frame information.

Upvotes: 1

Related Questions