初窥gdb - 02

来源:互联网 发布:七天网络查分登录注册 编辑:程序博客网 时间:2024/04/29 22:38

回顾上一期:《初窥gdb - 01》点击打开链接

上一期我们学习了设置断点和观察点的基本用法,这次让我们更熟悉他们。


关键命令:1. b    2. watch

新命令: 1. start 

                 2. print 

                 3. c / continue

熟悉gdb断点、观察点设置


首先我们理清上一期的一个问题,就是在程序未运行之前,为何无法设置针对变量的观察点。

还记得上一期我们怎么设置断点的吗?我们设置在main函数入口处,也就是 $ b main 命令。接下来,程序运行,我们才可以设置观察点array[0]~array[2] 。回想一下,变量具有作用域,只有在进入变量的作用域时,变量才可以使用。如果在main函数中调用一个fun函数,fun函数体中有其局部整形变量 int  S,我们只有调试在进入fun函数体中,才可以设置变量 S 的观察点。同样的,我们只有在进入main函数中,我们才可以设置array数组的观察点。废话较多,我们用实例来说明:


源文件:main.cpp

#include<iostream>int sum(int a, int b, int c);int main(){        int array[3];    for(int i;i<3;i++)       {         array[i]=i;          //数组赋值        }               int s=sum(array[0],array[1],array[2]);        return 0;}int sum(int a, int b, int c){ int t=a+b+c; return t;}
编译程序:

$ g++ -g main.cpp -o program

启动gdb:

$ gdb program

我们运行程序(run)之前,总要在main函数入口设置断点,这里我们引入一个简化的命令:start,它的原理是在main函数入口设置一个临时断点,然后运行程序。这样我们不需要每次都为main函数设置断点。

(gdb) start

Temporary breakpoint 1 at 0x40072e: file main.cpp, line 7.
Starting program: /home/kevin/workstation/test/gdb/program
                                                                                     
Temporary breakpoint 1, main () at main.cpp:7
7    {                                                                            


(gdb) watch array[2]

Hardware watchpoint 2: array[2]

(gdb) watch t

No symbol "t" in current context.

(gdb) c 新命令:continue

Continuing.

                     
Hardware watchpoint 2: array[2]

Old value = 4195888
New value = 2
main () at main.cpp:9
9        for(int i;i<3;i++)
 

(gdb) n

14        int s=sum(array[0],array[1],array[2]);

这里我们用step命令进入sum函数体,如果继续用n(next)命令直接跳到下一条语句而不进入sum函数体内。

(gdb) step

sum (a=0, b=1, c=2) at main.cpp:21

21     int t=a+b+c;

(gdb) watch t

Hardware watchpoint 3: t

(gdb) n


Hardware watchpoint 3: t

Old value = 0
New value = 3
sum (a=0, b=1, c=2) at main.cpp:22
22     return t;

(gdb) n

23    }

(gdb) n


Watchpoint 3 deleted because the program has left the block in
which its expression is valid.
0x0000000000400767 in main () at main.cpp:14

14        int s=sum(array[0],array[1],array[2]);

这里我们引入一个观察变量更方便的命令:print

(gdb) print array[0]

$1 = 0

(gdb) print array[1]

$2 = 1

(gdb) print array[2]

$3 = 2

(gdb) print t

No symbol "t" in current context.

 以上的例子告诉我们何时可以访问变量,接下来我们来熟悉一下如何对成员函数设置断点,以及访问成员变量。


main.cpp

#include"sum.h"int sum(int a, int b, int c);int main(){        int array[3];    for(int i;i<3;i++)       {         array[i]=i;          //数组赋值        }      Sum S;         int s2=S.sum(array[0],array[1]);    int s3=S.sum(array[0],array[1],array[2]);        return 0;}

sum.h

#include"sum.h"int Sum::sum(int a, int b){return a+b;}int Sum::sum(int a, int b, int c){return a+b+c;}

sum.cpp

class Sum {  public:    Sum(){test=12345;};    ~Sum(){};   int sum(int a, int b);   int sum(int a, int b, int c);  private:   int test;};

$ g++ -g main.cpp sum.cpp -o program

$ gdb program

(gdb) b Sum::sum       (成员函数依然需要域名解析

Breakpoint 1 at 0x40095e: Sum::sum. (2 locations)

(gdb) start

Temporary breakpoint 2 at 0x40082f: file main.cpp, line 7.

Starting program: /home/kevin/workstation/test/gdb/overload_function/program
Temporary breakpoint 2, main () at main.cpp:

7    {   

留意这里访问成员变量和对成员函数设断点不同,需要对象实例化

(gdb) watch Sum::test   (无法访问

Cannot reference non-static field "test"

(gdb) watch S.test          

Hardware watchpoint 3: S.test

(gdb) c

Continuing.

Hardware watchpoint 3: S.test

Old value = 2
New value = 12345
0x0000000000400940 in Sum::Sum (this=0x7fffffffde20) at sum.h:4
4        Sum(){test=12345;};


注意之前对成员函数sum设了一次断点,对这里所有重载函数都起效!

(gdb) c

Continuing.

Breakpoint 1, Sum::sum (this=0x7fffffffde20, a=0, b=1) at sum.cpp:5

5    {return a+b;}

(gdb) c

Continuing.

Breakpoint 1, Sum::sum (this=0x7fffffffde20, a=0, b=1, c=2) at sum.cpp:7

7    {return a+b+c;}

(gdb) c

Continuing.



0 0
原创粉丝点击