struct aarch64_debug_reg_state * aarch64_get_debug_reg_state (pid_t pid) { struct process_info *proc = find_process_pid (pid); return &proc->priv->arch_private->debug_reg_state; }
static void aarch64_linux_prepare_to_resume (struct lwp_info *lwp) { struct thread_info *thread = get_lwp_thread (lwp); ptid_t ptid = ptid_of (thread); struct arch_lwp_info *info = lwp->arch_private; if (DR_HAS_CHANGED (info->dr_changed_bp) || DR_HAS_CHANGED (info->dr_changed_wp)) { int tid = ptid_get_lwp (ptid); struct process_info *proc = find_process_pid (ptid_get_pid (ptid)); struct aarch64_debug_reg_state *state = &proc->priv->arch_private->debug_reg_state; if (show_debug_regs) fprintf (stderr, "prepare_to_resume thread %ld\n", lwpid_of (thread)); /* Watchpoints. */ if (DR_HAS_CHANGED (info->dr_changed_wp)) { aarch64_linux_set_debug_regs (state, tid, 1); DR_CLEAR_CHANGED (info->dr_changed_wp); } /* Breakpoints. */ if (DR_HAS_CHANGED (info->dr_changed_bp)) { aarch64_linux_set_debug_regs (state, tid, 0); DR_CLEAR_CHANGED (info->dr_changed_bp); } } }
/* Kill all inferiors. */ static int win32_kill (int pid) { struct process_info *process; if (current_process_handle == NULL) return -1; TerminateProcess (current_process_handle, 0); for (;;) { if (!child_continue (DBG_CONTINUE, -1)) break; if (!WaitForDebugEvent (¤t_event, INFINITE)) break; if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break; else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT) { struct target_waitstatus our_status = { 0 }; handle_output_debug_string (&our_status); } } win32_clear_inferiors (); process = find_process_pid (pid); remove_process (process); return 0; }
/* Called when resuming a thread. If the debug regs have changed, update the thread's copies. */ static void arm_prepare_to_resume (struct lwp_info *lwp) { struct thread_info *thread = get_lwp_thread (lwp); int pid = lwpid_of (thread); struct process_info *proc = find_process_pid (pid_of (thread)); struct arch_process_info *proc_info = proc->priv->arch_private; struct arch_lwp_info *lwp_info = lwp->arch_private; int i; for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++) if (lwp_info->bpts_changed[i]) { errno = 0; if (arm_hwbp_control_is_enabled (proc_info->bpts[i].control)) if (ptrace (PTRACE_SETHBPREGS, pid, (PTRACE_TYPE_ARG3) ((i << 1) + 1), &proc_info->bpts[i].address) < 0) perror_with_name ("Unexpected error setting breakpoint address"); if (arm_hwbp_control_is_initialized (proc_info->bpts[i].control)) if (ptrace (PTRACE_SETHBPREGS, pid, (PTRACE_TYPE_ARG3) ((i << 1) + 2), &proc_info->bpts[i].control) < 0) perror_with_name ("Unexpected error setting breakpoint"); lwp_info->bpts_changed[i] = 0; } for (i = 0; i < arm_linux_get_hw_watchpoint_count (); i++) if (lwp_info->wpts_changed[i]) { errno = 0; if (arm_hwbp_control_is_enabled (proc_info->wpts[i].control)) if (ptrace (PTRACE_SETHBPREGS, pid, (PTRACE_TYPE_ARG3) -((i << 1) + 1), &proc_info->wpts[i].address) < 0) perror_with_name ("Unexpected error setting watchpoint address"); if (arm_hwbp_control_is_initialized (proc_info->wpts[i].control)) if (ptrace (PTRACE_SETHBPREGS, pid, (PTRACE_TYPE_ARG3) -((i << 1) + 2), &proc_info->wpts[i].control) < 0) perror_with_name ("Unexpected error setting watchpoint"); lwp_info->wpts_changed[i] = 0; } }
static int lynx_detach (int pid) { ptid_t ptid = lynx_ptid_build (pid, 0); struct process_info *process; process = find_process_pid (pid); if (process == NULL) return -1; lynx_ptrace (PTRACE_DETACH, ptid, 0, 0, 0); the_target->mourn (process); return 0; }
static int lynx_kill (int pid) { ptid_t ptid = lynx_ptid_build (pid, 0); struct target_waitstatus status; struct process_info *process; process = find_process_pid (pid); if (process == NULL) return -1; lynx_ptrace (PTRACE_KILL, ptid, 0, 0, 0); lynx_wait (ptid, &status, 0); the_target->mourn (process); return 0; }
/* Detach from inferior PID. */ static int win32_detach (int pid) { struct process_info *process; winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL; winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL; #ifdef _WIN32_WCE HMODULE dll = GetModuleHandle (_T("COREDLL.DLL")); #else HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL")); #endif DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop); DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit); if (DebugSetProcessKillOnExit == NULL || DebugActiveProcessStop == NULL) return -1; { struct thread_resume resume; resume.thread = minus_one_ptid; resume.kind = resume_continue; resume.sig = 0; win32_resume (&resume, 1); } if (!DebugActiveProcessStop (current_process_id)) return -1; DebugSetProcessKillOnExit (FALSE); process = find_process_pid (pid); remove_process (process); win32_clear_inferiors (); return 0; }
static ptid_t lynx_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options) { int pid; int ret; int wstat; ptid_t new_ptid; if (ptid_equal (ptid, minus_one_ptid)) pid = lynx_ptid_get_pid (thread_to_gdb_id (current_thread)); else pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid)); retry: ret = lynx_waitpid (pid, &wstat); new_ptid = lynx_ptid_build (ret, ((union wait *) &wstat)->w_tid); find_process_pid (ret)->priv->last_wait_event_ptid = new_ptid; /* If this is a new thread, then add it now. The reason why we do this here instead of when handling new-thread events is because we need to add the thread associated to the "main" thread - even for non-threaded applications where the new-thread events are not generated. */ if (!find_thread_ptid (new_ptid)) { lynx_debug ("New thread: (pid = %d, tid = %d)", lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid)); add_thread (new_ptid, NULL); } if (WIFSTOPPED (wstat)) { status->kind = TARGET_WAITKIND_STOPPED; status->value.integer = gdb_signal_from_host (WSTOPSIG (wstat)); lynx_debug ("process stopped with signal: %d", status->value.integer); } else if (WIFEXITED (wstat)) { status->kind = TARGET_WAITKIND_EXITED; status->value.integer = WEXITSTATUS (wstat); lynx_debug ("process exited with code: %d", status->value.integer); } else if (WIFSIGNALED (wstat)) { status->kind = TARGET_WAITKIND_SIGNALLED; status->value.integer = gdb_signal_from_host (WTERMSIG (wstat)); lynx_debug ("process terminated with code: %d", status->value.integer); } else { /* Not sure what happened if we get here, or whether we can in fact get here. But if we do, handle the event the best we can. */ status->kind = TARGET_WAITKIND_STOPPED; status->value.integer = gdb_signal_from_host (0); lynx_debug ("unknown event ????"); } /* SIGTRAP events are generated for situations other than single-step/ breakpoint events (Eg. new-thread events). Handle those other types of events, and resume the execution if necessary. */ if (status->kind == TARGET_WAITKIND_STOPPED && status->value.integer == GDB_SIGNAL_TRAP) { const int realsig = lynx_ptrace (PTRACE_GETTRACESIG, new_ptid, 0, 0, 0); lynx_debug ("(realsig = %d)", realsig); switch (realsig) { case SIGNEWTHREAD: /* We just added the new thread above. No need to do anything further. Just resume the execution again. */ lynx_continue (new_ptid); goto retry; case SIGTHREADEXIT: remove_thread (find_thread_ptid (new_ptid)); lynx_continue (new_ptid); goto retry; } } return new_ptid; }
struct process_info * get_thread_process (struct thread_info *thread) { int pid = ptid_get_pid (thread->entry.id); return find_process_pid (pid); }
struct process_info * get_thread_process (const struct thread_info *thread) { return find_process_pid (thread->id.pid ()); }