时间:2021-07-01 10:21:17 帮助过:4人阅读
0.转储功能(core dump):
(1).开启转储功能:首先用 >ulimit -c 查看是否开启转储功能,如果命令返回不是0则已经开启,否则就是未开启。>ulimit -c unlimited 命令可以开启转储功能。也可以用 >ulimit -c 1024来设定转储文件的大小。 (2).设定转储文件生成地址:编辑/etc/sysctl.conf文件,在文件最后加入下列两行: kernel.core_pattern = /var/core/%t-%e-%p.core kernel.core_uses_pid = 0 然后将文件保存起来,保存完成之后执行:>sysctl -p命令(注意:执行这个命令需要root权限。)。此时执行一个会当机的程序,会在/var/core/文件夹下面生成转储文件(例如:1432378356-a.out-4821.core)。上面设定的文件名是有固定格式的,core_pattern中设定的就是文件保存目录和文件的名字格式。其中%t是转储时的unix时间戳,%e是当前执行的文件名,%p是crash进程的PID。格式符说明如下:(3).转储文件的压缩:通过在/etc/sysctl.conf文件的core_pattern中加入压缩脚本以及管道命令,可以对生成的转储文件进行压缩。首先在/etc/sysctl.conf文件中加入下列两行(如果已经存在则修改成下面的形式): kernel.core_pattern = |/usr/localsbin/zipsh %t %e %p kernel.core_uses_pid = 0 保存文件,然后执行:>sysctl -p命令。 /usr/local/sbin/zipsh文件的内容如下: #!/bin/sh exec gzip - > /var/core/$1-$2-$3.core.gz 这样的话,以后都会在/var/core下生成压缩的转储文件。
格式符号 说明 %% %字符本身 %p 被转储进程的进程ID(PID) %u 被转储进程的真是用户ID(UID) %g 被转储进程的真是组(GID) %s 引发转储的信号编号 %t 转储时间,unix时间戳(从1970年1月1日0时开始的秒数) %h 主机名 %e 可执行文件的名称 %c 转储文件的大小上限(内核版本2.6.24以后可使用)
(4).内存:可以查看具体内存地址中的内容,比如:目前执行的汇编指令,以及栈中内容等。 (GDB) x $pc:显示程序指针指向位置的内容。 (GDB) x/i $pc:显示程序当前位置的汇编指令。 (GDB) x/10i $pc:显示程序当前位置开始往后的10条汇编指令。 (GDB) disassem $pc:反汇编当前函数。简写为:disas $pc。 2.调试: (1).断点:调试程序中,设置断点进行调试是最方便有效的手段,因此学会如果灵活设置断点是调试的基本功。: A.设置断点: (GDB) break <函数名>:对当前正在执行的文件中的指定函数设置断点。可简写为:(GDB) b <函数名> (GDB) break <行号>:对当前正在执行的文件中的特定行设置断点。可简写为:(GDB) b <行号> (GDB) break <文件名:行号>:对指定文件的指定行设置断点。最常用的设置断点方式。可简写为:(GDB) b <文件名:行号> (GDB) break <文件名:函数名>:对指定文件的指定函数设置断点。C++类中的方法似乎不好使。可简写为:(GDB) b <文件名:函数名> (GDB) break <+/-偏移量>:当前指令行+/-偏移量出设置断点。可简写为:b <+/-偏移量> (GDB) break <*地址>:指定地址处设置断点。可简写为:b <*地址> B.查看、删除断点: (GDB) info break :显示所有断点以及监视点。可简写为:(GDB) i b (GDB) delete <编号>:删除编号指向的断点或者监视点。可简写为:(GDB) d <编号> (GDB) clear <行号>:删除改行的断点。 (GDB) clear <文件名:行号>:删除改行的断点。 C.设置无效、有效断点: (GDB) disable <断点编号> : 当前断点设置为无效。 (GDB) enable <断点编号>:当前断点设置为有效。 (2).监视点:可以监视某个变量,在变量被访问或者被修改时程序会在当前点进入断点。删除,查看监视点的方式与断点相同。设置监视点方式如下: (GDB) watch <表达式>:表达式发生变化时暂停。 (GDB) awatch <表达式>:表达式访问或者改变时暂停。 (GDB) rwatch <表达式>:表达式被访问时暂停。 (3).条件断点:在调试程序过程中,有时候我们只想在某个条件下停止程序,然后进行单步调试,而条件断点就是为此而设计。下面是条件断点的操作方式: (GDB) b <断点> if <条件表达式> : 例如:b main.cpp:8 if x=10 && y=10 (GDB) condition <断点编号>:删除该断点的条件。 (GDB) condition <断点编号> <条件表达式>:修改断点条件。例如:condition 1 x=10 && y=10 (4).断点命令:每次断点发生时候,想要查看的变量很多时,如果每个变量都手动print则需要浪费很多时间。断点命令可以在断点发生时批量执行GDB命令。下面是断点命令的设置方式: (GDB) commands <断点编号> (GDB) >print x (GDB) >print y (GDB) >end 首先输入GDB命令commands <断点编号>然后回车,这时候会出现>提示符。出现>提示符后可以输入断点发生时需要执行的GDB命令,每行一条,全部输入完成后输入end结束断点命令。 (5).反复执行:单步执行时如果进入了你不关心的函数,你想立即跳出函数;或者进入了大循环中,你想立即循环。下面的命令可以帮到你: (GDB) ignore <断点编号> <次数>:忽略N次断点。 (GDB) c N: 执行N次指令,会忽略断点。 (GDB) s/stepi/n/nexti N:往后执行N行,不会忽略断点。 (GDB) finish:执行完当前函数后停止,不会忽略断点。 (GDB) until:执行完当前循环后停止,不会忽略断点。 (GDB) until <地址>:执行到指定地址停止。 (6).设置变量值:对变量的值进行控制,可以更快的调试自己的程序。下面就是设置变量值的方法: (GDB) set variable <变量> = <表达式>:将变量的值设定为指定表达式的值。例如 set variable x=10 (7).手动生成转储文件: (GDB) generate-core-file 简写为:(GDB) gcore 3.调试在线进程: (1).启动GDB时链接目标进程:在启动GDB的时候,通过参数-p指定目标进程,就可以进入调试状态。刚链接成功后,程序是暂停运行状态,你可以进行设置断点等操作,然后输入(GDB) c 命令继续运行。命令如下: >gdb -p <PID>:PID是进程ID,可以通过>ps aux | grep <程序名> 获得。或者直接 >gdb -p `pidof <程序名>`也可以。>pidof <程序名>是通过名字获取进程ID的命令。 (2).GDB中链接目标进程: (GDB) attach <PID> (3).断开链接: (GDB) detach 4.调试多线程程序: (1).查看线程: (GDB) info thread:查看所有线程信息,可简写为:i thr (2).切换到指定线程: (GDB) thread <线程编号>:选中出现问题的线程,可简写为:thr <线程编号> (3).调试守护者进程:守护者进程在启动好子进程后,会自动关闭主进程,如果没有设定监控模式的话,GDB会提示断开与进程的链接。所以必须设定监控对象,设置方式如下: (GDB) set follow-fork-mode child/parent
格式 说明 x 显示为十六进制数 d 显示为十进制数 u 显示为无符号十进制数 o 显示为八进制数 t 显示为二进制数 a 显示为地址 c 显示为字符(ASCII) f 显示为浮点小数 s 显示为字符串 i 显示为机器语言(仅在显示内存的x命令中可用)
GDB调试器使用总结
标签: