Jak korzystać z PTRACE, aby uzyskać spójny widok wielu wątków?
Kiedy pracowałemna to pytanie, Natknąłem się na możliwy pomysł, który wykorzystujeptrace
, ale nie jestem w stanie właściwie zrozumieć, w jaki sposóbptrace
współdziała z wątkami.
Przypuśćmy, że mam podany, wielowątkowy proces główny i chcę dołączyć się do konkretnego wątku w nim (być może z rozwidlonego dziecka).
Czy mogę dołączyć do konkretnego wątku? (Podręczniki różnią się w tym pytaniu.)
Jeśli tak, to czy oznacza to, że pojedyncza operacja przechodzi tylko przez instrukcje jednego wątku? Czy zatrzymuje wszystkie wątki procesu?
Jeśli tak, czy wszystkie pozostałe wątki pozostają zatrzymane podczas połączeniaPTRACE_SYSCALL
lubPTRACE_SINGLESTEP
lub zrób towszystko wątki nadal? Czy istnieje sposób na przejście do przodu tylko w jednym wątku, ale gwarantuje, że pozostałe wątki pozostaną zatrzymane?
Zasadniczo chcę zsynchronizować oryginalny program, zmuszając wszystkie wątki do zatrzymania się, a następnie wykonuję tylko niewielki zestaw instrukcji jednowątkowych, wykonując jednoetapowy wątek.
Moje osobiste próby do tej pory wyglądają trochę tak:
pid_t target = syscall(SYS_gettid); // get the calling thread's ID
pid_t pid = fork();
if (pid > 0)
{
waitpid(pid, NULL, 0); // synchronise main process
important_instruction();
}
else if (pid == 0)
{
ptrace(target, PTRACE_ATTACH, NULL, NULL); // does this work?
// cancel parent's "waitpid" call, e.g. with a signal
// single-step to execute "important_instruction()" above
ptrace(target, PTRACE_DETACH, NULL, NULL); // parent's threads resume?
_Exit(0);
}
Nie jestem jednak pewien i nie mogę znaleźć odpowiednich referencji, że jest to jednocześnie poprawne i toimportant_instruction()
jest gwarantowane wykonanie tylko wtedy, gdy wszystkie inne wątki są zatrzymane. Rozumiem również, że mogą istnieć warunki wyścigu, gdy rodzic odbiera sygnały z innego miejsca i słyszałem, że powinienem użyćPTRACE_SEIZE
zamiast tego, ale to nie wydaje się istnieć wszędzie.
Wszelkie wyjaśnienia lub odniesienia byłyby bardzo mile widziane!