gdb

gcc -o app test.c -ggdb3 (可以最大限度的包含调试信息)
gdb ./app 
gdb 运行时设置命令行参数:(gdb)    run  命令行参数   或者  (gdb)  set args 命令行参数
打印变量的值:    p 变量  
p/t a 二进制形式打印变量a的值
p/t &a 以二进制形式打印变量a的地址
p/x a 以16进制打印变量a的值
p/x &a 以16进制打印变量a 的地址
断点设置:
  b    行号 或者b    文件名:行号  或者 b function_name 以函数名设置断点
  info breakpoints     查看断点信息
删除断点
clear 删除这行的断点 或者 clear 函数名 : 删除该函数的断点
delete b_id1 b_id2 ... : 删除指定编号的断点

finish 退出函数//finish:运行到当前函数结尾
until num 执行到某一行停下
until: 跑完一个循环,到循环外的下一行

start开始运行程序, 停在main函数入口处, 然后可next或step单步执行
reverse-next 逆向调试(不支持多线程)

gdb    或者    gdb -p pid 调试正在运行的进程
attch  pid(运行中程序的pid)
bt(在gdb调试程序的时候,用bt命令查看栈信息)
gdb中c为continuing
frame n   n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层  ,最顶层的栈就是当前栈


info source 查看当期啊代码对应文件

info threads 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 前面有*的是当前调试的线程。
thread ID 切换当前调试的线程为指定ID的线程。
break thread_test.c:123 thread all 在所有线程中相应的行上设置断点

条件断点:break  [where] if [condition]。要监视某个变量, 每经过那个断点时GDB会帮你检查一下条件是否满足。
thread apply ID1 ID2 command 让一个或者多个线程执行GDB命令command。 
thread apply all command 让所有被调试线程执行GDB命令command。

info symbol 0x807a505 : 查看当前内存地址0x807a505所指向的函数符号,此命令对查看 回调函数指针所指向的具体函数名 非常方便。

info f 更相信的显示当前栈信息

info line 行号, 函数名, 文件:行号, 文件:函数名, 查看相应函数或者行号源码在内存中地址
info line *0x807a505, 获取内存地址处源码, 16进制地址前必选加0x, 否则会当成十进制处理

list *0x807a505  查看0x807a505附近代码10行
list 38 查看38行代码周围的十行, 即33-42
list - 查看上一个命令查看的前十行及23-32
list main 查看main函数周围10行
list main.c:33      list main.c: main


调试的跳步解决:

是qt或者gdb调试的时候发现代码的执行总是跳来跳去的,这是因为编译的时候加入了优化选项。修改configure,把里面的所有 O2 都去掉,再编译、调试,既可解决此问题或者 gcc 输出改为-O


gdb 查看结构体
set  print  pretty on       //设定美化显示过程
ptype p_type  或者pt p_type打印结构体的定义 //whatis 也可打印变量类型
p  *p_type 打印结构体中变量值, p  p_type->a   查看结构体中成员值
whatis p_type  打印p_type类型

如用p ((struct NewStruct *)tmp_p)->a 出现
no struct type named NewStruct
需在编译时加     -fno-eliminate-unused-debug-types      选项  


gdb 调试问号
问题:关于gdb调试core文件总是一堆问号的问题
ulimit -a
查看是否打开core文件生成
vim /etc/profile    加入ulimit -c unlimited   保存    source /etc/profile     或者.  /etc/profile
问题描述:已经在编译选项中加入了-g,但是查看core文件时,还是一堆问号,使用的命令为:gdb -c core
解决方案:由于gdb -c core这样的使用在有些系统下支持不是很好,所以推荐用如下两种方法:

1)gdb app
(gdb) core-file core

2)gdb -c core app

3) gdb ./exe app

而其中第二种方法在某些系统上也是不好用的,所以就用第一种即可。

gdb 调式动态库:
需在动态库编译的时候加上-g 选项, 同时主程序也在编译时加-g选项, gdb进入时先在mian函数处打断点, 再在动态库函数处打断点
用s命令便可调试进动态连接库内部, 若看见的是调用的什么库, 可list *地址查看文件函数


反汇编源程序:

当然反汇编程序可以直接通过这种方式(gcc -S -o 1.s bit.c)生成

也可以在gdb 中 disas 函数名, 反汇编打印该函数


gdb 调试c++程序的时候,对文件打断点, 可通过list 类名:函数名的,选择相应的行号打断点 

print str 

字符串打印不全   ===> set print element 0

non-stop模式
set target-async 1
set pagination off
set non-stop on
gdb启动了不停模式,其实就是说,除了断点有关的线程会被停下来,其他线程会执行执行


线程中再 pthread_create 子线程 debug 
pthread_create(&ds_tid, NULL, ds_invoke, data) 
在执行到pthread_create 之前  break search.cpp:251,
然后continue, 直接单步调试可能不能立即进入线程处理函数, 因为pthread_create 调用不代表线程立即执行
thread 显示当前执行的线程

当执行到新线程的处理函数时
[Switching to Thread 0x617d3940 (LWP 26025)]
Breakpoint 2, ly::asp::ds_invoke (params=0x0) at src/search.cpp:251 
251     void* ds_invoke(void* params) {

info threads, 查看哪一个线程ID的 LWP 为26025 然后切换过去, 这个线程执行完再切换回来



breaksearch.cpp:251 thread 3  仅对线程编号为3的加断点

set scheduler-locking off|on|step

估计是实际使用过多线程调试的人都可以发现,在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。

off不锁定任何线程,也就是所有线程都执行,这是默认值。

on只有当前被调试程序会执行。

step在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

需要注意的是大的项目gdb 调试的时候必须有源码, 或者手动设置源码的路径, eg: 
asp   idl   logs   test  aspctl.sh  conf    data     info  md5.015.04.23  src    version
其中asp 即为可执行的二进制文件, src 即为源代码目录

gdb 打印宏  编译加上 -gdwarf-2 -g3


gdb 调试多进程

set follow-fork-mode child 跟踪子进程

set follow-fork-mode parent 跟踪父进程


如果某一行代码被多个线程使用,可以这样设置断点:

(gdb)b pos.c:17 thread 5  //在地pos.c的17行设置断点,但只对第5个线程生效。

(gdb)b pos.c:17 thread 5 if ret > 0   // 在pos.c的17行设置断点,当内部栈变量ret > 0 时中断

当调试一个程序的时候,不能在线调试

gcore pid 生成core 文件

gstack  打印当前各线程调用栈

用strace命令查看系统调用和花费的时间
#strace -T -r -c -p pid

top -H -p pid命令查看进程内各个线程占用的CPU百分比


gdb 环境中执行shell 命令

(gdb) shell cmd 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值