#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;
}
这是我的操作:
(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]) {
如你所见,printf
可以打印出environ[i]
,但是p environ[i]
给我不能在地址 0x0 访问内存
,为什么?
最佳答案
gdb 解析了错误的 environ
符号。 虽然我不知道为什么。请参阅下面的原因。
但是你可以测试一下。将程序更改为:
#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;
}
现在让我们在调试器中运行它。
(gdb) n 7 printf("%p\n", &environ); (gdb) n 0x8049760 8 while(environ[i]) { (gdb) p &environ $1 = (char ***) 0x46328da0 (gdb)
所以。实际程序在其链接期间已将 environ
解析为地址 0x8049760。
当 gdb 要访问 environ
符号时,它解析为 0x46328da0,这是不同的。
编辑。
看来您的 environ
符号实际上链接到 environ@@GLIBC_2.0
符号。
在 gdb 中这样写:
(gdb) p environ
然后按 Tab 键(两次),它会自动完成符号。产生:
(gdb) p environ environ environ@@GLIBC_2.0
environ@@GLIBC_2.0
是实际链接到 extern char **environ
打印它会产生与程序看到的相同的地址,0x8049760:
(gdb) p &'environ@@GLIBC_2.0' $9 = ( *) 0x8049760 (gdb) p ((char**)'environ@@GLIBC_2.0')[i] $10 = 0xbffff6ad "XDG_SESSION_ID=1"
因此,glibc 一度弃用了 environ
符号,并添加了一个更新的版本
关于c - 为什么我不能在 gdb 中打印出环境变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6203455/