假设我有这样的C程序:
#include <stdlib.h> #include <stdbool.h> int main() { while (true) { void *p = malloc(1000); free(p); } return 0; }
我用gdb
来连接它,就像这个gdb a.out PID
。 gdb
成功地附加到它,但我试图做一些像call printf("bla bla bla")
gdb
冻结,如果我按下Ctrl^C
我得到这个:
(gdb) call printf("bla bla bla") ^C Program received signal SIGINT, Interrupt. __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95 95 ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: No such file or directory. The program being debugged was signaled while in a function called from GDB. GDB remains in the frame where the signal was received. To change this behavior use "set unwindonsignal on". Evaluation of the expression containing the function (malloc) will be abandoned. When the function is done executing, GDB will silently stop.
我想这是因为我的a.out
创build了一个对象,并在malloc.c
获得了一个锁,在这一刻我连接到gdb
并尝试使用malloc
创buildstring“bla bla”。
我的问题是我如何检测到我在malloc.c
,让我的程序完成这个执行? 我需要做的不是在命令行中,而是使用某种types的gdb脚本(我只能使用-ex
选项在gdb
执行命令)。
你被冻结的原因可能是你的程序持有的锁,也是printf
要求的。 当你试图获得两次 – 你失败了。
一个可能的WA是在call printf
时候打开你的程序,在你打电话之前,键入finish
– 它会导致当前的功能完成并返回到主框架。 这将确保在您调用printf之前锁定是免费的。
如果“完成”解决方案不适合你。 这是另一个想法。
你可以检查你是否在malloc当你打破程序。 基于布尔输入/输出,您可以跳过调用打印命令。 这是一个工作的例子。
# gdb script: pygdb-logg.gdb # easier interface for pygdb-logg.py stuff # from within gdb: (gdb) source -v pygdb-logg.gdb # from cdmline: gdb -x pygdb-logg.gdb -se test.exe # first, "include" the python file: source -v pygdb-logg.py # define shorthand for inMalloc(): define inMalloc python inMalloc() end
关联的python文件:
# gdb will 'recognize' this as python # upon 'source pygdb-logg.py' # however, from gdb functions still have # to be called like: # (gdb) python print logExecCapture("bt") import sys import gdb import os def logExecCapture(instr): # /dev/shm - save file in RAM ltxname="/dev/shm/c.log" gdb.execute("set logging file "+ltxname) # lpfname gdb.execute("set logging redirect on") gdb.execute("set logging overwrite on") gdb.execute("set logging on") gdb.execute("bt") gdb.execute("set logging off") replyContents = open(ltxname, 'r').read() # read entire file return replyContents # in malloc? def inMalloc(): isInMalloc = -1; # as long as we don't find "Breakpoint" in report: while isInMalloc == -1: REP=logExecCapture("n") #Look for calls that have '_malloc' in them isInMalloc = REP.find("_malloc") if(isInMalloc != -1): # print ("Malloc:: ", isInMalloc, "\n", REP) gdb.execute("set $inMalloc=1") return True else: # print ("No Malloc:: ", isInMalloc, "\n", REP) gdb.execute("set $inMalloc=0") return False gdb -x pygdb-logg.gdb -se test.exe
从命令行或脚本中,
(gdb) inMalloc (gdb) print $inMalloc
从一个实际的测试程序:
Program received signal SIGINT, Interrupt. 0x00007ffff7a94dba in _int_malloc (av=<optimized out>, bytes=1) at malloc.c:3806 3806 malloc.c: No such file or directory. (gdb) inMalloc (gdb) if $inMalloc >print $inMalloc >end $1 = 1
我相信你的脚本可以使用类似的“if”结构来做/不做printf
大部分这是从这里被击倒