简体   繁体   English

使用gdb访问命令行参数

[英]accessing command-line arguments with gdb

I am on linux using gdb version 6.8-debian. 我在linux上使用gdb版本6.8-debian。 I have been curious about how the main function in a c-program gets executed and playing around and looking in different places, I learned that the function __libc_start_main is responsiple for this. 我一直很好奇c程序中的主要功能是如何被执行和在不同的地方玩耍,我了解到函数__libc_start_main对此负责。 The arguments to __libc_start_main are, among others: The address of main (like we know from c, the path is always given as argv[0]), next argc which should reside in the register ESI, and next address of argv which should be in ECX. __libc_start_main的参数包括:main的地址(就像我们从c中知道的那样,路径总是以argv [0]给出),next argc应该驻留在寄存器ESI中,而argv的下一个地址应该是在ECX。

To play around I made the following simple program, cmdargs.c, which simply outputs the first command-line argument given at start: 为了解决这个问题,我制作了以下简单程序cmdargs.c,它只是输出start时给出的第一个命令行参数:

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
    printf("%s: %s\n", "argv[1]", *++argv);
    return EXIT_SUCCESS;
}

Now I start to debug cmdargs and set a breakpoint on main and __libc_start_main (info from starting gdb removed): 现在我开始调试cmdargs并在main和__libc_start_main上设置断点(从启动gdb删除的信息):

gdb cmdargs gdb cmdargs

(gdb) b main
Breakpoint 1 at 0x80483d2
(gdb) b __libc_start_main
Breakpoint 2 at 0xb7f3f5a8
(gdb) r qwerty

Here i hit the Breakpoint 2 in __libc_start_main and can view argc and argv[0] with 在这里我点击了__libc_start_main中的断点2,可以查看argc和argv [0]

(gdb) p $esi

and

(gdb) x/s *($ecx)

This works as expected, but how do I access the first non-implicit commandline-argument "qwerty" ? 这按预期工作,但如何访问第一个非隐式命令行参数“qwerty”? I have tried continuing to the breakpoint at main and stepping in, but argc and argv are not recognised (Why?). 我已经尝试继续在main处断点并踩到,但argc和argv无法识别(为什么?)。 Can someone tell me whats going on ? 谁能告诉我发生了什么事?

Breakpoint 1, 0x080483d2 in main ()
(gdb) stepi
0x080483d5 in main () 
(gdb) p argc
No symbol "argc" in current context.
(gdb) p argv
No symbol "argv" in current context.
(gdb) 

Yep, your problem is the lack of symbols, not included at compilation time. 是的,你的问题是缺少符号,不包括在编译时。

To compile with debugging information: 要使用调试信息进行编译:

$ gcc -g3 cmdargs.c -o cmdargs

Then: 然后:

$ gdb ./cmdargs
...
Reading symbols from ./cmdargs...done.
(gdb) b main
Breakpoint 1 at 0x400545: file cmdargs.c, line 6.
(gdb) r
Starting program: cmdargs 

Breakpoint 1, main (argc=1, argv=0x7fffffffdc28) at cmdargs.c:6
6       printf("%s: %s\n", "argv[1]", *++argv);
(gdb) p argc
$1 = 1
(gdb) p argv
$2 = (char **) 0x7fffffffdc28
(gdb) p *argv
$3 = 0x7fffffffe00c "/home/jcgonzalez/cmdargs"

See, now you get access to the symbols (they are recognized), as well as to the line numbers. 看,现在您可以访问符号(它们被识别)以及行号。 As shown by Let_Me_Be , you can access single array elements with array[n] notation, but you can also show all the command line arguments at once (including the [0]-ed one) with the *array@times notation. Let_Me_Be所示,您可以使用array [n]表示法访问单个数组元素,但您也可以使用* array @ times表示法一次显示所有命令行参数(包括[0] -ed)。 Note that the first argument in the following example is a quoted string: 请注意,以下示例中的第一个参数是带引号的字符串:

(gdb) set args "this is an argument" these are four more 
(gdb) r
Starting program: cmdargs "this is an argument" these are four more

Breakpoint 1, main (argc=6, argv=0x7fffffffdbd8) at cmdargs.c:6
6       printf("%s: %s\n", "argv[1]", *++argv);
(gdb) p argc
$4 = 6
(gdb) p *argv@argc                                    
$5 = {0x7fffffffdfe6 "/home/jcgonzalez/cmdargs", 0x7fffffffdfff "this is an argument", 0x7fffffffe012 "these", 0x7fffffffe017 "are", 0x7fffffffe01b "four", 
  0x7fffffffe020 "more"}
(gdb) p argv[1]
$6 = 0x7fffffffdfff "this is an argument"
(gdb) p argv[2]
$7 = 0x7fffffffe012 "these"

The output looks as if you don't have enough debuging information. 输出看起来好像没有足够的debuging信息。 GDB shouldn't print only addresses but line numbers as well. GDB不应该只打印地址而是打印行号。

(gdb) b main
Breakpoint 1 at 0x400543: file test.c, line 3.
(gdb) r test1 test2
Starting program: /home/simon/a.out test1 test2

Breakpoint 1, main (argc=3, argv=0x7fffffffdca8) at test.c:3
3               puts("blabla");
(gdb) print argc
$1 = 3
(gdb) print argv
$2 = (char **) 0x7fffffffdca8
(gdb) print argv[0]
$3 = 0x7fffffffe120 "/home/simon/a.out"
(gdb) print argv[1]
$4 = 0x7fffffffe132 "test1"
(gdb) print argv[2]
$5 = 0x7fffffffe138 "test2"
(gdb)

你应该将-g选项添加到gcc,这告诉它也要构建调试信息..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM