问题 如何在GDB中调试程序时获取程序的环境


我在linux上用GDB调试程序。我在用 getenv 和 setenv 调用读取和设置环境变量。比如说我打电话 setenv("TZ", "UTC", 1); 为时区设置TZ环境变量。

要检查是否设置了env变量,我正在使用GDB命令 show environment。这将打印所有环境变量及其值。但它没有表现出来 TZ 被设定。

甚至命令 show environment TZ 说 Environment variable "TZ" not defined.

他们是另一种检查调试程序环境的方法吗?

p *(char *) getenv("TZ") 重新建立正确的价值 UTC


10552
2017-10-02 22:58


起源

不应该这样 p (char*)getenv("TZ")? - Jonathan Wakely
好像 environ 一片空白。 environ@@GLIBC_2.0 是指我的情况下真实环境的那个。 stackoverflow.com/questions/6203455/... - punekr12
environ 对我来说很好,但它可能与glibc版本(以及其他)有关。 - rici
@ punekr12:好的,我添加了一种打印整个环境的方法。 HTH。 - rici


答案:


gdb命令 show environment 显示属于的环境 gdb [请参阅注释],而不是正在调试的程序的环境。

调用 getenv 打印正在运行的程序环境似乎是一种非常合理的方法。

注意

Gdb维护一个环境数组,最初从它自己的环境中复制,用于启动每个新的子进程。 show environment 和 set environment 在这个环境上工作,所以 set environment 将改变环境变量 下次 你启动正在调试的程序。程序启动后,加载程序会将环境复制到程序的地址空间中,并进行任何更改 setenv 适用于该数组,而不是由该数组维护的数组 gdb

附录:如何打印调试程序的整个环境

在Linux上,每个进程的环境都可以通过伪文件获得 /proc/PID/environ,哪里 PID 由进程的pid替换。该文件的值是以空字符结尾的字符串列表,因此将其打印出来需要少量工作。

在gdb里面,一旦你开始运行要调试的程序,就可以得到它的pid info proc 然后用它来打印整个环境:

(gdb) info proc
process 6074
...
(gdb) shell xargs -0 printf %s\\n < /proc/6074/environ
XDG_VTNR=7
KDE_MULTIHEAD=false
...

当然,我可以在gdb之外,从不同的终端轻松完成。


7
2017-10-02 23:06



我需要查看程序的所有env变量进行调试,怎么做? - punekr12
@ punekr12:使用全局变量 environ 这是一个 char**;每个元素都指向表单中的字符串 var=value - rici
@ punekr12:但除非你的程序迭代变量 environ,这毫无意义。只是用 getenv 关于你感兴趣的变量。这将与程序看到的完全匹配。 - rici
show environment不是GDB自己的环境,而是它将为它启动的进程提供的环境,请参阅 sourceware.org/gdb/current/onlinedocs/gdb/Environment.html  - 虽然它是作为GDB自己环境的副本开始的,但可以使用它进行修改 set environment 和 unset environment,并且GDB自己的环境没有改变。 - Jonathan Wakely
@JonathanWakely:我不得不从proc fs中获取环境来向自己证明gdb不仅仅在自己的环境中设置变量:)你是对的,它没有。 - rici


您可以使用更改GDB的环境视图 set environment TZ =UTC 但这不会影响正在运行的程序,只会影响下次启动劣质进程时使用的环境。

您可以通过全局变量检查正在运行的劣质流程的当前环境 environ


2
2017-10-02 23:07