MDGSF Software Engineer

[GDB] gdb基础

2016-07-08
GDB

apt-get source coreutils

获取常用工具的源码,例如 ls 。等学会了用gdb就可以调试常用工具的源码了。

一个调试实例

写个简单的程序用来调试。

//main.c
#include <stdio.h>

int func(int n)
{
    int sum = 0;
    for (int i = 0; i < n; i++)
    {
        sum += i;
    }
    return sum;
}

int main()
{
    int iResult = 0;
    for (int i = 0; i <= 100; i++)
    {
        iResult += i;
    }
    printf("result[1-100] = %d\n", iResult);
    printf("result[1-250] = %d\n", func(250));
    return 0;
}

编译命令

g++ -g main.c -o test

要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。要加上 -g 的選項. (可以用-g, -g2, -g3具體請看 man gcc)通常如果程式不會很大,在 compile 的時候我都是用 -g3 的,因為如果你用到了 inline 的 function, 用 -g 去 compile 就無法去 debug inline function了.這時候就用到 -g2, -g3了,g後面的數字越大,也就是說 可以 debug 的級別越高.最高級別就是 -g3.

root@mdgsf-VirtualBox:# gdb test    <-------------------------开始调试
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 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 "i686-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...done.
(gdb) l         <--------------------- l命令相当于list,列出原码,不知道为什么不是从第一行开始。
6       for (int i = 0; i < n; i++)
7       {
8           sum += i;
9       }
10      return sum;
11  }
12
13  int main()
14  {
15      int iResult = 0;
(gdb) list       <--------------------- list,列出原码。
16      for (int i = 0; i <= 100; i++)
17      {
18          iResult += i;
19      }
20      printf("result[1-100] = %d\n", iResult);
21      printf("result[1-250] = %d\n", func(250));
22      return 0;
23  }
(gdb) list       <--------------------- list,列出原码。
Line number 24 out of range; main.c has 23 lines.
(gdb) l 0        <--------------------- 用list命令从第一行开始列出代码。
1   #include <stdio.h>
2
3   int func(int n)
4   {
5       int sum = 0;
6       for (int i = 0; i < n; i++)
7       {
8           sum += i;
9       }
10      return sum;
(gdb)       <--------------------- 直接回车,重复执行上一个命令。
11  }
12
13  int main()
14  {
15      int iResult = 0;
16      for (int i = 0; i <= 100; i++)
17      {
18          iResult += i;
19      }
20      printf("result[1-100] = %d\n", iResult);
(gdb) break 15       <--------------------- 在程序的第15行设置断点
Breakpoint 1 at 0x8048453: file main.c, line 15.
(gdb) break func     <--------------------- 在程序的func()函数入口设置断点
Breakpoint 2 at 0x8048423: file main.c, line 5.
(gdb) info break     <--------------------- 查看断点的信息
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08048453 in main() at main.c:15
2       breakpoint     keep y   0x08048423 in func(int) at main.c:5
(gdb) r              <--------------------- r (run) 运行程序
Starting program: /root/gdb/test

Breakpoint 1, main () at main.c:15
15      int iResult = 0;
(gdb) n              <--------------------- 单条语句执行,next命令简写。
16      for (int i = 0; i <= 100; i++)
(gdb) n              <--------------------- 单条语句执行,next命令简写。
18          iResult += i;
(gdb) c              <--------------------- c (continue) 继续运行程序。
Continuing.
result[1-100] = 5050        <----------程序输出。

Breakpoint 2, func (n=250) at main.c:5
5       int sum = 0;
(gdb) info break     <--------------------- 查看断点的信息
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08048453 in main() at main.c:15
    breakpoint already hit 1 time
2       breakpoint     keep y   0x08048423 in func(int) at main.c:5
    breakpoint already hit 1 time
(gdb) n
6       for (int i = 0; i < n; i++)
(gdb) n
8           sum += i;
(gdb) p i       <--------------------- 打印变量i的值,print命令简写。
$1 = 1
(gdb) p sum     <--------------------- 打印变量sum的值,print命令简写。
$2 = 0
(gdb) p i
$3 = 1
(gdb) n
6       for (int i = 0; i < n; i++)
(gdb) n
8           sum += i;
(gdb) n
6       for (int i = 0; i < n; i++)
(gdb) p i
$4 = 2
(gdb) p sum
$5 = 3
(gdb) bt        <--------------------- 查看函数堆栈。
#0  func (n=250) at main.c:6
#1  0x08048499 in main () at main.c:21
(gdb) finish    <--------------------- 退出函数。
Run till exit from #0  func (n=250) at main.c:6
0x08048499 in main () at main.c:21
21      printf("result[1-250] = %d\n", func(250));
Value returned is $6 = 31125
(gdb) c        <--------------------- 继续运行。
Continuing.
result[1-250] = 31125    <----------程序输出。
[Inferior 1 (process 10367) exited normally]  <--------程序退出,调试结束。
(gdb) q       <--------------------- 退出gdb

常用命令简写:

list  --> l     列出源代码
run   --> r     运行程序
next  --> n
continue  --> c
print --> p
backtrace --> bt
(gdb) help
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.

gdb的命令很多,gdb把之分成许多个种类。help命令只是例出gdb的命令种类,如果要看种类中的命令,可以使用help 命令,如:help breakpoints,查看设置断点的所有命令。也可以直接help 来查看命令的帮助。

(gdb) help list    <-----------------------用 help 命令查看具体用法
List specified function or line.
With no argument, lists ten more lines after or around previous listing.
"list -" lists the ten lines before a previous ten-line listing.
One argument specifies a line, and ten lines are listed around that line.
Two arguments with comma between specify starting and ending lines to list.
Lines can be specified in these ways:
  LINENUM, to list around that line in current file,
  FILE:LINENUM, to list around that line in that file,
  FUNCTION, to list around beginning of that function,
  FILE:FUNCTION, to distinguish among like-named static functions.
  *ADDRESS, to list around the line containing that address.
With two args if one is empty it stands for ten lines away from the other arg.
(gdb) help break
Set breakpoint at specified line or function.
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]
PROBE_MODIFIER shall be present if the command is to be placed in a
probe point.  Accepted values are `-probe' (for a generic, automatically
guessed probe type) or `-probe-stap' (for a SystemTap probe).
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of the selected
stack frame.  This is useful for breaking on return to a stack frame.

THREADNUM is the number from "info threads".
CONDITION is a boolean expression.

Multiple breakpoints at one place are permitted, and useful if their
conditions are different.

Do "help breakpoints" for info on other commands dealing with breakpoints.
(gdb) help run
Start debugged program.  You may specify arguments to give it.
Args may include "*", or "[...]"; they are expanded using "sh".
Input and output redirection with ">", "<", or ">>" are also allowed.

With no arguments, uses arguments last specified (with "run" or "set args").
To cancel previous arguments and run with no arguments,
use "set args" without arguments.
(gdb) help next
Step program, proceeding through subroutine calls.
Usage: next [N]
Unlike "step", if the current source line calls a subroutine,
this command does not enter the subroutine, but instead steps over
the call, in effect treating it as a single source line.
(gdb) help continue
Continue program being debugged, after signal or breakpoint.
Usage: continue [N]
If proceeding from breakpoint, a number N may be used as an argument,
which means to set the ignore count of that breakpoint to N - 1 (so that
the breakpoint won't break until the Nth time it is reached).

If non-stop mode is enabled, continue only the current thread,
otherwise all the threads in the program are continued.  To
continue all stopped threads in non-stop mode, use the -a option.
Specifying -a and an ignore count simultaneously is an error.
(gdb) help print
Print value of expression EXP.
Variables accessible are those of the lexical environment of the selected
stack frame, plus all those whose scope is global or an entire file.

$NUM gets previous value number NUM.  $ and $$ are the last two values.
$$NUM refers to NUM'th value back from the last one.
Names starting with $ refer to registers (with the values they would have
if the program were to return to the stack frame now selected, restoring
all registers saved by frames farther in) or else to debugger
"convenience" variables (any such name not a known register).
Use assignment expressions to give values to convenience variables.

{TYPE}ADREXP refers to a datum of data type TYPE, located at address ADREXP.
@ is a binary operator for treating consecutive data objects
anywhere in memory as an array.  FOO@NUM gives an array whose first
element is FOO, whose second element is stored in the space following
where FOO is stored, etc.  FOO must be an expression whose value
resides in memory.

EXP may be preceded with /FMT, where FMT is a format letter
but no count or size letter (see "x" command).
(gdb) help bt
Print backtrace of all stack frames, or innermost COUNT frames.
With a negative argument, print outermost -COUNT frames.
Use of the 'full' qualifier also prints the values of the local variables.
Use of the 'no-filters' qualifier prohibits frame filters from executing
on this backtrace.

http://blog.csdn.net/haoel/article/details/2879

http://blog.csdn.net/haoel/article/details/2880


weixingongzhonghao

上一篇 [C/C++] glog使用

Comments

Content