2012-05-15 27 views
6

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

Odpowiedz

0

Myślę, że to najprawdopodobniej problem z gdb. Nie wiem wystarczająco dużo o rzeczach kontrolujących gorsze rzeczy, żeby być bardziej pewnymi siebie. Wiem, że gorsza kontrola generalnie nie została podłączona do Pythona ...

Jedna rzecz, którą warto wypróbować, to posiadanie oddzielnego wątku Pythona, który czeka, a następnie wysyła polecenie "interrupt" do głównego wątku gdb za pomocą gdb .ogłosić wydarzenie.

Następnie, zamiast synchronicznie analizować wątki lub wykonywać pracę po "przerwie", należy użyć źródła zdarzeń gdb.events.stop, aby uruchomić swoje działania.

Proszę zgłaszać błędy o otworach w API Pythona.