Używam gdb 7.4.1 na osadzonym elemencie powerpc do przeprowadzenia analizy mojego wielowątkowego programu C++, który używa pthreads. Moim celem końcowym jest skrypt gdb z pythonem, aby zautomatyzować niektóre typowe funkcje analizy. Problem polega na tym, że znajduję pewne rozbieżności w zachowaniu, gdy uruchamiam polecenia pojedynczo vs. w komendzie zdefiniowanej przez gdb (lub wywołując te same komendy za pomocą skryptu Pythona).Wątek C++ nie zatrzymuje się w trybie asynchronicznym gdb, używając sekwencji poleceń zdefiniowanej przez użytkownika lub pythona
edytuj: Znalazłem this odniesienie do bardzo podobnego problemu na głównej liście mailingowej gdb. Chociaż nie w pełni śledzę reakcję Pedra na temat ograniczenia trybu asynchronicznego, myślę, że sugeruje on, że w trybie asynchronicznym nie można ufać względnemu czasowi sekwencji poleceń zdefiniowanych przez użytkownika. To właśnie znalazłem empirycznie.
W obu scenariuszach I wykonaj następujące czynności rozruchu, ładowania mój program, ustanawiając swoje argumenty i włączeniu asynchronicznych i non-stop trybie debugowania, a następnie uruchomienie programu 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 wydam polecenia interrupt
, a następnie info threads
, zobaczę listę wszystkich wątków z wyjątkiem tego, który został zatrzymany. Wtedy mogę continue &
i powtórzyć do moich serc treści, działa konsekwentnie. Po zatrzymaniu mogę sprawdzić ramkę stosu wątku i wszystko jest w porządku.
Jednak jeśli zamiast tego Polecenia te na sygnał gdb zdefiniowany przez użytkownika:
(gdb) define foo
(gdb) interrupt
(gdb) info threads
(gdb) continue &
(gdb) end
(gdb) foo
Cannot execute this command while the selected thread is running.
to lista gwint drukowane przez bla oznacza brak nici były zatrzymywane, a więc continue &
zwraca polecenie Cannot execute this command while the selected thread is running.
. Myślałem, że to problem nieodłącznie związane z asynchronicznym gdb komendanta, więc wprowadziłem absurdalnie długo czekać po komendzie przerwania i mam ten sam problem:
(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 lub bez polecenia uśpienia, zawsze mogę wydać instrukcję Komendy CLI i wątki są zatrzymywane poprawnie.
Podobnie, mam takie same wyniki sprowadzający skrypt Pythona zrobić Lektura wątku:
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 &")
uzyskać ten sam wynik, nawet jeśli mogę określić from_tty=True
w zaproszeniach gdb.execute
. Ponadto, jeśli użyję continue -a
, to pominie ciąg znaków błędu, ale nie pomoże inaczej, bc wywołanie przerwania nadal nie działa.
Więc ... to:
- błąd w kokpicie? Czy jest coś, co pomijam lub robię niewłaściwie, biorąc pod uwagę to, co próbuję osiągnąć? Czy to działa, czy też muszę używać GDB/MI do asynchronicznego "napędu" gdb w ten sposób?
- problem z czasem? Może wywołanie
shell sleep
(lubpython time.sleep()
) nie robi tego, co przypuszczam, że byłoby w tym kontekście. - Problem z moim używaniem pthreads? Zakładam, że skoro używanie ręcznych poleceń gdb zawsze działa poprawnie, to nie jest tak.
- problem z gdb?
Dzięki.