2011-09-02 10 views
13

Sto lavorando a un'applicazione linux che incorpora ptrace per osservare i thread di un altro processo. Quando l'applicazione che osservo avvia un processo figlio, questo funziona già abbastanza bene. Chiamando waitpid nella mia domanda posso ottenere i seguenti segnali nell'applicazione osservazione:ptrace e thread

  • SIGSTOP forma il processo figlio
  • SIGTRAP dal genitore

Per tenere traccia di tutti i bambini ho configurato ptrace con PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK, PTRACE_O_TRACECLONE e PTRACE_O_TRACEEXIT.

Mentre tutto funziona correttamente con i processi figlio, non riesco a osservare i thread dell'applicazione. Prendo il SIGTRAP dal processo di creazione del thread ma non ricevo alcun segnale dal thread.

C'è qualcosa di speciale con i thread e ptrace? In che modo strace tiene traccia dei thread (non sono riuscito a trovare alcuna routine speciale dedicata ai thread nel codice di strace)?

Questo è il modo che uso ptrace nella mia domanda:

  • Per prima cosa ho connettersi a un processo: ptrace(PTRACE_ATTACH, pid, NULL, NULL);
  • Poi, io chiamo waitpid(): trace_pid = waitpid(-1, &status, 0);
  • Impostare ptrace opzioni: ptrace(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXIT);

Dopo il collegamento al pid, chiamo waitpid() in un ciclo e chiamo ptrace(PTRACE_SETOPTIONS... per ogni nuova attività riportata da ptrace. Ovviamente, continuo le attività con SIGCONT dopo la gestione degli eventi.

+1

penso mi è venuta un po 'più vicino al nucleo del problema: quando viene creato un nuovo thread non ricevo nemmeno il sigstop nel processo di osservazione. Tuttavia, nella documentazione di ptrace sais: "inizia automaticamente a tracciare il processo appena clonato, che inizierà con un SIGSTOP." Come può accadere? – mupro

+0

Ho fatto un po 'di ulteriori indagini usando procfs e una piccola applicazione usando i thread posix. Tutta l'applicazione fa è iniziare un nuovo thread e dormire per un po '. Anche il nuovo thread sta dormendo per alcuni secondi. Come ho detto, non ricevo un sigstop con waitpid per il nuovo thread. Tuttavia, il file di stato nella procfs per il nuovo thread mi sta dicendo: Nome: thread_test Stato: t (tracing stop) Tgid: 2538 Pid: 2545 PPID: 2395 TracerPid: 2540 Così il nuovo thread è fermato ma waitpid non riceve il segnale di stop. Qual è il modo corretto di tracciare i thread? – mupro

risposta

13

Infine, ho trovato la soluzione io stesso: ho ricevuto i segnali provenienti da tutti i thread chiamando

waitpid(-1, &status, __WALL) 

invece di

waitpid(-1, &status, 0)