Поток C++ не останавливается в асинхронном режиме gdb с использованием определяемой пользователем последовательности команд или последовательности команд python

Я использую 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, он подавляет строку ошибки, но в противном случае не помогает, потому что вызов прерывания по-прежнему не работает.

Итак... это:

  • ошибка кабины? Есть ли что-то, что я пропускаю или делаю неправильно, учитывая то, чего я пытаюсь достичь? Должно ли это работать, или мне нужно использовать GDB/MI для асинхронного «управления» gdb таким образом?
  • проблема со временем? Возможно, вызов shell sleep(или python time.sleep()) не делает того, что я предполагаю, в этом контексте.
  • Проблема с использованием pthreads? Я предположил, что, поскольку использование ручных команд gdb всегда работает правильно, это не так.
  • Проблема с gdb?

Спасибо.

6
задан timblaktu 22 May 2012 в 01:42
поделиться