The question, as I understand it, is why the address of the local variable in main is different when the program starts from the shell or when it is started from gdb.
Here is an example program to show the difference:
mp@ubuntu :~$ cat sc #include<stdio.h> int main(int argc, char **argv) { char buffer[20]; system("env"); printf("%s %p\n", argv[0], buffer); return 0; }
We will run it in a clean environment. (I also disabled ASLR).
mp@ubuntu :~$ env -i sh $ ./s PWD=/home/mp ./s 0xbffffe48
$ gdb ./s (gdb) run Starting program: /home/mp/s COLUMNS=80 PWD=/home/mp LINES=42 /home/mp/s 0xbffffe08
Exiting the gdb print &buffer command matches the programmatic idea of ββthe address, but they are both different from when the program was run in the shell.
(gdb) b 6 Breakpoint 1 at 0x804849c: file sc, line 6. (gdb) run Starting program: /home/mp/s COLUMNS=80 PWD=/home/mp LINES=42 Breakpoint 1, main (argc=1, argv=0xbffffed4) at sc:6 6 printf("%s %p\n", argv[0], buffer); (gdb) p &buffer $1 = (char (*)[20]) 0xbffffe08 (gdb) n /home/mp/s 0xbffffe08 8 return 0;
There are several things that make a difference:
- gdb calls a program with an absolute path name, so the argv array is larger.
- gdb sets (or in this case adds) two environment variables. This is done in
readline/shell.c:sh_set_lines_and_columns() . Thus, the environment array is larger.
To remove these two variables from the environment, you can use to disable the environment or set exec-wrapper to run env -u ... Thus, the program addresses under gdb are the same as when running in the shell (if we use the absolute path).
$ `pwd`/s PWD=/home/mp /home/mp/s 0xbffffe28 $ gdb `pwd`/s (gdb) set exec-wrapper env -u LINES -u COLUMNS (gdb) run Starting program: /home/mp/s PWD=/home/mp /home/mp/s 0xbffffe28