Я использую gdb 7.4.1 на встроенной цели powerpc для выполнения некоторого анализа моей многопоточной программы на C++, которая использует pthreads. Моя конечная цель — написать gdb с помощью python для автоматизации некоторых общих функций анализа. Проблема в том, что я обнаруживаю некоторое несоответствие в поведении, когда я запускаю команды по отдельности, а не в пользовательской команде gdb (или вызывая те же команды через скрипт python).
редактировать: я нашел этуссылку на очень похожую проблему в основном списке рассылки gdb. Хотя я не полностью согласен с ответом Педро об ограничении асинхронного режима, я думаю, что он подразумевает, что в асинхронном режиме нельзя доверять относительному времени определяемых пользователем последовательностей команд. Это то, что я нашел эмпирическим путем.
В обоих сценариях я выполняю следующие шаги запуска: загружаю свою программу, устанавливаю ее аргументы и включаю асинхронный и непрерывный режимы отладки, а затем запускаю программу в фоновом режиме:
(gdb) file myprogram
(gdb) set args --interface=eth0 --try-count=0
(gdb) set target-async on
(gdb) set pagination off
(gdb) set non-stop on
(gdb) run &
В этот момент, если я вручную выполню команды interrupt
, а затем info threads
, я увижу список всех запущенных потоков, кроме одного, который был остановлен. Затем я могу продолжить &
и повторить сколько душе угодно, это работает стабильно. Когда я остановлен, я могу проверить кадры стека этого потока, и все в порядке.
Однако, если вместо этого я помещу эти команды в определяемую пользователем команду gdb:
(gdb) define foo
(gdb) interrupt
(gdb) info threads
(gdb) continue &
(gdb) end
(gdb) foo
Cannot execute this command while the selected thread is running.
Тогда список потоков, напечатанный foo, указывает, что ни один поток не был остановлен, и поэтому команда continue &
возвращает Невозможно выполнить эту команду во время работы выбранного потока.
. Я думал, что это проблема, присущая асинхронным командам gdb, поэтому я вставил абсурдно долгое ожидание после команды прерывания и получил такое же поведение:
(gdb) define foo
(gdb) interrupt
(gdb) shell sleep 5
(gdb) info threads
(gdb) continue &
(gdb) end
(gdb) foo
Cannot execute this command while the selected thread is running.
С командой sleep или без нее я всегда могу выполнить команды CLI вручную и потоки останавливаются правильно.
Точно так же я получаю те же результаты, используя скрипт Python для просмотра потока:
import gdb, time
gdb.execute("file myprogram")
gdb.execute("set args --interface=eth0 --try-count=0")
gdb.execute("set target-async on")
gdb.execute("set pagination off")
gdb.execute("set non-stop on")
gdb.execute("run &")
time.sleep(5)
gdb.execute("interrupt")
# here, I inspect threads via gdb module interface
# in practice, they're always all running bc the program neven got interrupted
for thread in gdb.selected_inferior().threads():
print thread.is_running(),
gdb.execute("continue &")
Я получаю тот же результат, даже если я указываю from_tty=True
в gdb.execute
звонки. Кроме того, если я использую continue -a
, он подавляет строку ошибки, но в противном случае не помогает, потому что вызов прерывания по-прежнему не работает.
Итак... это:
shell sleep
(или python time.sleep()
) не делает того, что я предполагаю, в этом контексте.Спасибо.