static void fbsd_resume (struct thread_resume *resume_info) { int pending_flag; /* Yes, the use of a global here is rather ugly. */ resume_ptr = resume_info; for_each_inferior (&all_threads, fbsd_set_resume_request); /* If there is a thread which would otherwise be resumed, which has a pending status, then don't resume any threads - we can just report the pending status. Make sure to queue any signals that would otherwise be sent. */ pending_flag = 0; find_inferior (&all_processes, resume_status_pending_p, &pending_flag); if (debug_threads) { if (pending_flag) fprintf (stderr, "Not resuming, pending status\n"); else fprintf (stderr, "Resuming, no pending status\n"); } if (pending_flag) for_each_inferior (&all_threads, fbsd_queue_one_thread); else { block_async_io (); enable_async_io (); for_each_inferior (&all_threads, fbsd_continue_one_thread); } }
static void stop_all_processes (void) { stopping_threads = 1; for_each_inferior (&all_processes, send_sigstop); for_each_inferior (&all_processes, wait_for_sigstop); stopping_threads = 0; }
void clear_inferiors (void) { for_each_inferior (&all_threads, free_one_thread); for_each_inferior (&all_dlls, free_one_dll); clear_list (&all_threads); clear_list (&all_dlls); current_inferior = NULL; }
void set_register_cache (struct reg *regs, int n) { int offset, i; #ifndef IN_PROCESS_AGENT /* Before changing the register cache internal layout, flush the contents of valid caches back to the threads. */ regcache_invalidate (); #endif reg_defs = regs; num_registers = n; offset = 0; for (i = 0; i < n; i++) { regs[i].offset = offset; offset += regs[i].size; } register_bytes = offset / 8; /* Make sure PBUFSIZ is large enough to hold a full register packet. */ if (2 * register_bytes + 32 > PBUFSIZ) fatal ("Register packet size exceeds PBUFSIZ."); #ifndef IN_PROCESS_AGENT /* Re-allocate all pre-existing register caches. */ for_each_inferior (&all_threads, realloc_register_cache); #endif }
void clear_inferiors (void) { for_each_inferior (&all_threads, free_one_thread); all_threads.head = all_threads.tail = NULL; }
static void win32_clear_inferiors (void) { if (current_process_handle != NULL) CloseHandle (current_process_handle); for_each_inferior (&all_threads, delete_thread_info); clear_inferiors (); }
static void linux_resume (int step, int signal) { struct process_info *process; process = get_thread_process (current_inferior); /* If the current process has a status pending, this signal will be enqueued and sent later. */ linux_resume_one_process (&process->head, step, signal); if (cont_thread == 0 || cont_thread == -1) for_each_inferior (&all_processes, linux_continue_one_process); }
static void fake_breakpoint_event (void) { OUTMSG2(("fake_breakpoint_event\n")); faked_breakpoint = 1; memset (¤t_event, 0, sizeof (current_event)); current_event.dwThreadId = main_thread_id; current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT; current_event.u.Exception.ExceptionRecord.ExceptionCode = EXCEPTION_BREAKPOINT; for_each_inferior (&all_threads, suspend_one_thread); }
void set_register_cache (struct reg *regs, int n) { int offset, i; reg_defs = regs; num_registers = n; offset = 0; for (i = 0; i < n; i++) { regs[i].offset = offset; offset += regs[i].size; } register_bytes = offset / 8; for_each_inferior (&all_threads, regcache_realloc_one); }
static void linux_kill (void) { struct thread_info *thread = (struct thread_info *) all_threads.head; struct process_info *process = get_thread_process (thread); int wstat; for_each_inferior (&all_threads, linux_kill_one_process); /* See the comment in linux_kill_one_process. We did not kill the first thread in the list, so do so now. */ do { ptrace (PTRACE_KILL, pid_of (process), 0, 0); /* Make sure it died. The loop is most likely unnecessary. */ wstat = linux_wait_for_event (thread); } while (WIFSTOPPED (wstat)); }
/* synchronize threads known by valgrind and threads known by gdbserver */ static void valgrind_update_threads (int pid) { ThreadId tid; ThreadState *ts; unsigned long ptid; struct thread_info *ti; /* call remove_thread for all gdb threads not in valgrind threads */ for_each_inferior (&all_threads, remove_thread_if_not_in_vg_threads); /* call add_thread for all valgrind threads not known in gdb all_threads */ for (tid = 1; tid < VG_N_THREADS; tid++) { #define LOCAL_THREAD_TRACE " ti* %p vgtid %d status %s as gdb ptid %s lwpid %d\n", \ ti, tid, VG_(name_of_ThreadStatus) (ts->status), \ image_ptid (ptid), ts->os_state.lwpid if (VG_(is_valid_tid) (tid)) { ts = VG_(get_ThreadState) (tid); ptid = ts->os_state.lwpid; ti = gdb_id_to_thread (ptid); if (!ti) { /* we do not report the threads which are not yet fully initialized otherwise this creates duplicated threads in gdb: once with pid xxx lwpid 0, then after that with pid xxx lwpid yyy. */ if (ts->status != VgTs_Init) { dlog(1, "adding_thread" LOCAL_THREAD_TRACE); add_thread (ptid, ts, ptid); } } else { dlog(2, "(known thread)" LOCAL_THREAD_TRACE); } } #undef LOCAL_THREAD_TRACE } }
void set_register_cache (struct reg *regs, int n) { int offset, i; reg_defs = regs; num_registers = n; offset = 0; for (i = 0; i < n; i++) { regs[i].offset = offset; offset += regs[i].size; } register_bytes = offset / 8; /* Make sure PBUFSIZ is large enough to hold a full register packet. */ if (2 * register_bytes + 32 > PBUFSIZ) fatal ("Register packet size exceeds PBUFSIZ."); /* Re-allocate all pre-existing register caches. */ for_each_inferior (&all_threads, realloc_register_cache); }
static void fbsd_detach (void) { for_each_inferior (&all_threads, fbsd_detach_one_process); }
/* Clear out any old thread list and reinitialize it to a pristine state. */ static void child_init_thread_list (void) { for_each_inferior (&all_threads, delete_thread_info); }
void clear_dlls (void) { for_each_inferior (&all_dlls, free_one_dll); clear_inferior_list (&all_dlls); }
void regcache_invalidate (void) { for_each_inferior (&all_threads, regcache_invalidate_one); }
void clear_dlls (void) { for_each_inferior (&all_dlls, free_one_dll); all_dlls.head = all_dlls.tail = NULL; }
void regcache_release (void) { /* Flush and release all pre-existing register caches. */ for_each_inferior (&all_threads, free_register_cache_thread_one); }
static void linux_detach (void) { for_each_inferior (&all_threads, linux_detach_one_process); }