Как продолжить выполнение после нажатия контрольных точек в gdb? - PullRequest
0 голосов
/ 26 июня 2019

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

1) использовать hook-stop.

define hook-stop
continue
end

Но, похоже, hook-stop срабатывает только один раз. Когда в следующий раз будет достигнута другая точка останова, выполнение все равно будет остановлено.

2) использовать gdb.events.stop.connect().

def handle_stop_event(event):
    if isinstance(event, gdb.BreakpointEvent):
        gdb.execute('continue')

gdb.events.stop.connect(handle_stop_event)

Этот метод работает хорошо. Но если было достигнуто слишком много точек останова, возникает ошибка "Fatal Python error: Cannot recover from stack overflow.".
Кажется из-за рекурсивного вызова. Мне интересно, почему gdb.execute('continue') может вызвать эту проблему.

Я искал в Интернете и все еще не нашел решения.

PS: GDB версии 7.11.1 в Ubuntu 16.04

Любой совет будет признателен! Заранее спасибо.

1 Ответ

1 голос
/ 26 июня 2019

Кажется, continue внутри hook-stop не работает должным образом. Вы видели этот вопрос Я вчера отправил?

Я думаю, что лучший подход здесь - это написать вспомогательную функцию на python и установить условную точку останова. Или используя commands - см. Раздел «Списки команд точек останова» в руководстве пользователя GDB.

Вот как это сделать (также описано в руководстве).

Модуль Python:

import gdb

class should_skip_f(gdb.Function):
    def __init__ (self):
        super (should_skip_f, self).__init__("should_skip")

    def invoke(self):
        return True  # Your condition here

should_skip_f()
(gdb) b <your target> if !$should_skip()

Или добавьте условие к существующим контрольным точкам с помощью

(gdb) condition <BNUM> !$should_skip()

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

'commands [LIST...]'
'... COMMAND-LIST ...'
'end'
     Specify a list of commands for the given breakpoints.  The commands
     themselves appear on the following lines.  Type a line containing
     just 'end' to terminate the commands.

Что касается рекурсии - да, это плохой «дизайн» сценария отладчика (если говорить о разработке одноразовых одноразовых вещей). Вы можете посмотреть, что там происходит, если вы расширите свой скрипт на Python, например,

import inspect
...
  def handle_stop_event(event):
    ...
    print(len(inspect.stack())) # Or you can print the frames themselves...

Интерпретатор Python не знает, что выполнение не возвращается из gdb.execute("continue"), поэтому фреймы стека Python для вызовов этой функции никогда не уничтожаются.

Вы можете увеличить максимальный размер стека для интерпретатора, но, как я уже сказал, этот сценарий не кажется мне лучшим решением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...