1

Follow-up

Hmmm I am not sure if I am doing the right thing. Thanks for all the helps thus far.

My previous thread: Is this really the address

I am making new thread because this is really a separate problem, and the core problem.

Please bear with me, thank you.


Let me restate my goal:

I want to be able to look into the memory address of each variable (we know the entry address of the program, and we know how many bytes are set aside from reading the assembly code). Suppose we are given the following source code:

Source Code

int main()
{ 
   int a = 15;
   int b;
   int c;
   b = c;
   c = c+1;
return 0;   
}

We should be able to find out the address of variable a and c, and the values in these memory addresses.

Using gdb layout asm I get this

│0x80483f4 <main()>      push   %ebp                                              │
   │0x80483f5 <main()+1>    mov    %esp,%ebp                                         │
   │0x80483f7 <main()+3>    sub    $0x10,%esp                                        │
   │0x80483fa <main()+6>    movl   $0xf,-0x4(%ebp)                                   │
   │0x8048401 <main()+13>   mov    -0x8(%ebp),%eax                                   │
   │0x8048404 <main()+16>   mov    %eax,-0xc(%ebp)                                   │
   │0x8048407 <main()+19>   addl   $0x1,-0x8(%ebp)                                   │
   │0x804840b <main()+23>   mov    $0x0,%eax                                         │
   │0x8048410 <main()+28>   leave                                                    │
   │0x8048411 <main()+29>   ret                                                      │
   │0x8048412               nop      


// the statement int a = 15 is in the address 0x80483fa
// I want to get the value 15
x/w 0x80483fd     <== this will print 15

But it doesn't make sense to me because from what I recalled, the variables are supposed to be in ebp - 0x10 right?

// the starting address of the program is 0x80483f4
// minus 0x10 we get 0x80483E4
x/w 0x80483E4    <== will print a big number

// Since b = c, I should be able to get that as I decrement, but no luck

I don't think I know what I am doing...? On one hand, the automatic variables are destroyed as soon as the program terminates...

PS: I really can't use cout, or printf, or setting breakpoints or watcher while debugging.

So doing print $ebp will not work because there is no active register (remember the program terminates - no breakpoint!). So commands like info locals, info registers aren't available.

I have been spending the whole day trying to figure out what is going on. I really appreciate all the helps and I am looking forward to getting more. Thanks.

What should I do?? I need to look at the value of variable a, b, c. How can this be done?

Thank you very much.


Not really a homework, but a class discussion.

Community
  • 1
  • 1
CppLearner
  • 16,273
  • 32
  • 108
  • 163

1 Answers1

1

These variables do not have one particular memory location. They are stack variables. So you cannot rely on them being in memory after the program terminates, because they are considered out of scope after the function in which they are created returns, allowing the address at which they resided to be reused for storing other content.

Imagine you have a function whose source looks like this:

int foo(int x) {
    int y = x;
    if (y == 0) {
        return 0;
    }
    return foo(x-1)+1;
}

If you call foo(1), the variable y will exist at two different memory addresses, one for each of the two stack frames created for the two nested invocations of foo (foo(1) and foo(0)). If you call foo(10), there will be eleven instances of y, each one holding a different value and residing at a different memory address.

If you do not use a breakpoint, then the variables for all intents and purposes do not exist. They only have storage allocated when the program is running and the current stack contains a frame from the function in which they reside. You cannot grab them postmortem (except from a core dump, which is a form of breakpoint really).

Sum-up: if you do not analyze the program while it is running, either via breaking to a debugger or via adding some code that will print/set aside values, you can not inspect stack variables. These are stack variables. If you must have them be single-instance, you should make them heap-allocated global variables by moving them outside of function scope.

Borealid
  • 95,191
  • 9
  • 106
  • 122
  • THANKS for the input. OMG. Yes. You are very correct. But from disassmbling the code, we know the entry address of the program. Can't we just decrement 4 bytes? It should be the address of the first local variable, int a, if we were still running the program. Please also correct my terminology: when we are talking about $ebp - 0x4, we can still use "address" as an alias to "location", right? – CppLearner Oct 02 '11 at 04:00
  • 1
    @JohnWong The entry address of the program is the address of the `main` function. That has no relation to where the stack frame for `main` resides. The *code* is at one place in memory, and the *data* it uses are at another (in this case, atop the stack). It is not the case that a particular function always places its stack frame at the same spot; if that were true, recursive functions could not exist. The instances of stack variables are not located near where the instructions making up the function reside. – Borealid Oct 02 '11 at 04:05
  • 1
    @JohnWong Imagine a recipe book - `main` is a recipe for cookies. `a`, `b`, and `c` are ingredients. You don't store the eggs for your cookies **in** the recipe book. Each time you want to make the recipe you get them out of the fridge and put them in a fresh space on the counter. The entry point is a bookmark in the recipe book. The counter space is the stack. After you're done cooking and cleaning up, the counter is empty and the recipe book still has the same stuff in it - but no eggs! – Borealid Oct 02 '11 at 04:10
  • I really really appreciate your help here. But during the runtime, it is TRUE that we get the location of our variables by negatve offset from esp (which at that point,ebp also points to the esp). I will have to email my professor again. I will come back adn tell you what he said later. Thanks. I really really appreciate what you have said so far. Very true. and u have no idea how much it meant to me that you helped me. – CppLearner Oct 02 '11 at 04:17
  • 1
    @JohnWong "during the runtime". **When the program is running**, you absolutely can find where the variables reside (on the stack). However, that location may not be consistent across different runs - in fact, on modern machines, it's purposefully randomized as a security measure. – Borealid Oct 02 '11 at 11:43
  • Thanks. I don't think it is possible to step through the program one line at a time without setting a breakpoint in GDB. It can be done in Visual Studio. Thank you, Borealid. – CppLearner Oct 02 '11 at 15:54
  • @JohnWong stepping through the program one line at a time in gdb is done via the "n" command. – Borealid Oct 03 '11 at 01:12
  • Yes. I can step through it now. Thanks :] Professor didn't want us to manually set breakpoint ourselves, but using the command START is fine. – CppLearner Oct 08 '11 at 17:16