c - 为什么我不能在 gdb 中打印出环境变量?

标签 c linux gdb environment-variables

#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/

相关文章:

来自 main 的 C 函数没有插入 arm 中的堆栈

java - 无法使用 Socket 连接将数据发送到 c 服务器

linux - 在 Red Hat 64 位上安装 xampp

debugging - 如何在附加 gdb 的情况下运行 R 脚本?

c - 基本C,输出不正确

C 定义和 char 指针声明之间的错误

Linux 控制台应用程序开发

linux - 在 Hyperledger Fabric 中是否可以在 2 台不同的机器上连接 2 个组织

c - 缓冲区溢出出现在预期之前

python - Python 程序运行时获取全局变量