C GDB不';t让我读取argv内存段

C GDB不';t让我读取argv内存段,c,memory,segmentation-fault,gdb,argv,C,Memory,Segmentation Fault,Gdb,Argv,我用C编写了一个简单的脚本: #include <stdio.h> void usage(char *program_name) { printf("Usage: %s <message> <# of times to repeat>\n", program_name); exit(1); } int main(int argc, char *argv[]) { int i, count; // if(argc < 3)

我用C编写了一个简单的脚本:

#include <stdio.h>

void usage(char *program_name) {
   printf("Usage: %s <message> <# of times to repeat>\n", program_name);
   exit(1);
}

int main(int argc, char *argv[]) {
   int i, count;

//  if(argc < 3)      // If less than 3 arguments are used,
//    usage(argv[0]); // display usage message and exit.

   count = atoi(argv[2]); // convert the 2nd arg into an integer
   printf("Repeating %d times..\n", count);

   for(i=0; i < count; i++)
      printf("%3d - %s\n", i, argv[1]); // print the 1st arg
}
很明显,它出现了分段错误,因为程序需要三个argv才能工作。我对执行控件的行进行了注释。所以它出错了

(gdb) where
#0  0x00007ffff7a56e56 in ____strtoll_l_internal () from /usr/lib/libc.so.6
#1  0x00007ffff7a53a80 in atoi () from /usr/lib/libc.so.6
#2  0x00005555555546ea in main (argc=2, argv=0x7fffffffe958) at convert2.c:14
(gdb) break main
Breakpoint 1 at 0x5555555546d2: file convert2.c, line 14.
(gdb) run test
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/user/Desktop/booksrc/convert2 test

Breakpoint 1, main (argc=2, argv=0x7fffffffe958) at convert2.c:14
14     count = atoi(argv[2]); // convert the 2nd arg into an integer
(gdb) cont
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a56e56 in ____strtoll_l_internal () from /usr/lib/libc.so.6
(gdb) x/3xw 0x7fffffffe958 // this is memory of the "argv" some line before
0x7fffffffe958: 0xffffebfe  0x00007fff  0xffffec22
(gdb) x/s 0xffffebfe
0xffffebfe: <error: Cannot access memory at address 0xffffebfe>
(gdb) x/s 0x00007fff
0x7fff: <error: Cannot access memory at address 0x7fff>
(gdb) x/s 0xffffec22
0xffffec22: <error: Cannot access memory at address 0xffffec22>
(gdb)其中
#来自/usr/lib/libc.so.6的0 0x00007FF7A56E56 in uuuuuuuuuuuuuuuuuuuuu strtoll_ul_uinternal()
#来自/usr/lib/libc.so.6的atoi()中的1 0x00007FF7A53A80
#convert2.c:14处的2个0x000055546EA主(argc=2,argv=0x7fffffffe958)
(gdb)主断路器
断点1位于0x5546D2:文件convert2.c,第14行。
(gdb)运行测试
正在调试的程序已启动。
从头开始?(y或n)y
启动程序:/home/user/Desktop/booksrc/convert2测试
convert2.c处的主断点1(argc=2,argv=0x7fffffe958):14
14计数=atoi(argv[2]);//将第二个参数转换为整数
(gdb)续
持续的。
程序接收信号SIGSEGV,分段故障。
0x00007FF7A56E56位于/usr/lib/libc.so.6中的
(gdb)x/3xw 0x7fffffffe958//这是前面某行“argv”的内存
0x7FFFFFE958:0xFFFFBFE 0x00007fff 0xFFFFC22
(gdb)x/s 0xFFFFBFE
0xFFFFBFE:
(gdb)x/s 0x00007fff
0x7fff:
(gdb)x/s 0xFFFFC22
0xFFFFC22:

理论上,对于“x/s”,我应该在第一个地址中看到命令行,在第二个地址中看到“test”,在第三个地址中看到null。但什么都没有。如果我将该地址复制粘贴到ascii到字符串转换器,它会毫无意义地提供数据。我做错了什么?

您的平台使用64位指针,请尝试:

(gdb) x/3xg 0x7fffffffe958
要在
argv
数组中显示64位指针,请执行以下操作:

(gdb) x/s 0x00007fffffffebfe
或者只是:

(gdb) p argv[0]

首先,始终检查命令行是否正确

从代码中取消对检查的注释

然后在
gdb
中设置参数(在运行之前)


它起作用了!!谢谢但是为什么0x00007fff给我null,而它应该是第三个argv(0xFFFFC22,即“test”),并且应该是第二个地址(即null)我不必考虑地址的顺序与AGV的位置有关?@ ALXEJ:0x000,7FFF不是一个有效的地址-它是地址的最重要的一半。为了获得第二个字符串在<代码> ARGV 数组中,你需要完整的地址:0x7FFFFFFEF22。或者只是让你的生活变得简单,并且做<代码> P AGV(1)。。另外,将此内存地址复制到十六进制到文本站点并将其转换是错误的吗?@AllExJ:这些十六进制值是内存地址。它们表示字符串的位置,而不是字符串本身。您需要检查(x)该位置的内存,并将其解释为字符串如上图所示,显示字符串。因此,否:将地址转换为文本不会给出字符串。@AllExJ:要使
argv
符号可用,请在到达设置的断点后执行一次步骤(您在
main
符号上设置断点,而不是在
main
函数的开始处设置断点)。你确定你已经设置了命令行参数吗?总是检查。我怎么做?我对Cby在你的代码中取消对检查的注释是新手。你对它进行了注释,可能是因为它不允许你继续。你需要设置命令行选项,并且thr
argc
必须是
3
nono我对它进行了注释,只是为了用g进行检查db,只是为了练习。我是故意这么做的。为什么?在我的回答中设置gdb中的参数。如果您必须对其进行注释,您的gdb调试是错误的,因为您没有设置命令行参数
(gdb) p argv[0]
(gdb) set args "hello world" 12