0

I disassemble the next simple source:

#include <stdio.h>

void func3() {
   int i = 11;
   printf("\t\t\t[in func3] i = %d\n", i);
}

void func2() {
   int i = 7;
   printf("\t\t[in func2] i = %d\n", i);
   func3();
   printf("\t\t[back in func2] i = %d\n", i);
}

void func1() {
   int i = 5;
   printf("\t[in func1] i = %d\n", i);
   func2();
   printf("\t[back in func1] i = %d\n", i);
}

int main() {
   int i = 3;
   printf("[in main] i = %d\n", i);
   func1();
   printf("[back in main] i = %d\n", i);
}

and break with gdb: main then func1:

Breakpoint 2, func1 () at /home/storenth/scope.c:16
16     int i = 5;
(gdb) i r rbp rsp
rbp            0x7fffffffda50   0x7fffffffda50
rsp            0x7fffffffda40   0x7fffffffda40
(gdb) x/4x 0x7fffffffda50
0x7fffffffda50: 0x00007fffffffda70  0x0000555555554731
0x7fffffffda60: 0x00007fffffffdb50  0x0000000300000000
(gdb) x/4x 0x7fffffffda40
0x7fffffffda40: 0x00007ffff7de59f0  0x0000000000000000
0x7fffffffda50: 0x00007fffffffda70  0x0000555555554731
(gdb) nexti
17     printf("\t[in func1] i = %d\n", i);
(gdb) x/4x 0x7fffffffda40
0x7fffffffda40: 0x00007ffff7de59f0  0x0000000500000000
0x7fffffffda50: 0x00007fffffffda70  0x0000555555554731
(gdb) x/4xw 0x7fffffffda40
0x7fffffffda40: 0xf7de59f0  0x00007fff  0x00000000  0x00000005
(gdb) x/x 0x00007ffff7de59f0
0x7ffff7de59f0 <_dl_fini>:  0xe5894855

So, I expect to see only 0x5 under the RSP in the current stack frame because of the variable int i = 5; but also get 0x00007ffff7de59f0 which point me at <_dl_fini>:0xe5894855.

  1. Where am I wrong in my reasoning?
  2. And what is <_dl_fini>?
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
storenth
  • 967
  • 11
  • 18
  • Probably left over from something `_start` did before calling `main`. `main` has to align the stack before making another call, so there's no reason to expect it to overwrite every qword of the space it allocates. (Especially given GCC's missed-optimization bugs that result in allocating 16 extra bytes of stack space sometimes.) If you look at the asm for `main`, this should be obvious. e.g. [Why does the compiler allocate more than needed in the stack?](https://stackoverflow.com/q/37770751) – Peter Cordes Aug 24 '20 at 09:00
  • 1
    Also, your title is incorrect. The RSP *register* doesn't hold the address of `_dl_fini`. That address is in stack memory *pointed to* by RSP. – Peter Cordes Aug 24 '20 at 09:03
  • @PeterCordes yes, I examine its behavior with more then one variable and boom) Btw, if I initialized 4 variable in `func1` they stored in unexpected order for me in the stack: `0x7fffffffda4c`, next variable `0x7fffffffda50` etc, why not vice versa in case of the rule: The stack grows up toward lower memory addresses? – storenth Aug 24 '20 at 10:10
  • 2
    Yes, the stack grows downward. This is well documented all over the place, do some searching if you want to know more. But within a single function's stack frame, there's no guarantee that layout has anything to do with source order of declarations. That's just a detail of compiler internals. Again, widely discussed in many [tag:assembly] SO questions about stack frame layout. – Peter Cordes Aug 24 '20 at 10:17

0 Answers0