番外
2019年7月26日至27日,公司邀请《软件调试》和《格蠹汇编——软件调试案例集锦》两本书的作者张银奎老师进行《Linux高级调试与优化》培训,有幸聆听张老师的课程。若干年前有幸拜读过《软件调试》一书,受益匪浅。
张老师给人的感觉温文尔雅,谦谦如玉,对Windows和Linux内核的内存分配和任务管理机制有非常深入的了解,对Intel CPU的内部实现机制也有很深的功底,如数据/代码缓存、数据/代码TLB缓存、乱序执行、MMU机制等。
整个培训的内容包括:
1)Linux gdb调试命令
2)Linux信号量机制和应用程序崩溃
3)用户态进程coredump转储和分析
4)用户态堆
5)Linux内存管理
6)Linux任务管理
7)使用kdb/kgdb调试Linux内核
8)oops和panic
Linux gdb命令
1、跟踪调试类
file <可执行文件> 加载可执行文件
break <func>|<file:line> 设置代码段断点
watch <addr/variable> 设置数据段断点(也称内存断点或者硬件断点,Intel CPU最多支持同时设置4个数据断点)
awatch 设置数据写操作断点
rwatch 设置数据读操作断点
info break 查看断点
enable <break number> 使能断点
disable <break number> 禁用断点
delete <break number> 删除断点
bt(backtrace) 显示函数调用栈
run 从程序入口开始执行
continue 继续运行,直到下一个断点或者程序结束
n(next) 执行下一行代码,如果为子函数调用,不进入子函数内部
ni 执行下一条指令
s(step) 单步调试,执行下一行代码,如果为子函数调用,进入子函数内部
si 单步调试,执行下一条指令
finish 执行到当前函数退栈
frame <n> 选择第n层调用栈帧
up 选择上一层调用栈帧
down 选择下一层调用栈帧
info threads 查看所有线程
thread [thread number] 跳转到指定的线程
2、info类(观察调试相关信息)
info break 显示break断点
info watch 显示watch观察点
info files 显示elf文件信息
info sharedlibrary 显示共享库地址映射
info registers 显示CPU通用寄存器值
info all-registers 显示所有CPU寄存器值
info args 显示函数参数
info var [regex] 显示全局变量或者名字包含regex字符串的全局变量
info locals显示局部变量
info func [regex] 显示函数或者函数名称中包含regex字符串的函数
info address s 显示符号s的地址
info signals 显示信号量
info stack 显示函数调用栈,作用同bt命令
info frame [n] 显示指令调用栈帧
info display 显示显示配置
info line num 显示代码行
info source 显示代码文件名
info sources 显示正在使用的代码列表
info threads 显示所有线程
thread apply all <command> 针对所有线程执行指定命令
thread apply all bt 显示所有线程的调用栈
3、show命令观察gdb本身的信息
4、x直接观察内存
x/128wx $sp
x/128wi $pc
例如:
(gdb) x/64wx $sp
0xe342c548: 0x00000000 0xe342cb40 0x00000000 0x00000000
0xe342c558: 0x06f74f8f 0x0c6a543b 0xe342cb40 0xfff333f4
0xe342c568: 0x00000000 0x00000152 0x00000000 0xfff333f4
0xe342c578: 0x00000000 0xe342c67c 0x00000000 0x00000000
0xe342c588: 0x00000000 0x00000000 0x00000000 0x00000000
0xe342c598: 0x00000000 0x00000000 0x00000000 0x00000000
0xe342c5a8: 0x00000000 0x00000000 0x00000000 0x00000000
0xe342c5b8: 0x00000000 0x00000000 0x00000000 0x00000000
0xe342c5c8: 0x00000000 0x00000000 0x00000000 0x00000000
0xe342c5d8: 0x00000000 0x00000000 0x00000000 0x00000000
0xe342c5e8: 0x00000000 0x00000000 0x00000000 0x00000000
0xe342c5f8: 0x00000000 0x00000000 0x00000000 0x00000000
0xe342c608: 0x00000000 0x00000000 0x00000000 0x00000000
0xe342c618: 0x00000000 0x00000000 0x00000000 0x00000000
0xe342c628: 0x00000000 0x00000000 0x00000000 0x00000000
0xe342c638: 0x00000000 0x00000000 0x00000000 0x00000000
5、list命令
显示当前执行命令前后的代码
disp /3i $pc 每次单步执行都显示接下来要执行三条指令
6、print命令
p [/f] expr - print命令后通常接C语言表达式,返回表达式结果
ptype [expr]/[type] 打印结构体
p addr@[num] 表示打印从addr地址开始的num个字节
7、disassemble 反汇编
set disassemble-flavor [att|intel|arm|thumb] 设置汇编指令格式
Linux gdb模式使用AT&T汇编格式,通过set disassemble-flavor intel可以修改汇编格式
8、gdb中执行shell命令
使用shell <cmd>或者!<cmd>格式即可
参考文档