static void lynx_resume (struct thread_resume *resume_info, size_t n) { ptid_t ptid = resume_info[0].thread; const int request = (resume_info[0].kind == resume_step ? (n == 1 ? PTRACE_SINGLESTEP_ONE : PTRACE_SINGLESTEP) : PTRACE_CONT); const int signal = resume_info[0].sig; /* If given a minus_one_ptid, then try using the current_process' private->last_wait_event_ptid. On most LynxOS versions, using any of the process' thread works well enough, but LynxOS 178 is a little more sensitive, and triggers some unexpected signals (Eg SIG61) when we resume the inferior using a different thread. */ if (ptid_equal (ptid, minus_one_ptid)) ptid = current_process()->priv->last_wait_event_ptid; /* The ptid might still be minus_one_ptid; this can happen between the moment we create the inferior or attach to a process, and the moment we resume its execution for the first time. It is fine to use the current_thread's ptid in those cases. */ if (ptid_equal (ptid, minus_one_ptid)) ptid = thread_to_gdb_id (current_thread); regcache_invalidate (); errno = 0; lynx_ptrace (request, ptid, 1, signal, 0); if (errno) perror_with_name ("ptrace"); }
int ptid_is_pid (ptid_t ptid) { if (ptid_equal (minus_one_ptid, ptid) || ptid_equal (null_ptid, ptid)) return 0; return (ptid_get_lwp (ptid) == 0 && ptid_get_tid (ptid) == 0); }
int ptid_lwp_p (ptid_t ptid) { if (ptid_equal (minus_one_ptid, ptid) || ptid_equal (null_ptid, ptid)) return 0; return (ptid_get_lwp (ptid) != 0); }
int ptid_match (ptid_t ptid, ptid_t filter) { if (ptid_equal (filter, minus_one_ptid)) return 1; if (ptid_is_pid (filter) && ptid_get_pid (ptid) == ptid_get_pid (filter)) return 1; else if (ptid_equal (ptid, filter)) return 1; return 0; }
static void info_mach_exceptions_command (const char *args, int from_tty) { int i; task_t task; kern_return_t kret; darwin_exception_info info; info.count = sizeof (info.ports) / sizeof (info.ports[0]); if (args != NULL) { if (strcmp (args, "saved") == 0) { if (ptid_equal (inferior_ptid, null_ptid)) printf_unfiltered (_("No inferior running\n")); darwin_inferior *priv = get_darwin_inferior (current_inferior ()); disp_exception (&priv->exception_info); return; } else if (strcmp (args, "host") == 0) { /* FIXME: This need a privilegied host port! */ kret = host_get_exception_ports (darwin_host_self, EXC_MASK_ALL, info.masks, &info.count, info.ports, info.behaviors, info.flavors); MACH_CHECK_ERROR (kret); disp_exception (&info); } else error (_("Parameter is saved, host or none")); } else { struct inferior *inf; if (ptid_equal (inferior_ptid, null_ptid)) printf_unfiltered (_("No inferior running\n")); inf = current_inferior (); darwin_inferior *priv = get_darwin_inferior (inf); kret = task_get_exception_ports (priv->task, EXC_MASK_ALL, info.masks, &info.count, info.ports, info.behaviors, info.flavors); MACH_CHECK_ERROR (kret); disp_exception (&info); } }
/* Generic prepare_to_proceed(). This one should be suitable for most targets that support threads. */ int generic_prepare_to_proceed (int select_it) { ptid_t wait_ptid; struct target_waitstatus wait_status; /* Get the last target status returned by target_wait(). */ get_last_target_status (&wait_ptid, &wait_status); /* Make sure we were stopped either at a breakpoint, or because of a Ctrl-C. */ if (wait_status.kind != TARGET_WAITKIND_STOPPED || (wait_status.value.sig != TARGET_SIGNAL_TRAP && wait_status.value.sig != TARGET_SIGNAL_INT)) { return 0; } if (!ptid_equal (wait_ptid, minus_one_ptid) && !ptid_equal (inferior_ptid, wait_ptid)) { /* Switched over from WAIT_PID. */ CORE_ADDR wait_pc = read_pc_pid (wait_ptid); if (wait_pc != read_pc ()) { if (select_it) { /* Switch back to WAIT_PID thread. */ inferior_ptid = wait_ptid; /* FIXME: This stuff came from switch_to_thread() in thread.c (which should probably be a public function). */ flush_cached_frames (); registers_changed (); stop_pc = wait_pc; select_frame (get_current_frame ()); } /* We return 1 to indicate that there is a breakpoint here, so we need to step over it before continuing to avoid hitting it straight away. */ if (breakpoint_here_p (wait_pc)) { return 1; } } } return 0; }
static void mi_cmd_var_update_iter (struct varobj *var, void *data_pointer) { struct mi_cmd_var_update *data = data_pointer; int thread_id, thread_stopped; thread_id = varobj_get_thread_id (var); if (thread_id == -1 && (ptid_equal (inferior_ptid, null_ptid) || is_stopped (inferior_ptid))) thread_stopped = 1; else { struct thread_info *tp = find_thread_id (thread_id); if (tp) thread_stopped = is_stopped (tp->ptid); else thread_stopped = 1; } if (thread_stopped && (!data->only_floating || varobj_floating_p (var))) varobj_update_one (var, data->print_values, 0 /* implicit */); }
static ptid_t find_active_thread (void) { int val; td_thread_t *thread; td_thread_info_t ti; struct ptrace_lwpinfo pl; if (!ptid_equal (cached_thread, minus_one_ptid)) return cached_thread; if (target_has_execution) { pl.pl_lwpid = 0; val = ptrace (PT_LWPINFO, ptid_get_pid(inferior_ptid), (void *)&pl, sizeof(pl)); while ((val != -1) && (pl.pl_lwpid != 0) && (pl.pl_event != PL_EVENT_SIGNAL)) { val = ptrace (PT_LWPINFO, ptid_get_pid(inferior_ptid), (void *)&pl, sizeof(pl)); } if (pl.pl_lwpid == 0) /* found no "active" thread, stay with current */ pl.pl_lwpid = inferior_ptid.lwp; } else { return inferior_ptid; } cached_thread = ptid_build (ptid_get_pid (main_ptid), pl.pl_lwpid, 0); return cached_thread; }
static void kill_command (char *arg, int from_tty) { /* FIXME: This should not really be inferior_ptid (or target_has_execution). It should be a distinct flag that indicates that a target is active, cuz some targets don't have processes! */ if (ptid_equal (inferior_ptid, null_ptid)) error ("The program is not being run."); if (!query ("Kill the program being debugged? ")) error ("Not confirmed."); target_kill (); init_thread_list (); /* Destroy thread info */ /* Killing off the inferior can leave us with a core file. If so, print the state we are left in. */ if (target_has_stack) { printf_filtered ("In %s,\n", target_longname); if (deprecated_selected_frame == NULL) fputs_filtered ("No selected stack frame.\n", gdb_stdout); else print_stack_frame (get_selected_frame (), 1, SRC_AND_LOC); } bfd_cache_close_all (); }
static void nbsd_update_thread_list (struct target_ops *ops) { int retval; ptid_t ptid; if (nbsd_thread_active == 0) return; if (ptid_equal (inferior_ptid, minus_one_ptid)) { printf_filtered ("No process.\n"); return; } if (target_has_execution) { struct ptrace_lwpinfo pl; pl.pl_lwpid = 0; retval = ptrace (PT_LWPINFO, ptid_get_pid(inferior_ptid), (void *)&pl, sizeof(pl)); while ((retval != -1) && pl.pl_lwpid != 0) { ptid = ptid_build (ptid_get_pid (main_ptid), pl.pl_lwpid, 0); if (!in_thread_list (ptid)) add_thread (ptid); retval = ptrace (PT_LWPINFO, ptid_get_pid(inferior_ptid), (void *)&pl, sizeof(pl)); } } }
thread_object * find_thread_object (ptid_t ptid) { int pid; struct threadlist_entry *thread; PyObject *inf_obj; thread_object *found = NULL; pid = ptid_get_pid (ptid); if (pid == 0) return NULL; inf_obj = find_inferior_object (pid); if (! inf_obj) return NULL; for (thread = ((inferior_object *)inf_obj)->threads; thread; thread = thread->next) if (ptid_equal (thread->thread_obj->thread->ptid, ptid)) { found = thread->thread_obj; break; } Py_DECREF (inf_obj); if (found) return found; return NULL; }
static task_t get_task_from_args (const char *args) { task_t task; char *eptr; if (args == NULL || *args == 0) { if (ptid_equal (inferior_ptid, null_ptid)) printf_unfiltered (_("No inferior running\n")); darwin_inferior *priv = get_darwin_inferior (current_inferior ()); return priv->task; } if (strcmp (args, "gdb") == 0) return mach_task_self (); task = strtoul (args, &eptr, 0); if (*eptr) { printf_unfiltered (_("cannot parse task id '%s'\n"), args); return TASK_NULL; } return task; }
static int r_debug_qnx_wait (RDebug *dbg, int pid) { ptid_t ptid = qnxr_wait (desc, pid); if (!ptid_equal (ptid, null_ptid)) { dbg->reason.signum = desc->signal; return desc->notify_type; } return 0; }
static int gdbsim_thread_alive (struct target_ops *ops, ptid_t ptid) { if (ptid_equal (ptid, remote_sim_ptid)) /* The simulators' task is always alive. */ return 1; return 0; }
static struct thread_info * record_btrace_find_resume_thread (ptid_t ptid) { struct thread_info *tp; /* When asked to resume everything, we pick the current thread. */ if (ptid_equal (minus_one_ptid, ptid) || ptid_is_pid (ptid)) ptid = inferior_ptid; return find_thread_ptid (ptid); }
static void dcache_info (char *exp, int tty) { splay_tree_node n; int i, refcount; if (exp) { char *linestart; i = strtol (exp, &linestart, 10); if (linestart == exp || i < 0) { printf_filtered (_("Usage: info dcache [linenumber]\n")); return; } dcache_print_line (i); return; } printf_filtered (_("Dcache %u lines of %u bytes each.\n"), dcache_size, last_cache ? (unsigned) last_cache->line_size : dcache_line_size); if (!last_cache || ptid_equal (last_cache->ptid, null_ptid)) { printf_filtered (_("No data cache available.\n")); return; } printf_filtered (_("Contains data for %s\n"), target_pid_to_str (last_cache->ptid)); refcount = 0; n = splay_tree_min (last_cache->tree); i = 0; while (n) { struct dcache_block *db = (struct dcache_block *) n->value; printf_filtered (_("Line %d: address %s [%d hits]\n"), i, paddress (target_gdbarch, db->addr), db->refs); i++; refcount += db->refs; n = splay_tree_successor (last_cache->tree, n->key); } printf_filtered (_("Cache state: %d active lines, %d hits\n"), i, refcount); }
const char * target_pid_to_str (ptid_t ptid) { static char buf[80]; if (ptid_equal (ptid, minus_one_ptid)) xsnprintf (buf, sizeof (buf), "<all threads>"); else if (ptid_equal (ptid, null_ptid)) xsnprintf (buf, sizeof (buf), "<null thread>"); else if (ptid_get_tid (ptid) != 0) xsnprintf (buf, sizeof (buf), "Thread %d.0x%lx", ptid_get_pid (ptid), ptid_get_tid (ptid)); else if (ptid_get_lwp (ptid) != 0) xsnprintf (buf, sizeof (buf), "LWP %d.%ld", ptid_get_pid (ptid), ptid_get_lwp (ptid)); else xsnprintf (buf, sizeof (buf), "Process %d", ptid_get_pid (ptid)); return buf; }
static ptid_t sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { ptid_t rtnval; ptid_t save_ptid; struct cleanup *old_chain; save_ptid = inferior_ptid; old_chain = save_inferior_ptid (); inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid)); if (PIDGET (inferior_ptid) == -1) inferior_ptid = procfs_first_available (); if (PIDGET (ptid) != -1) { ptid_t save_ptid = ptid; ptid = thread_to_lwp (ptid, -2); if (PIDGET (ptid) == -2) /* Inactive thread */ error ("This version of Solaris can't start inactive threads."); if (info_verbose && PIDGET (ptid) == -1) warning ("Specified thread %ld seems to have terminated", GET_THREAD (save_ptid)); } rtnval = procfs_ops.to_wait (ptid, ourstatus); if (ourstatus->kind != TARGET_WAITKIND_EXITED) { /* Map the LWP of interest back to the appropriate thread ID */ rtnval = lwp_to_thread (rtnval); if (PIDGET (rtnval) == -1) rtnval = save_ptid; /* See if we have a new thread */ if (is_thread (rtnval) && !ptid_equal (rtnval, save_ptid) && !in_thread_list (rtnval)) { printf_filtered ("[New %s]\n", target_pid_to_str (rtnval)); add_thread (rtnval); } } /* During process initialization, we may get here without the thread package being initialized, since that can only happen after we've found the shared libs. */ do_cleanups (old_chain); return rtnval; }
static int nto_set_thread (ptid_t ptid) { int res = 0; TRACE ("%s pid: %d tid: %ld\n", __func__, ptid_get_pid (ptid), ptid_get_lwp (ptid)); if (nto_inferior.ctl_fd != -1 && !ptid_equal (ptid, null_ptid) && !ptid_equal (ptid, minus_one_ptid)) { pthread_t tid = ptid_get_lwp (ptid); if (EOK == devctl (nto_inferior.ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0)) res = 1; else TRACE ("%s: Error: failed to set current thread\n", __func__); } return res; }
static void gdbsim_resume (struct target_ops *ops, ptid_t ptid, int step, enum target_signal siggnal) { if (!ptid_equal (inferior_ptid, remote_sim_ptid)) error (_("The program is not being run.")); if (remote_debug) printf_filtered ("gdbsim_resume: step %d, signal %d\n", step, siggnal); resume_siggnal = siggnal; resume_step = step; }
static char * gdbsim_pid_to_str (struct target_ops *ops, ptid_t ptid) { static char buf[64]; if (ptid_equal (remote_sim_ptid, ptid)) { xsnprintf (buf, sizeof buf, "Thread <main>"); return buf; } return normal_pid_to_str (ptid); }
struct inferior_list_entry * find_inferior_id (struct inferior_list *list, ptid_t id) { struct inferior_list_entry *inf = list->head; while (inf != NULL) { if (ptid_equal (inf->id, id)) return inf; inf = inf->next; } return NULL; }
void inferior_event_handler (enum inferior_event_type event_type, gdb_client_data client_data) { switch (event_type) { case INF_REG_EVENT: fetch_inferior_event (client_data); break; case INF_EXEC_COMPLETE: if (!non_stop) { /* Unregister the inferior from the event loop. This is done so that when the inferior is not running we don't get distracted by spurious inferior output. */ if (target_has_execution && target_can_async_p ()) target_async (0); } /* Do all continuations associated with the whole inferior (not a particular thread). */ if (!ptid_equal (inferior_ptid, null_ptid)) do_all_inferior_continuations (0); /* When running a command list (from a user command, say), these are only run when the command list is all done. */ if (interpreter_async) { check_frame_language_change (); /* Don't propagate breakpoint commands errors. Either we're stopping or some command resumes the inferior. The user will be informed. */ TRY { bpstat_do_actions (); } CATCH (e, RETURN_MASK_ALL) { exception_print (gdb_stderr, e); } END_CATCH } break; default: printf_unfiltered (_("Event type not recognized.\n")); break; }
ptid_t thread_id_to_gdb_id (ptid_t thread_id) { struct inferior_list_entry *inf = all_threads.head; while (inf != NULL) { if (ptid_equal (inf->id, thread_id)) return thread_id; inf = inf->next; } return null_ptid; }
int dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache, CORE_ADDR memaddr, gdb_byte *myaddr, int len, int should_write) { int i; int res; int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr); xfunc = should_write ? dcache_poke_byte : dcache_peek_byte; /* If this is a different inferior from what we've recorded, flush the cache. */ if (! ptid_equal (inferior_ptid, dcache->ptid)) { dcache_invalidate (dcache); dcache->ptid = inferior_ptid; } /* Do write-through first, so that if it fails, we don't write to the cache at all. */ if (should_write) { res = target_write (ops, TARGET_OBJECT_RAW_MEMORY, NULL, myaddr, memaddr, len); if (res <= 0) return res; /* Update LEN to what was actually written. */ len = res; } for (i = 0; i < len; i++) { if (!xfunc (dcache, memaddr + i, myaddr + i)) { /* That failed. Discard its cache line so we don't have a partially read line. */ dcache_invalidate_line (dcache, memaddr + i); /* If we're writing, we still wrote LEN bytes. */ if (should_write) return len; else return i; } } return len; }
static void mi_about_to_proceed (void) { /* Suppress output while calling an inferior function. */ if (!ptid_equal (inferior_ptid, null_ptid)) { struct thread_info *tp = inferior_thread (); if (tp->control.in_infcall) return; } mi_proceeded = 1; }
struct thread_info * find_thread_ptid (ptid_t ptid) { struct inferior_list_entry *inf = all_threads.head; while (inf != NULL) { struct thread_info *thread = get_thread (inf); if (ptid_equal (thread->entry.id, ptid)) return thread; inf = inf->next; } return NULL; }
static void gdbsim_create_inferior (struct target_ops *target, char *exec_file, char *args, char **env, int from_tty) { int len; char *arg_buf, **argv; if (exec_file == 0 || exec_bfd == 0) warning (_("No executable file specified.")); if (!program_loaded) warning (_("No program loaded.")); if (remote_debug) printf_filtered ("gdbsim_create_inferior: exec_file \"%s\", args \"%s\"\n", (exec_file ? exec_file : "(NULL)"), args); if (ptid_equal (inferior_ptid, remote_sim_ptid)) gdbsim_kill (target); remove_breakpoints (); init_wait_for_inferior (); if (exec_file != NULL) { len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10; arg_buf = (char *) alloca (len); arg_buf[0] = '\0'; strcat (arg_buf, exec_file); strcat (arg_buf, " "); strcat (arg_buf, args); argv = gdb_buildargv (arg_buf); make_cleanup_freeargv (argv); } else argv = NULL; sim_create_inferior (gdbsim_desc, exec_bfd, argv, env); inferior_ptid = remote_sim_ptid; add_inferior_silent (ptid_get_pid (inferior_ptid)); add_thread_silent (inferior_ptid); target_mark_running (&gdbsim_ops); insert_breakpoints (); /* Needed to get correct instruction in cache */ clear_proceed_status (); }
thread_object * find_thread_object (ptid_t ptid) { int pid; struct threadlist_entry *thread; PyObject *inf_obj; pid = PIDGET (ptid); inf_obj = find_inferior_object (pid); if (inf_obj) for (thread = ((inferior_object *)inf_obj)->threads; thread; thread = thread->next) if (ptid_equal (thread->thread_obj->thread->ptid, ptid)) return thread->thread_obj; return NULL; }
void exec_file_attach (char *filename, int from_tty) { /* Remove any previous exec file. */ exec_close (); if (!ptid_equal (inferior_ptid, null_ptid)) { target_kill (); init_thread_list (); struct program_space *ss; ALL_PSPACES (ss) { set_current_program_space (ss); breakpoint_program_space_exit (ss); } symbol_file_clear (0); }