番外

  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> 设置代码段断点,如果设置的函数所在的库还没有加载到进程地址空间,也可以设置断点,这个时候它是一个悬而未决的断点(pending状态),因为不确定其具体地址是多少,但是进程继续运行加载了库文件后,其地址就确定下来了

break [file:line] if cond 如果cond满足条件则在指定处断点

info breakpoints 查看断点

enable <break number> 使能断点

disable <break number> 禁用断点

delete <break number> 删除断点

watch <addr/variable> 设置数据段断点(也称内存断点或者硬件断点,Intel CPU最多支持同时设置4个数据断点)

awatch 设置数据写操作断点

rwatch 设置数据读操作断点

info watchpoints 查看观察点

backtrace 显示函数调用栈,如果出现符号表无法显示,而是显示??,则表示编译器没有为该段代码分配符号表,即一段匿名代码,比如汇编代码或者一次性执行的代码

where 与backtrace相同

run 从程序入口开始执行

continue 继续运行,直到下一个断点或者程序结束

next 执行下一行代码,如果代码行为子函数调用,不进入子函数内部,当做一条代码行执行

step 单步调试,执行下一行代码,如果代码行为子函数调用,进入子函数内部逐条执行

ni 执行下一条指令

si 单步调试,执行下一条指令

finish 运行直到当前函数执行完

frame <n> 选择第n层调用栈帧

up 选择上一层调用栈帧

down 选择下一层调用栈帧

info threads 查看所有线程

thread [thread number] 跳转到指定的线程

thread apply all <command> 针对所有线程执行指定命令

thread apply all bt 显示所有线程的调用栈

2、info类(观察调试相关信息)

info breakpoints 显示break断点

info watchpoints 显示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 显示所有线程

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] 设置汇编指令格式

Linux gdb模式使用AT&T汇编格式,通过set disassemble-flavor intel可以修改汇编格式

8、gdb中执行shell命令

使用shell <cmd>或者!<cmd>格式即可

9、gdb配置命令

set solib-absolute-prefix 设置应用程序加载库的前缀
set solib-search-path 设置应用程序加载库的绝对路径

ptrace(process trace)

GDB实现机制

gdb、glibc和linux都是属于GNU框架之下,gdb和strace命令一样,都是基于linux内核提供的ptrace系统调用实现的。

ptrace(process trace)系统调用允许父进程监视或者操控子进程的内部执行状态,修改子线程的内存和寄存器,因此它通常被gdb或者strace这类跟踪调试或者代码分析的工具使用。

gdb设置断点的原理是插桩,一段代码执行到桩处,则触发SIGTRAP(Trace/breakpoint trap)信号量。

参考文档

1、Debugging with gdb

1、gdb quick reference

Linux高级调试与优化——gdb调试命令的更多相关文章

  1. Linux gcc/g++下GDB调试及其调试脚本的使用

    GDB调试及其调试脚本的使用返回脚本百事通一.GDB调试 1.1. GDB 概述 GDB 是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB ...

  2. Linux下编译ffmpeg并用GDB调试

    1.在Ubuntu界面上调处命令行界面,最方便的方式是使用快捷键Ctrl+Alt+T. 2.安装SDL SDL是一个开源的多媒体开发库,可以设置图像和视频的绘制等操作.如果不安装SDL,FFMPEG将 ...

  3. 对linux高级用户有用的20个命令

    41.命令:ifconfig ifconfig命令用于配置网络接口信息.如配置网络接口的ip地址,默认网关地址等,以便机器能够联通互联网. 显示当前网络接口信息 viidiot@ubuntu:~$ i ...

  4. 使用Qt Creator作为Linux IDE,代替Vim:实现两台Linux电脑远程部署和gdb调试(一台电脑有桌面系统,一台电脑无桌面系统)

      版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/libaineu2004/article/details/62423830 尊重作者,支持原创,如 ...

  5. Linux下Eclipse里用gdb调试JNI里C/C++

    1,给Eclipse安装CDT插件 2,先以Debug方式运行java程序,停在java代码的断点上 3,Debug Configuration里选择C/C++ Attach to Applicati ...

  6. linux系统基础的优化以及常用命令

    编辑网卡配置文件 vim /etc/sysconfig/network-scripts/ifcfg-eth0 修改配置参数 ONBOOT= yes启动或者关闭ipsystemctl restart/s ...

  7. 一文入门Linux下gdb调试(一)

    作者:良知犹存 转载授权以及围观:欢迎添加微信号:Conscience_Remains 总述 在window下我们习惯了IDE的各种调试按钮,说实话确实挺方便的,但到了Linux下,没有那么多的IDE ...

  8. 一文入门Linux下gdb调试(二)

    作者:良知犹存 转载授权以及围观:欢迎添加微信号:Conscience_Remains 总述     今天我们介绍一下core dump文件,Core dump叫做核心转储,它是进程运行时在突然崩溃的 ...

  9. gdb调试线程

    gdb thread apply all bt 如果你发现有那么几个栈停在 pthread_wait 或者类似调用上,大致就可以得出结论:就是它们几个儿女情长,耽误了整个进程. 注意gdb的版本要高于 ...

随机推荐

  1. ExpressionTree学习笔记

    概述: 这段时间需要制定自定义查询条件,感觉有必要学习ExpressionTree. 学习参考资料:https://msdn.microsoft.com/en-us/library/mt654263. ...

  2. element-ui 中 switch 开关绑定number 的解决方法

    虽然element-ui 的文档中说明 v-model的值可以是 boolean / string / number 三种类型 , (文档在此)https://element.eleme.cn/#/z ...

  3. 1.Java 字符分割

    使用方法 性能比较 使用方法 或|,点.,加+,乘*,在字符串中出现时,如果这个字符串需要被split,则split时候,需要在前面加两个反斜杠. 与&,在split时候,不需要转义. 一.j ...

  4. HMC版本支持

      Target Version Upgrade From Upgrade Instructions Updates Date Available End of Service Models supp ...

  5. Java Script语法

    JavaScript 语法 JavaScript 是一个程序语言.语法规则定义了语言结构. JavaScript 语法 JavaScript 是一个脚本语言. 它是一个轻量级,但功能强大的编程语言. ...

  6. ui自动化之selenium操作(四)简单元素操作

    1. clear() clear()方法用于清除文本输入框内的内容:一般输入框中都有默认文字,如果不清空有可能会导致字符拼接: browser.find_element(By.ID,"use ...

  7. Rsync实现负载均衡的数据同步

    使用三台服务器:系统:CentOS 6.8 192.168.8.169 开发服务器 192.168.8.167 线上服务器1192.168.8.168 线上服务器2 实现思路:在开发服务器上制定一个规 ...

  8. [易学易懂系列|rustlang语言|零基础|快速入门|(13)|Generics泛型]

    [易学易懂系列|rustlang语言|零基础|快速入门|(13)] 有意思的基础知识 Generics泛型 我们今天来看看泛型. 什么是泛型? 我们来看看这样的情景: 我们要写一个函数,这个函数可以处 ...

  9. Java线程与Linux内核线程的映射关系(转)

    Java线程与Linux内核线程的映射关系 Java线程与Linux内核线程的映射关系Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程 ...

  10. jQuery $.ajax传递数组的traditional参数传递必须true 对象的序列化

    数组类型参数传递: 若一个请求中包含多个值,如:(test.action?tid=1&tid=2&tid=3),参数都是同一个,只是指定多个值,这样请求时后台会发生解析错误,应先使用 ...