#include <unistd.h>
#include <stdio.h>
extern char **environ;
int main(int argc, char *argv[]) {
int i = 0;
while(environ[i]) {
printf("%s\n", environ[i++]);
}
return 0;
}
Here's my ops:
(gdb) n
8 printf("%s\n", environ[i++]);
(gdb) p environ[i]
Cannot access memory at address 0x0
(gdb) n
LOGNAME=root
7 while(environ[i]) {
As you can see,printf
can print out environ[i]
,but p environ[i]
gives me Cannot access memory at address 0x0
,why?
The ptype [ARG] command will print the type. Show activity on this post.
gdb resolves the wrong environ
symbol. I don't know why though. See below as to why.
But you can test it. Change the program to:
#include <unistd.h>
#include <stdio.h>
extern char **environ;
int main(int argc, char *argv[]) {
int i = 0;
printf("%p\n", &environ);
while(environ[i]) {
printf("%s\n", environ[i++]);
}
return 0;
}
Now let's run this in the debugger.
(gdb) n 7 printf("%p\n", &environ); (gdb) n 0x8049760 8 while(environ[i]) { (gdb) p &environ $1 = (char ***) 0x46328da0 (gdb)
So. The actual program has, during its linking, resolved environ
to the address 0x8049760.
When gdb wants to access the environ
symbol, it resolves to 0x46328da0, which is different.
Edit.
It seems your environ
symbol is actually linked to the environ@@GLIBC_2.0
symbol.
In gdb write this:
(gdb) p environ
And hit the tab key (twice), it'll autocomplete the symbols. Which yields:
(gdb) p environ environ environ@@GLIBC_2.0
environ@@GLIBC_2.0
is the one actually linked to the extern char **environ
Printing this yields the same address as the program sees, 0x8049760:
(gdb) p &'environ@@GLIBC_2.0' $9 = ( *) 0x8049760 (gdb) p ((char**)'environ@@GLIBC_2.0')[i] $10 = 0xbffff6ad "XDG_SESSION_ID=1"
So, at one point glibc deprecated the environ
symbol, and added a newer version
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With