为什么我不能在GDB打印出环境变量? [英] Why I can't print out environment variables in gdb?

查看:550
本文介绍了为什么我不能在GDB打印出环境变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 的#include<&unistd.h中GT;
#包括LT&;&stdio.h中GT;焦炭的extern ** ENVIRON;
INT主(INT ARGC,CHAR *的argv []){
  INT I = 0;
  而(ENVIRON [I]){
    的printf(%S \\ n,ENVIRON [我++]);
  }
  返回0;
}

下面是我的OPS:

 (GDB)N
8的printf(%S \\ n,ENVIRON [我++]);
(GDB)p ENVIRON [I]
在地址0x0不能访问内存
(GDB)N
LOGNAME =根
7,而(ENVIRON [I]){

正如你所看到的,的printf 可打印出 ENVIRON [I] ,但 p ENVIRON [I] 给我在地址0x0 ,无法访问的内存为什么?


解决方案

GDB解析错误 ENVIRON 符号。 我不知道为什么,虽然。请参阅下文,为什么。

但你可以测试它。该程序更改为:

 的#include<&unistd.h中GT;
#包括LT&;&stdio.h中GT;焦炭的extern ** ENVIRON;
INT主(INT ARGC,CHAR *的argv []){
  INT I = 0;
  的printf(%P \\ N,&安培; ENVIRON);
  而(ENVIRON [I]){
    的printf(%S \\ n,ENVIRON [我++]);
  }
  返回0;
}

现在,让我们在调试器中运行这个。


(GDB)N
7的printf(%P \\ N,与ENVIRON);
(GDB)N
0x8049760
8时(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字符** ENVIRON

打印这就产生了相同的地址作为该计划认为,0x8049760:


(GDB)P&'ENVIRON @@ GLIBC_2.0
$ 9 =(*)0x8049760
(GDB)P((字符**)ENVIRON @@ GLIBC_2.0')[I]
$ 10 = 0xbffff6adXDG_SESSION_ID = 1

所以,在一个点上的glibc德precated的 ENVIRON 符号,并且加入了新的版本。

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

解决方案

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

这篇关于为什么我不能在GDB打印出环境变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆