[英]Why I can't print out environment variables in gdb?
#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?如您所见,
printf
可以打印出environ[i]
,但是p environ[i]
给了我Cannot access memory at address 0x0
,为什么?
gdb resolves the wrong environ
symbol. environ
解决了错误的环境符号。 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.实际程序在其链接期间已将环境解析为地址
environ
。 When gdb wants to access the environ
symbol, it resolves to 0x46328da0, which is different.当 gdb 想要访问
environ
符号时,它解析为 0x46328da0,这是不同的。
Edit.编辑。 It seems your
environ
symbol is actually linked to the environ@@GLIBC_2.0
symbol.看来您的
environ
符号实际上链接到environ@@GLIBC_2.0
符号。 In gdb write this:在 gdb 中写下:
(gdb) p environ
And hit the tab key (twice), it'll autocomplete the symbols.并按 Tab 键(两次),它会自动完成符号。 Which yields:
产生:
(gdb) p environ environ environ@@GLIBC_2.0
environ@@GLIBC_2.0
is the one actually linked to the extern char **environ
environ@@GLIBC_2.0
是实际链接到extern char **environ
的那个
Printing this yields the same address as the program sees, 0x8049760:打印它会产生与程序看到的地址相同的地址,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因此,glibc 一度弃用了
environ
符号,并添加了一个更新的版本
Environment variables are accessed in C/C++ using the function getenv()
defined in stdlib.h
.使用
stdlib.h
中定义的 function getenv()
在 C/C++ 中访问环境变量。 However, using the envp
parameter of the main function you can use the following example to iterate over environment variables.但是,使用主
envp
的 envp 参数,您可以使用以下示例来迭代环境变量。
#include <stdio.h>
int main(int argc, char *argv[], char *envp[])
{
char **next = envp;
while (*next)
{
printf("%s\n", *next);
next++;
}
return 0;
}
Tested on a Mac在 Mac 上测试
Like grundprinzip said, use getenv(sz) and remember to null-check the return value就像 grundprinzip 所说,使用 getenv(sz)并记住对返回值进行空检查
Alternatively,或者,
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[], char*[] environ) {
int i = 0;
while(environ[i]) {
printf("%s\n", environ[i++]);
}
return 0;
}
Probably the process under debugging is started with可能正在调试的过程是从
execve(binary, NULL, NULL);
and the extern char **environ
gets that 2nd NULL
even though there's an environment available.即使有可用的环境,
extern char **environ
也会得到第二个NULL
。
With a little change, your program works both standalone and under gdb
.稍作改动,您的程序既可以独立运行,也可以在
gdb
下运行。
/* #include <unistd.h> */ /* no more environ */
#include <stdio.h>
/* extern char **environ; */ /* no more environ */
int main(int argc, char *argv[]) {
int i = 0;
char **ptr = argv + argc + 1; /* points to environment, in Un*x */
while(ptr[i]) {
printf("%s\n", ptr[i++]);
}
return 0;
}
Why, and how, that NULL
gets converted to the proper value inside gdb
I have no idea.为什么以及如何将
NULL
转换为gdb
内的正确值,我不知道。
There's nothing wrong with your code.你的代码没有问题。 I tried it on my machine and it printed the environment as expected.
我在我的机器上试了一下,它按预期打印了环境。 You should not need to use getenv().
您不需要使用 getenv()。
Are you running this application from the terminal?您是否从终端运行此应用程序? If not, you should be.
如果不是,你应该是。 Other means of executing an application might be calling your binary without passing it the environment.
执行应用程序的其他方法可能是调用您的二进制文件而不将其传递给环境。
From the terminal what is your output when you run "env"?从终端运行“env”时,您的 output 是什么? It should output the same list as your program.
它应该 output 与您的程序相同的列表。 It does on my machine.
它在我的机器上。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.