Как очистить точку останова от процессора после уничтожения GDB? - PullRequest
0 голосов
/ 09 ноября 2018

Я отлаживал приложение Free Pascal в GDB, работающее в среде Linux через SSH, когда мое SSH-соединение разрывалось. Из опыта я видел, что GDB закрывается, когда это происходит, и, конечно, я запустил pidof gdb и ничего не вернулось. Я снова открыл GDB и подключился к тому же работающему приложению, и я смог продолжить отладку и закончил работу через несколько минут. Через час после того, как я закончил отладку, приложение неожиданно умерло. Единственный журнал, который у меня есть, отражает то, что произошло, это:

Nov  5 16:29:59 kernel: [846469.866825] traps: Maintain[9065] trap int3 ip:7f5148924cf1 sp:7f51376a4420 error:0

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

Вот мои вопросы:

  1. Возможно ли, чтобы GDB оставил ловушку останова в процессоре после неожиданного закрытия?
  2. Если это так, есть ли способ очистить точку останова от процессора после того, как он был применен, а затем неожиданно закрыт?

1 Ответ

0 голосов
/ 09 ноября 2018

Я предполагаю, что этот сигнал был вызван тем, что программа достигла точки останова, которую я установил

Это предположение, вероятно, неверно: GDB удаляет все точки останова, когда автоматически отключается от процесса.

Похоже, адрес ловушки 7f5148924cf1 принадлежит какой-то общей библиотеке.

Если у вас есть дамп ядра или записано расположение общих библиотек, когда процесс был активен, вы можете проверить библиотеку, которая была загружена по этому адресу, и посмотреть, какая там инструкция. Скорее всего, это int3, который не имеет никакого отношения к точкам останова GDB. Нередко помещать __asm__("INT3") или __asm__(UD2) в ветку «не может быть», эффективно реализуя assert, который не может быть скомпилирован.

Еще одна возможность: ваше приложение перепрыгнуло через дикий указатель на функцию.

Я только что посмотрел на objdump -d для моего libpthread.so.0, и я вижу много INT3 s:

__pthread_initialize_minimal:
...
    9479:       b8 00 40 00 00          mov    $0x4000,%eax
    947e:       e9 8f fe ff ff          jmpq   9312 <__pthread_initialize_minimal+0x1f2>
    9483:       cc                      int3   
    9484:       cc                      int3   
    9485:       cc                      int3   
    9486:       cc                      int3   
    9487:       cc                      int3   
    9488:       cc                      int3   
    9489:       cc                      int3   

sigcancel_handler:
...
    950c:       e8 2f 9e 00 00          callq  13340 <__pthread_unwind>
    9511:       cc                      int3   
    9512:       cc                      int3   
    9513:       cc                      int3   
    9514:       cc                      int3   

и т.д.. Если приложение когда-либо попадает, например, 0x9511 или любой другой INT3 s, он умрет с SIGTRAP, как и ваше приложение.

...