LINUX.ORG.RU

как научить GDB позиционироваться на обработчике сигнала?


0

1

привет.

есть такой трейс:

#0  0xb77dc424 in __kernel_vsyscall ()
#1  0xb75a3622 in wait () from /lib/i386-linux-gnu/libc.so.6
#2  0x08048e50 in gdb_print_stack () at main.cpp:74
#3  0x08048f70 in signal_handler (signum=11) at main.cpp:90
#4  <signal handler called>
#5  0x0804908d in func (i=0, c=0x804938e "44") at main.cpp:125
хочу добавить еще печать аргументов функции, и локальных переменных. для этого, нужно чтоб при печати трейса, GDB останавливался уровнем выше обработчика.

обратите внимание на строку: #4 <signal handler called>

т.е. GDB точно знает, что это обработчик. я думаю, что должна существовать какая-то команда/возможность указать отладчику печатать стек именно в обработчике.

подскажите куда копать?

благодарен.

★★★
Ответ на: комментарий от rand

этот вариант я уже обдумывал.. думается мне, что глубина хвоста стека не обязательно 3.

вот трейс того же кода но собранного с -O2:

#0  0xb7714424 in __kernel_vsyscall ()
#1  0xb74db622 in wait () from /lib/i386-linux-gnu/libc.so.6
#2  0x08048cd4 in gdb_print_stack () at main.cpp:72
#3  0x08048dd3 in signal_handler (signum=11) at main.cpp:88
#4  <signal handler called>
#5  0xb7468810 in vfprintf () from /lib/i386-linux-gnu/libc.so.6
#6  0xb74901cb in vsnprintf () from /lib/i386-linux-gnu/libc.so.6
#7  0xb7472c73 in snprintf () from /lib/i386-linux-gnu/libc.so.6
#8  0x08048fdb in func (i=i@entry=-7782, c=c@entry=0x8049172 "44") at main.cpp:136
тут уже нужно чтоб печатался восьмой фрейм.

niXman ★★★
() автор топика

Я не понял, чего ты хочешь, но брейкпойнт с заданной последовательностью команд тебе поможет. help break, help commands.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

поясняю...

дебагер запускается в обработчике сигнала SIGSEGV. поэтому, ручное вмешательство невозможно. нужно «научить» дебагер всегда позиционироваться фреймом выше обработчика.

niXman ★★★
() автор топика
Ответ на: комментарий от niXman

Так дебагер запускается исключительно чтобы stacktrace посмотреть? Можно использовать процедуру backtrace в обработчике.

gdb можно подсунуть произвольный выполняемый файл с его командами при старте! И frame считается от #0, т.е. в обоих случаях «frame 5» будет вставать над обработчиком.

io ★★
()
Ответ на: комментарий от niXman

поясняю...

нужно «научить» дебагер всегда позиционироваться фреймом выше обработчика.

Тебе что - нужна готовая последовательность команд, навешиваемая на брейкпойнт?

tailgunner ★★★★★
()
Ответ на: комментарий от io

дебагер запускается исключительно чтобы stacktrace посмотреть?

пока - да. но я хочу еще научить его печатать аргументы функции и локальные переменные. а для этого, мне нужно его научить позиционироваться на фрейм до обработчика.

gdb можно подсунуть произвольный выполняемый файл с его командами при старте!

оно сейчас так и есть:

set logging on /path/to/log.file
bt
info args
info locals
q
проблема только с «info args» и «info locals» потому, что для того чтоб они показывали что нужно, GDB нужно установить_на/сообщить нужный фрейм.

а для того чтоб это сделать, нужно определить номер фрейма обработчика, и от него и плясать.

номер интересующего фрейма не может быть константой. проверенно.

niXman ★★★
() автор топика
Ответ на: комментарий от io

возможно кто-то в курсе, на какое событие навешивать пайтоновсий обработчик для того, чтоб из скрипта парсить трейс и выдирать номер фрейма?

niXman ★★★
() автор топика
Ответ на: комментарий от niXman

тут еще сложность с тем, что интересующая меня функция func() находится в непостоянном положении относительно хендлера.

niXman ★★★
() автор топика
Ответ на: комментарий от niXman

по желанию можно поменять имя $a :-)

(gdb) set variable $a=__kernel_rt_sigreturn
(gdb) p/x $a
$5 = 0x11040c
(gdb) while $eip!=$a
 >up
 >end
#1  <signal handler called>
(gdb) up
#2  0x0804852b in abzac (i=393110) at sigact.c:24
24			abzac(i+1);

Думаю ясно как это превратить в gdb-скрипт.

io ★★
()
Ответ на: комментарий от io

надеюсь, последний вопрос: могу ли я каким-то образом определить, при отмотке стека, что '$pc' указывает на функцию в моей программе, а не в libc/libstdc++ ?

niXman ★★★
() автор топика
Ответ на: комментарий от niXman

А кто мешает сравнивать с адресами в рамках программы? Посмотреть (или явно влинковать/определить) первую-последнюю процедуру и использовать сравнение с диапазоном.

io ★★
()
Ответ на: комментарий от io

никто не мешает. думал, в gdb есть для этого уже что-то готовенькое =)

снова спасибо.

niXman ★★★
() автор топика
Ответ на: комментарий от niXman

а если сегфолт действительно в либС произойдет ? :)
Ну например ты дал «неправильный» блок памяти под заполнение.

Jetty ★★★★★
()
Ответ на: комментарий от Jetty

да, есть такая вероятность. пусть остается как есть.

niXman ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.