i007.cc

i007.cc

优先队列-降维打击

GDB的使用

编译选项

要调试C/C++的程序,在编译时,要把调试信息加到可执行文件中。编译器(cc/gcc/g++)添加-g参数。

比如:g++ -g hello.cpp -o hello

启动gdb

1) gdb -p 进程ID

调试正在运行的程序, 找到进程ID之后, gdb -p过去就可以

2) gdb 二进制文件名

直接用gdb启动程序, 如果程序做过fork之类的, 需要设置gdb参数`set follow-fork-mode child`

3) gdb 二进制文件名 coredump

调试dump文件

常用的调试命令

设置断点:

1) b 文件名:行号

   (gdb) b main.cpp:10

2) b 函数名

```gdb
(gdb) b ProcessMessage
(gdb) b Server::Loop
```

条件断点:

cond(ition) bnum expression

例如想要在a变量等于1的时候, 进入断点10, 那么就是:

   (gdb)cond 10 a == 1

数据断点

watch 变量

例如有一个变量a, 我想知道他在那里被改变了

   (gdb)watch a

也有可能是程序写越界导致了a变量被改变(a的类型为int)

   (gdb)watch *(int*)&a

启用关闭断点

info b可以看到所有的断点信息(状态)

enable 断点编号, 启用断点

disable 断点编号, 关闭断点

delete 断点编号, 删除断点

   (gdb) info b
   (gdb) enable 1
   (gdb) disable 2
   (gdb) delete 3

恢复程序运行和单步调试:

step/s : 单步跟踪,如果有函数调用,会进入该函数

next/n : 单步跟踪,如果有函数调用,不会进入该函数

finish : 运行程序,知道当前函数完成返回

continue/c : 继续运行

run/r : 运行程序

其他常用命令:

p i : 打印变量i的值,p是print命令的缩写

x : 用来查看一段内存的指令, x/nfu, n是个数, f是format, u是单位(b,h,w,g), 具体需要看gdb手册

bt : 查看函数堆栈

f: 切换函数栈, 比如f 1, f 10

frame 栈帧号 : 打印栈帧

list : 显示程序中的代码, 可以通过+-来控制向上翻还是向下翻

quit :退出gdb

设置变量的值

有时候需要在运行的时候修改变量的值, 可以通过set来做

   (gdb) set a = 10
   (gdb) set *(int*)0x8048a51 = 100

coredump等问题的定位及解决

gdb coredump应用程序 coredump文件

通过以下命令调试

info threads 显示所有线程

bt 显示线程堆栈信息

thread thread_num 切换线程

frame num 切换栈

gdb常见问题

1) C++11的auto变量打印

auto变量可能不能正常打印期数据和类型

2) 捕获信号

发送给程序的信号, 可能会被gdb捕获, 而不是被程序处理, 这是正常现象 3) 变量值错误

gdb有时候会打印错误的变量值, 跟log的值不一样, 推荐尽量打log, log里面的值一定是正确的, gdb里面不一定 4) 复杂类型变量

gdb支持pretty printer, 可以让复杂类型看起来更舒服一些

   (gdb) set print pretty on
   (gdb) p *this
   $2 = {
    <gsdk::Singleton<gsdk::message::MainLoop>> = {
        <gsdk::Noncopyable> = {<No data fields>}, 
        members of gsdk::Singleton<gsdk::message::MainLoop>:
        static once_ = {
            _M_once = 2
        }, 
        static ptr_ = 0x612000000ac0
    }, 
    members of gsdk::message::MainLoop: 
    run_ = true, 

gdb可以通过python插件扩展来支持个复杂类型的打印, 例如STL等, Ubuntu等发行版自带了STL的pretty printer.

   (gdb) p this->queue_.queue_ 
   $4 = std::vector of length 0, capacity 1

5)

参考资料

1) GDB User Mannual

发表回复