2016-05-03 4 views
2

Я часто работаю с PostgreSQL для отладки, и он использует SIGINT внутренне для некоторых своих межпроцессорных сигналов.Отладка программы, использующей SIGINT с gdb

В результате при запуске определенных бэкендов под gdb исполнение обычно прервано. Можно использовать команду signal, чтобы убедиться, что SIGINT передано программе и что она не захвачена gdb ... но затем gdb не отвечает на control-C в командной строке, так как отправляет SIGINT.

При запуске:

handle SIGINT noprint nostop pass 

gdb пожалуется

SIGINT is used by the debugger. 
Are you sure you want to change it? (y or n) y 

Есть ли способ, чтобы получить GDB, чтобы использовать другой сигнал прерывания? Или любой альтернативный метод, который позволил бы мне иметь gdb игнорировать SIGINT?

(Это не проблема для большинства бэкэнд-отладок PostgreSQL, но это боль с работниками фона и autovacuum).

+0

_Is Есть ли способ, чтобы получить GDB, чтобы использовать другой сигнал прерывания _ - SIGINT поставляется из системы, когда входной драйвер видит управление C в буфере. Теоретически можно было бы сказать программе относиться к другому сигналу так, как он будет относиться к SIGINT, но на практике я сомневаюсь, что gdb или что-то еще сделает это, потому что значение не является гибким из операционной системы. – mah

+0

Не могли бы вы его решить, настроив gdb на обработку другого сигнала с помощью 'stop nopass' (или' stop pass', если программа нуждается в сигнале) и отправить этот сигнал программе вместо использования ctrl-c? – kaylum

+0

Использование, например. 'kill -USR1' с другого терминала? – immibis

ответ

1

В UNIX-подобных системах вы можете отличить инициированный tty SIGINT от одного отправленного kill, посмотрев на элемент si_pid в структуре siginfo. Если pid равно 0, оно исходит от tty.

Так что вы могли бы сделать что-то вроде этого:

catch signal SIGINT 
commands 
    if $_siginfo._sifields._kill.si_pid == 0 
    print "Received SIGINT from tty" 
    else 
    printf "Received SIGINT from %d; continuing\n", $_siginfo._sifields._kill.si_pid 
    signal SIGINT 
    end 
end 
1

Эта часть gdb немного сложна, как из-за ее истории, так и из-за различных режимов работы, которые она поддерживает.

Можно подумать, что работающий gdb в отдельном терминале и только с использованием attach поможет ему поступать правильно, но я не думаю, что это так просто.

В одну сторону вперед можно использовать только асинхронное выполнение при отладке, а затем использовать команду для прерывания нижнего. Что-то вроде:

(gdb) attach 5555 
... attaches 
(gdb) continue & 
... lots of stuff happens 
(gdb) interrupt -a 

В зависимости от версии GDB вам может понадобиться установить target-async для этой работы.

4

Читатели, которые в конечном итоге на этой странице (как я) с несколько иной вариации этой проблемы, было бы, возможно, будет более заинтересован в этом вопросе:

Debugging a segmentation fault when I do ctrl c

... и ответ, который:

  • отправить SIGINT внутри самого БГД:

    сигнала (GDB) 2

(Обычно я бы разместить ссылку как простой комментарий под вопрос OP на этой странице, но так как уже есть 7 комментарии, комментарии скрыты/похоронены.)

Если вы читаете все детали вопроса OP здесь, то очевидно, что мой ответ неверен для OP.

Однако мой ответ является правильным для многих ситуаций, которые могут быть описаны одним и тем же названием:? «Отладка программы, которая использует SIGINT с помощью GDB»

Смежные вопросы