gdb调试学习总结《二》

gdb调试学习总结《二》

一. 关于编译指定:
DEBUG “ENV{CXXFLAGS} -O0 -g -ggdb -Werror -Wall”
RELEASE “ENV{CXXFLAGS} -O3 -Werror -Wall”
CXX_FLAGS “{DEBUG} -mfloat-abi=softfp -mfpu=neon -std=c++0x -Wl,-Map=XXXXmain.map”
-Werror:把警告当作错误;
-Wall:打开一些很有用的警告选项;

二. 多线程的调试:
初次接触gdb下多线程的调试,往往会忽视gdb中活动线程的概念。一般来讲,在使用gdb调试的时候,
只有一个线程为活动线程,如果希望得到其他的线程的输出结果,必须使用thread命令切换至指定的线程,
才能对该线程进行调试或观察输出结果。
GDB多线程调试的基本命令:
info threads 显示当前可调试的所有线程,前面有*的是当前调试的线程。
thread 切换当前调试的线程为指定ID的线程。
break <thread_test.c:123> thread all 在所有线程中相应的行上设置断点(watch也可以指定thread)
thread apply 让一个或者多个线程执行GDB命令command。
thread apply all 让所有被调试线程执行GDB命令command。
set scheduler-locking off|on|step 在step或continue命令调试时候,其他线程也是同时执行的,怎么只让被调试 程序执行呢? off 不锁定任何线程,也就是所有线程都执行,这是默认值。on只有当前被调试程序会执行。
*** 重点实例:thread apply all bt

三. 基本调试补充:
tbreak 临时设置一次:
设置方法与break相同,只不过tbreak只在断点停一次,过后会自动将断点删除
条件断点:
条件可以是任何合法的c 表达式。 例如 b n if val1 == val2
当已经设置了断点,可以用condition命令对断点号 n 添加条件,例:condition 2 val1 ==val2
取消断点条件:condition bnum

四. 对于发布程序,死机如何调试?
方法1. 打开系统开关,让其可以在死掉的时候生成core文件。
ulimit -a
ulimit -c unlimited
arm-xxx-gdb main core
死掉的时候就可以在当前目录看到core.pid(pid为进程号)的文件。接着使用gdb定位。

方法2. 使用Linux中提供的三个函数用于打印调用堆栈,保存到文件中。
int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *buffer, int size);
void backtrace_symbols_fd(void *const *buffer, int size, int fd);

五. 其他工具:
pstack: pstack用来跟踪进程栈,这个命令在排查线程问题时非常有用(比如发现死锁)。
strace: 常用来跟踪进程执行时的系统调用和所接收的信号(跟踪到系统调用,包括参数,返回值,执行消耗的时间)。
gdb、gcore

死机时刻的寄存器 https://blog.csdn.net/wuzengfengjing1/article/details/80926859

####################################################
gdb的使用感悟:
注意:问题定位最重要的是问题复现,研究操作和异常现象的关系,大概猜测异常时代码执行流。
主要在以下几方面使用GDB:
A1.查看调用堆栈(coredump文件)、或查看与修改运行时变量;
作用:查看死机位置,或者分析运行流程(断点加bt)与打印变量。
A2.多线程调试,查看当前线程运行状态(以确定当前线程是不是因为等锁等原因挂起)
死锁分析: https://blog.csdn.net/zhang2531/article/details/52085731;
辅助工具:pstack。
gdb指令步骤:info thread{多次执行位置变否}-》thread [num]-》where -》frame [num] -》p mutex1。
A3.碰到难缠的内存非法改写问题,用GDB的断点与查看内存变化以定位改写者;
主要三种方法:
方法1:第一现场:如果是固定的内存被破坏,可以利用gdb来抓取第一现场的调用栈;
方法2:利用Git二分回退代码库的commit点,缩减代码范围进行code review;
方法3:第二现场:第二现场一般都能定位到间接原因。如果程序crash还不是第一现场,可以利用mprotect使程序crash在第一现场; 如果这种越界第二现场每次都不同地方的,具有随机性,用保护页内存也不一定行。
有兴趣的关注kgdb:
对于linux内核调试kgdb:https://blog.csdn.net/gqb_driver/article/details/9117597

发布了41 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/wade_510/article/details/102710480