unsigned char valgrind_wait (char *ourstatus) { int pid; unsigned long wptid; ThreadState *tst; enum target_signal sig; int code; pid = VG_(getpid) (); dlog(1, "enter valgrind_wait pid %d\n", pid); regcache_invalidate(); valgrind_update_threads(pid); /* First see if we are done with this process. */ if (exit_status_to_report != 0) { *ourstatus = exit_status_to_report; exit_status_to_report = 0; if (*ourstatus == 'W') { code = exit_code_to_report; exit_code_to_report = 0; dlog(1, "exit valgrind_wait status W exit code %d\n", code); return code; } if (*ourstatus == 'X') { sig = target_signal_from_host(exit_code_to_report); exit_code_to_report = 0; dlog(1, "exit valgrind_wait status X signal %u\n", sig); return sig; } } /* in valgrind, we consider that a wait always succeeds with STOPPED 'T' and with a signal TRAP (i.e. a breakpoint), unless there is a signal to report. */ *ourstatus = 'T'; if (vki_signal_to_report.si_signo == 0) sig = TARGET_SIGNAL_TRAP; else sig = target_signal_from_host(vki_signal_to_report.si_signo); if (vgdb_interrupted_tid != 0) tst = VG_(get_ThreadState) (vgdb_interrupted_tid); else tst = VG_(get_ThreadState) (VG_(running_tid)); wptid = tst->os_state.lwpid; /* we can only change the current_inferior when the wptid references an existing thread. Otherwise, we are still in the init phase. (hack similar to main thread hack in valgrind_update_threads) */ if (tst->os_state.lwpid) current_inferior = gdb_id_to_thread (wptid); stop_pc = (*the_low_target.get_pc) (); dlog(1, "exit valgrind_wait status T ptid %s stop_pc %s signal %u\n", image_ptid (wptid), sym (stop_pc), sig); return sig; }
static void remove_thread_if_not_in_vg_threads (struct inferior_list_entry *inf) { struct thread_info *thread = get_thread (inf); if (!VG_(lwpid_to_vgtid)(thread_to_gdb_id(thread))) { dlog(1, "removing gdb ptid %s\n", image_ptid(thread_to_gdb_id(thread))); remove_thread (thread); } }