《Debug Hacks》-看了21个Hack

栏目: C · 发布时间: 5年前

内容简介:这部分内容让我想到了,吴军说的
  • 虽然豆瓣上老早就标注为想看了,但20190416偶然搜到的这本书,20190417开始看了40页左右,7个Hack,以目前的状况要看10个才能第1遍撸完。

内容

chap1 热身准备 19/419

Hack1、调试是什么

Hack2、Debug hacks的地图 22/419

Hack3、调试的心得 24/419

  • 复现之前
  • 复现之后
    • 确认现象
    • 确认复现率和时间
  • 分析
  • 找不出原因
    • 作者 把锅甩给硬件,哈哈---lionel
    • 找以前的同类bug

这部分内容让我想到了,吴军说的 专业和业余的区别

chap2 调试前的必知必会 31/419

Hack4、获取进程的内核转储 31/419

  • 启用内核转储
    • 启用 ulimit -c unlimted
    • gdb -c core.* ./a.out //core文件 进程
    • gdb l 5 -- 这个可以看到文件的第几行?在调试core的时候?
  • 在专用目录中生成内核转储
  • 使用用户模式辅助程序自助压缩内核转储文件
    • 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 ,别名还有 whereinfo stack 简写成 info s
    • 我主要用在调试core的时候了
    • bt N 只显示开头N个帧; bt -N 只显示最后N个的帧;
    • bt full 3 从外向内显示3个栈帧,及其局部变量。 这个就没用过
  • 显示变量
    • p 变量
  • 显示寄存器
    • info registers 简称 info reg
    • p/格式 变量
      • 寄存器可使用的格式
  • 单步执行
    • nextn
    • steps ,进入函数内部。 书中写错了
    • nextistepi 逐条执行汇编指令
  • 继续运行
    • 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 命令查看现在选择的帧。
    • 选择帧可以使用 updown 命令
    • 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之前执行

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时的调试方法

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python编程快速上手

Python编程快速上手

Albert Sweigart / 王海鹏 / 人民邮电出版社 / 2016-7-1 / 69.00元

如今,人们面临的大多数任务都可以通过编写计算机软件来完成。Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。通过Python编程,我们能够解决现实生活中的很多任务。 本书是一本面向实践的Python编程实用指南。本书的目的,不仅是介绍Python语言的基础知识,而且还通过项目实践教会读者如何应用这些知识和技能。本书的首部分介绍了基本Python编程概念,第二部分介绍了一些不......一起来看看 《Python编程快速上手》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具