Wie verwende ich PTRACE, um eine konsistente Ansicht mehrerer Threads zu erhalten?

Während ich arbeiteteauf diese FrageIch bin auf eine mögliche Idee gestoßen, die benutztptrace, aber ich kann nicht richtig verstehen, wieptrace interagiert mit Threads.

Angenommen, ich habe einen bestimmten Multithread-Hauptprozess und möchte ihn an einen bestimmten Thread anhängen (möglicherweise von einem verzweigten Kind).

Kann ich an einen bestimmten Thread anhängen? (Die Handbücher gehen in dieser Frage auseinander.)

Wenn ja, bedeutet das, dass beim Einzelschritt nur die Anweisungen dieses einen Threads durchlaufen werden? Stoppt es alle Threads des Prozesses?

Wenn ja, bleiben alle anderen Threads angehalten, während ich anrufePTRACE_SYSCALL oderPTRACE_SINGLESTEPoder tunalles Fäden weiter? Gibt es eine Möglichkeit, nur in einem einzelnen Thread vorwärtszugehen, aber sicherzustellen, dass die anderen Threads angehalten bleiben?

Grundsätzlich möchte ich das ursprüngliche Programm synchronisieren, indem ich alle Threads zum Stoppen zwinge und dann nur einen kleinen Satz von Single-Thread-Anweisungen durch schrittweises Ausführen des einen verfolgten Threads ausführen möchte.

Meine bisherigen persönlichen Versuche sehen ungefähr so ​​aus:

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);
}

Ich bin mir jedoch nicht sicher und kann keine geeigneten Referenzen finden, dass dies gleichzeitig korrekt ist und dassimportant_instruction() wird garantiert nur ausgeführt, wenn alle anderen Threads gestoppt sind. Ich verstehe auch, dass es Rennbedingungen geben kann, wenn die Eltern Signale von einer anderen Stelle empfangen, und ich habe gehört, dass ich diese verwenden solltePTRACE_SEIZE stattdessen, aber das scheint nicht überall zu existieren.

Jede Klarstellung oder Hinweise wäre sehr dankbar!

Antworten auf die Frage(4)

Ihre Antwort auf die Frage