调试利器GDB-下

Posted dengqiangjiayou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了调试利器GDB-下相关的知识,希望对你有一定的参考价值。

调试利器GDB-下

  • 函数调用栈的查看(backtrace和frame)(在你阅读开源代码的时候或许这很有帮助)

    • backtrace
      • 查看函数调用的顺序(函数)
    • frame N
      • 切换到栈编号为N的上下文中
    • info frame
      • 查看当前函数调用的栈帧的信息
  • 调试小技巧
    | 操作 | 命令 |
    | -------------- |
    | 断点处自动打印 | display /f expression |
    | | undisplay |
    | 查看程序中的符号 | whatis |
    | | ptype |
    | GDB中的代码查看 | list |
    | | set listsize N |
    | GDB中的shell操作 | shell |

调试程序:

topeet@ubuntu:~/Desktop/Code$ ls
func.c  test.c  test.c~  test.out
topeet@ubuntu:~/Desktop/Code$ gcc -g test.c -o test.out 
topeet@ubuntu:~/Desktop/Code$ gdb test.out 
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/topeet/Desktop/Code/test.out...done.
(gdb) shell cat test.c
#include <stdio.h>

int g_var = 1;

struct ST
{
    int i;
    int j;
};

int func()
{
    struct ST st[5] = {0};
    int i = 0;
    
    for(i=0; i<5; i++)
    {
        st[i].i = i;
        st[i].j = i * i;
    }
    
    for(i=0; i<5; i++)
    {
        printf("st[%d].i = %d\\n", i, st[i].i);
        printf("st[%d].j = %d\\n", i, st[i].j);
    }
}

int main()
{
    static c_var = 2;
	
    func();
	
    return 0;
}
(gdb) file test.out //载入可执行文件,当然也可以在gdb里面编译 shell gcc -g test.c -o test.out
Load new symbol table from "/home/topeet/Desktop/Code/test.out"? (y or n) y
Reading symbols from /home/topeet/Desktop/Code/test.out...done.
(gdb) break test.c:18
Breakpoint 1 at 0x400554: file test.c, line 18.
(gdb) list test.c:18
13	    struct ST st[5] = {0};
14	    int i = 0;
15	    
16	    for(i=0; i<5; i++)
17	    {
18	        st[i].i = i;
19	        st[i].j = i * i;
20	    }
21	    
22	    for(i=0; i<5; i++)
(gdb) set linesize 20
No symbol "linesize" in current context.
(gdb) list test.c:18
13	    struct ST st[5] = {0};
14	    int i = 0;
15	    
16	    for(i=0; i<5; i++)
17	    {
18	        st[i].i = i;
19	        st[i].j = i * i;
20	    }
21	    
22	    for(i=0; i<5; i++)
(gdb) set lintsize 20
No symbol "lintsize" in current context.
(gdb) set listsize 20
(gdb) show listsize 
Number of source lines gdb will list by default is 20.
(gdb) list test.c:18
8	    int j;
9	};
10	
11	int func()
12	{
13	    struct ST st[5] = {0};
14	    int i = 0;
15	    
16	    for(i=0; i<5; i++)
17	    {
18	        st[i].i = i;
19	        st[i].j = i * i;
20	    }
21	    
22	    for(i=0; i<5; i++)
23	    {
24	        printf("st[%d].i = %d\\n", i, st[i].i);
25	        printf("st[%d].j = %d\\n", i, st[i].j);
26	    }
27	}
(gdb) continue 
The program is not being run.
(gdb) start
Temporary breakpoint 2 at 0x4005d6: file test.c, line 33.
Starting program: /home/topeet/Desktop/Code/test.out 

Temporary breakpoint 2, main () at test.c:33
33	    func();
(gdb) continue 
Continuing.

Breakpoint 1, func () at test.c:18
18	        st[i].i = i;
(gdb) display /d i
1: /d i = 0
(gdb) display /d i*i
2: /d i*i = 0
(gdb) display /a &a
No symbol "a" in current context.
(gdb) display /a &i
3: /a &i = 0x7fffffffe1ac
(gdb) continue 
Continuing.

Breakpoint 1, func () at test.c:18
18	        st[i].i = i;
3: /a &i = 0x7fffffffe1ac
2: /d i*i = 1
1: /d i = 1

Breakpoint 1, func () at test.c:18
18	        st[i].i = i;
3: /a &i = 0x7fffffffe1ac
2: /d i*i = 4
1: /d i = 2
(gdb) continue 
Continuing.

Breakpoint 1, func () at test.c:18
18	        st[i].i = i;
3: /a &i = 0x7fffffffe1ac
2: /d i*i = 9
1: /d i = 3
(gdb) continue 
Continuing.

Breakpoint 1, func () at test.c:18
18	        st[i].i = i;
3: /a &i = 0x7fffffffe1ac
2: /d i*i = 16
1: /d i = 4
(gdb) continue 
Continuing.
st[0].i = 0
st[0].j = 0
st[1].i = 1
st[1].j = 1
st[2].i = 2
st[2].j = 4
st[3].i = 3
st[3].j = 9
st[4].i = 4
st[4].j = 16
[Inferior 1 (process 10073) exited normally]
(gdb) whatis g_var //查看变量类型
type = int
(gdb) ptype g_
No symbol "g_" in current context.
(gdb) ptype g_var
type = int
(gdb) whatis ST
No symbol "ST" in current context.
(gdb) whatis struct ST //注意whatis和ptype的区别
type = struct ST
(gdb) ptype struct ST
type = struct ST {
    int i;
    int j;
}
(gdb) info variables //查看这个文件里面定义了哪些变量
All defined variables:

File test.c:
int g_var;

Non-debugging symbols:
0x00000000004006b8  _IO_stdin_used
0x00000000004007f8  __FRAME_END__
0x0000000000600e24  __init_array_end
0x0000000000600e24  __init_array_start
0x0000000000600e28  __CTOR_LIST__
0x0000000000600e30  __CTOR_END__
0x0000000000600e38  __DTOR_LIST__
0x0000000000600e40  __DTOR_END__
0x0000000000600e48  __JCR_END__
0x0000000000600e48  __JCR_LIST__
0x0000000000600e50  _DYNAMIC
0x0000000000600fe8  _GLOBAL_OFFSET_TABLE_
0x0000000000601018  __data_start
0x0000000000601018  data_start
0x0000000000601020  __dso_handle
0x000000000060102c  c_var.2067
---Type <return> to continue, or q <return> to quit---quit
Quit
(gdb) info functions //查看这个文件里定义了什么函数
All defined functions:

File test.c:
int func();
int main();

Non-debugging symbols:
0x00000000004003e0  _init
0x0000000000400420  printf
0x0000000000400420  printf@plt
0x0000000000400430  __libc_start_main
0x0000000000400430  __libc_start_main@plt
0x0000000000400440  __gmon_start__
0x0000000000400440  __gmon_start__@plt
0x0000000000400450  _start
0x0000000000400480  __do_global_dtors_aux
0x00000000004004f0  frame_dummy
0x00000000004005f0  __libc_csu_init
0x0000000000400660  __libc_csu_fini
0x0000000000400670  __do_global_ctors_aux
0x00000000004006a8  _fini
0x00007ffff7ddaaa0  __libc_memalign
---Type <return> to continue, or q <return> to quit---quit
Quit
(gdb) 

总结:

  • GDB支持数据断点设置(一种类型的硬件断点)
  • watch用于监视变量是否被改变,x用于查看内存中的数据(当然需要配合相应的参数)
  • GDB支持函数调用栈的查看(backtrace、info frames)
  • GDB支持运行时对程序中的符号进行查看(whatis、ptype)

小问题:GDB中肯定可以跟踪一个函数,可以看哪些函数调用了这个函数,可以帮助串起整个程序,但还有待挖掘

以上是关于调试利器GDB-下的主要内容,如果未能解决你的问题,请参考以下文章

调试利器GDB(下)

调试利器GDB(上)

调试利器GDB-上

调试利器GDB-上

调试利器GDB-中

调试利器GDB-中