内容简介:这部分内容让我想到了,吴军说的
- 虽然豆瓣上老早就标注为想看了,但20190416偶然搜到的这本书,20190417开始看了40页左右,7个Hack,以目前的状况要看10个才能第1遍撸完。
内容
chap1 热身准备 19/419
Hack1、调试是什么
Hack2、Debug hacks的地图 22/419
- 程序异常结束
- 程序不结束
-
strace
命令基本没怎么用过呢,soft lookup也没有听过
Hack3、调试的心得 24/419
- 复现之前
-
复现之后
- 确认现象
- 确认复现率和时间
- 分析
-
找不出原因
- 作者 把锅甩给硬件,哈哈---lionel
- 找以前的同类bug
这部分内容让我想到了,吴军说的 专业和业余的区别 。
chap2 调试前的必知必会 31/419
Hack4、获取进程的内核转储 31/419
-
启用内核转储
-
启用
ulimit -c unlimted
-
gdb -c core.* ./a.out
//core文件 进程 -
gdb l 5
-- 这个可以看到文件的第几行?在调试core的时候?
-
启用
-
在专用目录中生成内核转储
-
cat /etc/sysctl.conf
修改kernel.core_pattern的值 -
sysctrl -p
- kernel.core_pattern中可设置的格式符
-
-
使用用户模式辅助程序自助压缩内核转储文件
-
exec gzip ->
- lionel,这个理解了,还没好好看呢
-
-
启用整个系统的内核转储功能
- 34/419
Hack5、调试器的基本使用方法(之一) 36/419
-
准备
gcc -Wall -02 -g 源文件 CFLAGS = -Wall -02 -g ./configure CFLAGS="-Wall -02 -g"
-
启动
-
$gdb 可执行文件名
-
-
设置断点
-
b file.c :110
// 通过指定文件名和行号, 我第一次用时,不知道- break +偏移量 【 暂停位置往后3行 】 这2个没用过
- break -偏移量
- break *地址
-
b
后面啥也不加,就会在下一行设置断点
-
info break
用于查看设置好的断点
-
-
运行
-
run
可以简写成r
,然后加参数 -
start
命令也可以? 我也用得极少
-
-
显示栈帧
-
backtrace
简写bt
,别名还有where
和info stack
简写成info s
- 我主要用在调试core的时候了
-
bt N
只显示开头N个帧;bt -N
只显示最后N个的帧; -
bt full 3
从外向内显示3个栈帧,及其局部变量。 这个就没用过
-
-
显示变量
-
p 变量
-
-
显示寄存器
-
info registers
简称info reg
-
p/格式 变量
- 寄存器可使用的格式
-
-
单步执行
-
next
即n
-
step
即s
,进入函数内部。 书中写错了 -
nexti
或stepi
逐条执行汇编指令
-
-
继续运行
-
continue
简写为c
-
有种我之前不知道的
,
c 5
表示5次遇到断点不停止,第6次遇到断点时才暂停执行。
-
-
监视点
-
watch <表达式>
这个使用得比较少
-
-
删除断点和监视点
-
delete <编号>
即d 2
或者d 2-10
-
- 其它断点
-
改变变量的值
-
set variable <变量>=<表达式>
这个在我项目中,是有想过,但没找到解决方案
-
-
生成内核转储文件
generate-core-file gcore
Hack6、调试器的基本使用方法(之二) 50/419
-
attach到进程
-
attach pid
上回看人家调试的时候,就用了attach这个命令 -
在gdb和进程分离时使用
detach
命令,这样进程可以继续运行 -
info proc
显示进程信息
-
-
条件断点
-
break 断点 if 条件
,举例b iseq_compile if node==0
-
condition 断点编号
-
-
反复执行
ignore 断点编号 次数
-
删除断点和禁用断点
-
clear
删除已定义的断点 -
disable
临时禁用;enable
断点重新启用 -
disable display 显示编号
-
disable mem 内存区域
-
-
断点命令
-
commads
可以定义在断点中断后自动执行的命令。
-
-
常用命令及省略形式(别名)
x info list show
Hack7、调试器的基本使用方法(之三) 57/419
-
值的历史
p $ show value
-
变量
-
set $i=0
,随意定义变量;p $i
-
-
命令历史
-
show history
,命令历史文件们于./.gdb_history
-
- 初始化文件(.gdbinit)
- 命令定义
Hack8、Intel架构的基本知识 63/419
- 字节序
- 32位环境中的寄存器
-
64位环境中的寄存器
-
CPUID
指令可以查看运行中的处理器支持的物理地址空间。
-
-
地址
- Linux采用(flat model)内存模型
- 还有一种是 分段式内存模型 (segment model)
- 数据类型
Hack9、调试时必需的栈知识 70/419
-
0
- [sum.c]
- 函数调用和栈的关系
- 调试器的backtrace
-
使用GDB操作栈帧
-
frame
命令查看现在选择的帧。 -
选择帧可以使用
up
和down
命令 -
i frame 1
用info命令的frame选项可以看到更详细的栈帧信息。
-
-
栈大小的限制
-
i proc mapping
-
Hack10、函数调用时的参数传递方法(x86_64篇) 79/419
- 函数参数与调试
- 通过GDB确认
- x86_64下的调用
Hack11、函数调用时的参数传递方法(i386篇) 84/419
- i386下的函数调用
-
i386中的寄存器调用
-
gcc在函数声明中添加
__attribute__((regparm(3)))
这种语法格式见过,好像会在main之前执行
-
gcc在函数声明中添加
Hack12、函数调用时的参数传递方法(C++篇) 87/419
-
C++语言的函数调用
-
nm
命令
-
- 在x86_64中查看参数
- 在i386中查看参数
Hack13、怎样学习汇编语言 90/419
-
查看反汇编的输出结果
gcc -Wall -00 assemble.c -o assemble objdump -d --no-show-raw-insn assemble
- 设置变量的值:movl指令
- 用if语句比较变量:cmpl指令
- while语句的汇编代码
- 函数调用:call指令
- 函数指针调
- 数组操作:movzbl指令
- 返回值设置
Hack14、从汇编代码查找相应的源代码 95/419
-
用crash反汇编
crash /boot/vmlinux-2.6.19 dis journal_commit_transaction
-
根据前后的信息确定源代码范围
- [fs/jbd/commit.c]
-
确认寄存器偏移量和结构的成员
crash> struct -o transacton_t carsh> mod -s jbd
-
确认源代码文件名和行号
-
crash> dis -l journal_commit_transaction
-
chap3 内核调试的准备 105/419
chap4 应用程序调试实践 157/419
Hack26、发生SIGSEGV,应用程序异常停止 157/419
-
0
-
bt 10
,如果某个地址被调用多次,可以怀疑,递归函数调用产生栈溢出。
-
-
源代码层面的调试
info signal up
-
栈溢出导致SIGSEGV的应对方法
- 为捕获栈溢出,需要使用备用栈,相应函数是sigaltstack(2)
Hack27、backtrace无法正确显示 165/419
-
概要
- 调试器的backtrace并非万能钥匙。
-
问题内容
- 某个线程间通信的程序中含有bug,生成了core。
-
检查backtrace
-
执行
bt
看不出啥有用信息;似乎是nanosleep()
执行过程中产生了SIGSEGV。
-
执行
-
什么是backtrace
- 调试器的backtrace是 根据栈里保存的函数返回地址来显示的 ,如果bt没用,可以理解为栈被破坏了。
-
查看寄存器和栈
info reg x/i 0x3b4869ac80
Hack28、数组非法访问导致内存破坏 169/419
- 数组的错误操作
-
可怀疑是缓冲区溢出的情况
- 即使指定了编译选项-g,利用GDB读入core并显示backtrace之后,栈帧中还是没有显示符号名。 通常,指定-g选项后,各个栈帧都应显示出函数名 。
-
运行地址的改变
- 第1类:直接指定地址并调用
- 第2类:指定一块内存区域,保存了跳转地址
- 第3类:执行ret命令,用于函数结束时返回调用者函数
-
确定破坏跳转地址值的位置(栈破坏)
-
x/30c $esp-15
-
p (char*)$esp-20
这两个命令是啥意思?
-
-
确定破坏跳转地址值的位置(GOT破坏)
disas 0x080483ca objdump -s bufov2
Hack29、利用监视点检测非法内存访问 175/419
- 监视点何时有效?
-
监视点的设置方法
-
watch *0x80495a8
-
-
寻找问题原因
p $pc disas
Hack30、malloc()和free()发生故障 178/419
- 错误使用内存相关库函数引起的bug
-
利用MALLOC_CHECK_进行调试
-
env MALLOC_CHECK_=1 ./membug
-
Hack31、应用程序停止响应(死锁篇)181/419
-
死锁的例子
- [astall.c]
-
停止响应时的解决方法 没遇到过,得实践下lionel
ps ax -L | grep astall gdb -p
- 使用多个mutex时的调试方法
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
HTTP/2基础教程
Stephen Ludin、Javier Garza / 罗正龙、郑维智 / 人民邮电出版社 / 2018-1 / 49.00元
让网站和应用更快速、更简洁、更稳健,从而有效提升用户体验,这无疑是众多开发者梦寐以求的。然而互联网发展日新月异,HTTP/1.1协议已经难以满足现今的需求。在众多Web性能提升方案中,HTTP/2值得尝试。 本书是HTTP/2实用指南,介绍了HTTP/2的设计初衷和新特性,以及如何才能充分利用这些特性来打造高性能网站及应用。作者用定量分析方法,对比了不同网络环境下及不同浏览器上HTTP/1.......一起来看看 《HTTP/2基础教程》 这本书的介绍吧!