Wątek C ++ nie zatrzymuje się w trybie asynchronicznym gdb przy użyciu sekwencji poleceń zdefiniowanych przez użytkownika lub Pythona

Używam gdb 7.4.1 na osadzonym celu powerpc, aby przeprowadzić analizę mojego wielowątkowego programu C ++, który używa pthreads. Moim końcowym celem jest skrypt gdb z python, aby zautomatyzować niektóre typowe funkcje analizy. Problem polega na tym, że znajduję pewne rozbieżności w zachowaniu, gdy uruchamiam polecenia indywidualnie w poleceniu zdefiniowanym przez użytkownika gdb (lub wywołując te same polecenia za pomocą skryptu Pythona).

edytuj: znalazłemto odniesienie do bardzo podobnego problemu na głównej liście dyskusyjnej gdb. Chociaż nie podążam za odpowiedzią Pedro na temat ograniczenia trybu asynchronicznego, myślę, że sugeruje on, że w trybie asynchronicznym nie można ufać względnemu taktowaniu sekwencji poleceń zdefiniowanych przez użytkownika. To właśnie znalazłem empirycznie.

W obu scenariuszach wykonuję następujące kroki uruchamiania, ładuję mój program, ustawiam jego argumenty i włączam asynchroniczne i non-stop tryby debugowania, a następnie uruchamiam program w tle:

(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 &

W tym momencie, jeśli ręcznie wydaminterrupt i wtedyinfo threads Polecenia, widzę listę wszystkich wątków uruchomionych z wyjątkiem jednego, który został zatrzymany. Wtedy ja mogęcontinue & i powtarzam do moich serc, działa konsekwentnie. Po zatrzymaniu mogę sprawdzić ramki stosu tego wątku i wszystko jest w porządku.

Jeśli jednak zamiast tego umieściłem te polecenia w zdefiniowanym przez użytkownika poleceniu 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.

Następnie lista wątków wydrukowana przez foo wskazuje, że wątki nie zostały zatrzymane, a więccontinue & powraca polecenieCannot execute this command while the selected thread is running.. Myślałem, że jest to problem związany z asynchronicznym poleceniem gdb, więc wstawiłem absurdalnie długie oczekiwanie po poleceniu przerwania i otrzymałem to samo zachowanie:

(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.

Z poleceniem sleep lub bez niego zawsze mogę wydać ręczne polecenia CLI, a wątki zostaną poprawnie zatrzymane.

Podobnie uzyskuję te same wyniki, które pochodzą ze skryptu Pythona, aby wykonać wątek perusal:

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 &")

Otrzymuję ten sam wynik, nawet jeśli określęfrom_tty=True wgdb.execute połączenia. Również jeśli używamcontinue -a pomija ciąg błędu, ale nie pomaga w przeciwnym razie bc wywołanie przerwania nadal nie działa.

Więc ... to jest:

błąd kokpitu? Czy jest coś, co pomijam lub robię źle, biorąc pod uwagę to, co próbuję osiągnąć? Czy powinno to działać, czy też muszę używać GDB / MI do asynchronicznego „napędu” gdb w ten sposób?problem z wyczuciem czasu? Może przywołaćshell sleep (lubpython time.sleep()) nie robi tego, co zakładam, w tym kontekście.problem z moim użyciem pthreads? Założyłem, że skoro używanie ręcznych komend gdb zawsze działa poprawnie, tak nie jest.problem z gdb?

Dzięki.

questionAnswers(1)

yourAnswerToTheQuestion