gdb зависает в malloc

Предположим, что у меня есть такая программа на C, как это:

#include  #include  int main() { while (true) { void *p = malloc(1000); free(p); } return 0; } 

и я прикрепляю к нему с gdb как этот gdb a.out PID . gdb успешно присоединяется к нему, но я пытаюсь сделать что-то вроде call printf("bla bla bla") gdb freezes, и если я нажму 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 создавал объект и приобрел блокировку внутри malloc.c и в этот момент я подключился к gdb и попытался создать строку bla bla bla с помощью malloc .

Мой вопрос в том, как я могу обнаружить, что я внутри malloc.c и пусть моя программа завершит это выполнение? Мне нужно сделать это не внутри командной строки, а используя какой-то скрипт gdb (я могу выполнять команды внутри gdb с опцией -ex ).

Причина, по которой вы застыли, – это, вероятно, блокировка, которую удерживает ваша программа, а также требуется printf . Когда вы пытаетесь получить его дважды – вы терпите неудачу.

Возможная WA заключается в том, чтобы разбить вашу программу на call printf , как раз перед тем, как сделать вызов, введите finish – это приведет к завершению текущей функции и возврату к основному фрейму. Это обеспечит освобождение блокировки до вызова printf.

Если решение «finish» не работает для вас. Вот еще одна идея.

Вы можете проверить, находитесь ли вы в 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=, 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

Большая часть этого была отброшена отсюда