コード例 #1
0
ファイル: target.c プロジェクト: Caleb1994/stewieos-binutils
int
set_desired_thread (int use_general)
{
  struct thread_info *found;

  if (use_general == 1)
    found = find_thread_ptid (general_thread);
  else
    found = find_thread_ptid (cont_thread);

  current_thread = found;
  return (current_thread != NULL);
}
コード例 #2
0
static void
nto_find_new_threads (struct nto_inferior *nto_inferior)
{
  pthread_t tid;

  TRACE ("%s pid:%d\n", __func__, nto_inferior->pid);

  if (nto_inferior->ctl_fd == -1)
    return;

  for (tid = 1;; ++tid)
    {
      procfs_status status;
      ptid_t ptid;
      int err;

      status.tid = tid;
      err = devctl (nto_inferior->ctl_fd, DCMD_PROC_TIDSTATUS, &status,
		    sizeof (status), 0);

      if (err != EOK || status.tid == 0)
	break;

      /* All threads in between are gone.  */
      while (tid != status.tid || status.state == STATE_DEAD)
	{
	  struct thread_info *ti;

	  ptid = ptid_build (nto_inferior->pid, tid, 0);
	  ti = find_thread_ptid (ptid);
	  if (ti != NULL)
	    {
	      TRACE ("Removing thread %d\n", tid);
	      remove_thread (ti);
	    }
	  if (tid == status.tid)
	    break;
	  ++tid;
	}

      if (status.state != STATE_DEAD)
	{
	  TRACE ("Adding thread %d\n", tid);
	  ptid = ptid_build (nto_inferior->pid, tid, 0);
	  if (!find_thread_ptid (ptid))
	    add_thread (ptid, NULL);
	}
    }
}
コード例 #3
0
void
set_desired_thread (int use_general)
{
  struct thread_info *found;

  if (use_general == 1)
    found = find_thread_ptid (general_thread);
  else
    found = find_thread_ptid (cont_thread);

  if (found == NULL)
    current_thread = get_first_thread ();
  else
    current_thread = found;
}
コード例 #4
0
ファイル: target.c プロジェクト: T-J-Teru/gdb
void
set_desired_inferior (int use_general)
{
  struct thread_info *found;

  if (use_general == 1)
    found = find_thread_ptid (general_thread);
  else
    found = find_thread_ptid (cont_thread);

  if (found == NULL)
    current_inferior = (struct thread_info *) all_threads.head;
  else
    current_inferior = found;
}
コード例 #5
0
ファイル: inferiors.c プロジェクト: ajinkya93/netbsd-src
ptid_t
gdb_id_to_thread_id (ptid_t gdb_id)
{
  struct thread_info *thread = find_thread_ptid (gdb_id);

  return thread ? thread->entry.id : null_ptid;
}
コード例 #6
0
ファイル: lynx-low.c プロジェクト: dcolascione/binutils
static int
lynx_thread_alive (ptid_t ptid)
{
  /* The list of threads is updated at the end of each wait, so it
     should be up to date.  No need to re-fetch it.  */
  return (find_thread_ptid (ptid) != NULL);
}
コード例 #7
0
ファイル: thread-db.c プロジェクト: jon-turney/binutils-gdb
bool
thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len)
{
  struct thread_db *thread_db;
  struct lwp_info *lwp;
  thread_info *thread = find_thread_ptid (ptid);

  if (thread == NULL)
    return false;

  thread_db = get_thread_process (thread)->priv->thread_db;

  if (thread_db == NULL)
    return false;

  lwp = get_thread_lwp (thread);

  if (!lwp->thread_known && !find_one_thread (thread->id))
    return false;

  gdb_assert (lwp->thread_known);

  *handle = (gdb_byte *) &lwp->thread_handle;
  *handle_len = sizeof (lwp->thread_handle);
  return true;
}
コード例 #8
0
ファイル: lynx-low.c プロジェクト: dcolascione/binutils
static void
lynx_add_threads_after_attach (int pid)
{
  /* Ugh!  There appears to be no way to get the list of threads
     in the program we just attached to.  So get the list by calling
     the "ps" command.  This is only needed now, as we will then
     keep the thread list up to date thanks to thread creation and
     exit notifications.  */
  FILE *f;
  char buf[256];
  int thread_pid, thread_tid;

  f = popen ("ps atx", "r");
  if (f == NULL)
    perror_with_name ("Cannot get thread list");

  while (fgets (buf, sizeof (buf), f) != NULL)
    if ((sscanf (buf, "%d %d", &thread_pid, &thread_tid) == 2
	 && thread_pid == pid))
    {
      ptid_t thread_ptid = lynx_ptid_build (pid, thread_tid);

      if (!find_thread_ptid (thread_ptid))
	{
	  lynx_debug ("New thread: (pid = %d, tid = %d)",
		      pid, thread_tid);
	  add_thread (thread_ptid, NULL);
	}
    }

  pclose (f);
}
コード例 #9
0
ファイル: record-btrace.c プロジェクト: embecosm/binutils-gdb
static int
record_btrace_tailcall_frame_sniffer (const struct frame_unwind *self,
				      struct frame_info *this_frame,
				      void **this_cache)
{
  const struct btrace_function *bfun, *callee;
  struct btrace_frame_cache *cache;
  struct frame_info *next;

  next = get_next_frame (this_frame);
  if (next == NULL)
    return 0;

  callee = btrace_get_frame_function (next);
  if (callee == NULL)
    return 0;

  if ((callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
    return 0;

  bfun = callee->up;
  if (bfun == NULL)
    return 0;

  DEBUG ("[frame] sniffed tailcall frame for %s on level %d",
	 btrace_get_bfun_name (bfun), bfun->level);

  /* This is our frame.  Initialize the frame cache.  */
  cache = bfcache_new (this_frame);
  cache->tp = find_thread_ptid (inferior_ptid);
  cache->bfun = bfun;

  *this_cache = cache;
  return 1;
}
コード例 #10
0
ファイル: target.c プロジェクト: Caleb1994/stewieos-binutils
void
done_accessing_memory (void)
{
  if (the_target->done_accessing_memory != NULL)
    the_target->done_accessing_memory ();

  /* Restore the previous selected thread.  */
  general_thread = prev_general_thread;
  current_thread = find_thread_ptid (general_thread);
}
コード例 #11
0
ファイル: record-btrace.c プロジェクト: embecosm/binutils-gdb
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);
}
コード例 #12
0
ファイル: linux-thread-db.c プロジェクト: bjori/gdb
static int
thread_get_info_callback (const td_thrhandle_t *thp, void *argp)
{
  td_thrinfo_t ti;
  td_err_e err;
  ptid_t thread_ptid;
  struct thread_get_info_inout *inout;
  struct thread_db_info *info;

  inout = argp;
  info = inout->thread_db_info;

  err = info->td_thr_get_info_p (thp, &ti);
  if (err != TD_OK)
    error (_("thread_get_info_callback: cannot get thread info: %s"),
	   thread_db_err_str (err));

  /* Fill the cache.  */
  thread_ptid = ptid_build (info->pid, ti.ti_lid, 0);
  inout->thread_info = find_thread_ptid (thread_ptid);

  /* In the case of a zombie thread, don't continue.  We don't want to
     attach to it thinking it is a new thread.  */
  if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
    return TD_THR_ZOMBIE;

  if (inout->thread_info == NULL)
    {
      /* New thread.  Attach to it now (why wait?).  */
      if (!have_threads (thread_ptid))
 	thread_db_find_new_threads_1 (thread_ptid);
      else
	attach_thread (thread_ptid, thp, &ti);
      inout->thread_info = find_thread_ptid (thread_ptid);
      gdb_assert (inout->thread_info != NULL);
    }

  return 0;
}
コード例 #13
0
gdbpy_ref<>
py_get_event_thread (ptid_t ptid)
{
  if (non_stop)
    {
      thread_info *thread = find_thread_ptid (ptid);
      if (thread != nullptr)
	return thread_to_thread_object (thread);
      PyErr_SetString (PyExc_RuntimeError, "Could not find event thread");
      return NULL;
    }
  return gdbpy_ref<>::new_reference (Py_None);
}
コード例 #14
0
ファイル: record-btrace.c プロジェクト: embecosm/binutils-gdb
static int
record_btrace_thread_alive (struct target_ops *ops, ptid_t ptid)
{
  /* We don't add or remove threads during replay.  */
  if (record_btrace_is_replaying (ops))
    return find_thread_ptid (ptid) != NULL;

  /* Forward the request.  */
  for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
    if (ops->to_thread_alive != NULL)
      return ops->to_thread_alive (ops, ptid);

  return 0;
}
コード例 #15
0
ファイル: thread-db.c プロジェクト: jon-turney/binutils-gdb
static int
find_one_thread (ptid_t ptid)
{
  td_thrhandle_t th;
  td_thrinfo_t ti;
  td_err_e err;
  struct lwp_info *lwp;
  struct thread_db *thread_db = current_process ()->priv->thread_db;
  int lwpid = ptid.lwp ();

  thread_info *thread = find_thread_ptid (ptid);
  lwp = get_thread_lwp (thread);
  if (lwp->thread_known)
    return 1;

  /* Get information about this thread.  */
  err = thread_db->td_ta_map_lwp2thr_p (thread_db->thread_agent, lwpid, &th);
  if (err != TD_OK)
    error ("Cannot get thread handle for LWP %d: %s",
	   lwpid, thread_db_err_str (err));

  err = thread_db->td_thr_get_info_p (&th, &ti);
  if (err != TD_OK)
    error ("Cannot get thread info for LWP %d: %s",
	   lwpid, thread_db_err_str (err));

  if (debug_threads)
    debug_printf ("Found thread %ld (LWP %d)\n",
		  (unsigned long) ti.ti_tid, ti.ti_lid);

  if (lwpid != ti.ti_lid)
    {
      warning ("PID mismatch!  Expected %ld, got %ld",
	       (long) lwpid, (long) ti.ti_lid);
      return 0;
    }

  /* If the new thread ID is zero, a final thread ID will be available
     later.  Do not enable thread debugging yet.  */
  if (ti.ti_tid == 0)
    return 0;

  lwp->thread_known = 1;
  lwp->th = th;
  lwp->thread_handle = ti.ti_tid;

  return 1;
}
コード例 #16
0
ファイル: record-btrace.c プロジェクト: embecosm/binutils-gdb
static int
record_btrace_frame_sniffer (const struct frame_unwind *self,
			     struct frame_info *this_frame,
			     void **this_cache)
{
  const struct btrace_function *bfun;
  struct btrace_frame_cache *cache;
  struct thread_info *tp;
  struct frame_info *next;

  /* THIS_FRAME does not contain a reference to its thread.  */
  tp = find_thread_ptid (inferior_ptid);
  gdb_assert (tp != NULL);

  bfun = NULL;
  next = get_next_frame (this_frame);
  if (next == NULL)
    {
      const struct btrace_insn_iterator *replay;

      replay = tp->btrace.replay;
      if (replay != NULL)
	bfun = replay->function;
    }
  else
    {
      const struct btrace_function *callee;

      callee = btrace_get_frame_function (next);
      if (callee != NULL && (callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
	bfun = callee->up;
    }

  if (bfun == NULL)
    return 0;

  DEBUG ("[frame] sniffed frame for %s on level %d",
	 btrace_get_bfun_name (bfun), bfun->level);

  /* This is our frame.  Initialize the frame cache.  */
  cache = bfcache_new (this_frame);
  cache->tp = tp;
  cache->bfun = bfun;

  *this_cache = cache;
  return 1;
}
コード例 #17
0
ファイル: record-btrace.c プロジェクト: embecosm/binutils-gdb
static struct thread_info *
record_btrace_find_thread_to_move (ptid_t ptid)
{
  struct thread_info *tp;

  /* First check the parameter thread.  */
  tp = find_thread_ptid (ptid);
  if (tp != NULL && (tp->btrace.flags & BTHR_MOVE) != 0)
    return tp;

  /* Otherwise, find one other thread that has been resumed.  */
  ALL_THREADS (tp)
    if ((tp->btrace.flags & BTHR_MOVE) != 0)
      return tp;

  return NULL;
}
コード例 #18
0
ファイル: record-btrace.c プロジェクト: embecosm/binutils-gdb
static struct thread_info *
require_btrace_thread (void)
{
  struct thread_info *tp;

  DEBUG ("require");

  tp = find_thread_ptid (inferior_ptid);
  if (tp == NULL)
    error (_("No thread."));

  btrace_fetch (tp);

  if (btrace_is_empty (tp))
    error (_("No trace."));

  return tp;
}
コード例 #19
0
ファイル: record-btrace.c プロジェクト: embecosm/binutils-gdb
static void
record_btrace_fetch_registers (struct target_ops *ops,
			       struct regcache *regcache, int regno)
{
  struct btrace_insn_iterator *replay;
  struct thread_info *tp;

  tp = find_thread_ptid (inferior_ptid);
  gdb_assert (tp != NULL);

  replay = tp->btrace.replay;
  if (replay != NULL)
    {
      const struct btrace_insn *insn;
      struct gdbarch *gdbarch;
      int pcreg;

      gdbarch = get_regcache_arch (regcache);
      pcreg = gdbarch_pc_regnum (gdbarch);
      if (pcreg < 0)
	return;

      /* We can only provide the PC register.  */
      if (regno >= 0 && regno != pcreg)
	return;

      insn = btrace_insn_get (replay);
      gdb_assert (insn != NULL);

      regcache_raw_supply (regcache, regno, &insn->pc);
    }
  else
    {
      struct target_ops *t;

      for (t = ops->beneath; t != NULL; t = t->beneath)
	if (t->to_fetch_registers != NULL)
	  {
	    t->to_fetch_registers (t, regcache, regno);
	    break;
	  }
    }
}
コード例 #20
0
ファイル: record-btrace.c プロジェクト: embecosm/binutils-gdb
static void
record_btrace_info (struct target_ops *self)
{
  struct btrace_thread_info *btinfo;
  struct thread_info *tp;
  unsigned int insns, calls;

  DEBUG ("info");

  tp = find_thread_ptid (inferior_ptid);
  if (tp == NULL)
    error (_("No thread."));

  btrace_fetch (tp);

  insns = 0;
  calls = 0;

  btinfo = &tp->btrace;

  if (!btrace_is_empty (tp))
    {
      struct btrace_call_iterator call;
      struct btrace_insn_iterator insn;

      btrace_call_end (&call, btinfo);
      btrace_call_prev (&call, 1);
      calls = btrace_call_number (&call);

      btrace_insn_end (&insn, btinfo);
      btrace_insn_prev (&insn, 1);
      insns = btrace_insn_number (&insn);
    }

  printf_unfiltered (_("Recorded %u instructions in %u functions for thread "
		       "%d (%s).\n"), insns, calls, tp->num,
		     target_pid_to_str (tp->ptid));

  if (btrace_is_replaying (tp))
    printf_unfiltered (_("Replay in progress.  At instruction %u.\n"),
		       btrace_insn_number (btinfo->replay));
}
コード例 #21
0
ファイル: py-inferior.c プロジェクト: Drakey83/steamlink-sdk
static void
python_on_normal_stop (struct bpstats *bs, int print_frame)
{
  struct cleanup *cleanup;
  enum gdb_signal stop_signal;

  if (!gdb_python_initialized)
    return;

  if (!find_thread_ptid (inferior_ptid))
      return;

  stop_signal = inferior_thread ()->suspend.stop_signal;

  cleanup = ensure_python_env (get_current_arch (), current_language);

  if (emit_stop_event (bs, stop_signal) < 0)
    gdbpy_print_stack ();

  do_cleanups (cleanup);
}
コード例 #22
0
ファイル: record-btrace.c プロジェクト: 5kg/gdb
static struct btrace_thread_info *
require_btrace (void)
{
  struct thread_info *tp;
  struct btrace_thread_info *btinfo;

  DEBUG ("require");

  tp = find_thread_ptid (inferior_ptid);
  if (tp == NULL)
    error (_("No thread."));

  btrace_fetch (tp);

  btinfo = &tp->btrace;

  if (VEC_empty (btrace_inst_s, btinfo->itrace))
    error (_("No trace."));

  return btinfo;
}
コード例 #23
0
ファイル: record-btrace.c プロジェクト: 5kg/gdb
static void
record_btrace_info (void)
{
  struct btrace_thread_info *btinfo;
  struct thread_info *tp;
  unsigned int insts, funcs;

  DEBUG ("info");

  tp = find_thread_ptid (inferior_ptid);
  if (tp == NULL)
    error (_("No thread."));

  btrace_fetch (tp);

  btinfo = &tp->btrace;
  insts = VEC_length (btrace_inst_s, btinfo->itrace);
  funcs = VEC_length (btrace_func_s, btinfo->ftrace);

  printf_unfiltered (_("Recorded %u instructions in %u functions for thread "
		       "%d (%s).\n"), insts, funcs, tp->num,
		     target_pid_to_str (tp->ptid));
}
コード例 #24
0
ファイル: regcache.c プロジェクト: ajinkya93/netbsd-src
struct regcache *
get_thread_regcache_for_ptid (ptid_t ptid)
{
  return get_thread_regcache (find_thread_ptid (ptid), 1);
}
コード例 #25
0
ファイル: mi-interp.c プロジェクト: ajinkya93/netbsd-src
static void
mi_on_resume (ptid_t ptid)
{
  struct thread_info *tp = NULL;

  if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
    tp = inferior_thread ();
  else
    tp = find_thread_ptid (ptid);

  /* Suppress output while calling an inferior function.  */
  if (tp->control.in_infcall)
    return;

  /* To cater for older frontends, emit ^running, but do it only once
     per each command.  We do it here, since at this point we know
     that the target was successfully resumed, and in non-async mode,
     we won't return back to MI interpreter code until the target
     is done running, so delaying the output of "^running" until then
     will make it impossible for frontend to know what's going on.

     In future (MI3), we'll be outputting "^done" here.  */
  if (!running_result_record_printed && mi_proceeded)
    {
      fprintf_unfiltered (raw_stdout, "%s^running\n",
			  current_token ? current_token : "");
    }

  if (ptid_get_pid (ptid) == -1)
    fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n");
  else if (ptid_is_pid (ptid))
    {
      int count = 0;

      /* Backwards compatibility.  If there's only one inferior,
	 output "all", otherwise, output each resumed thread
	 individually.  */
      iterate_over_inferiors (mi_inferior_count, &count);

      if (count == 1)
	fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n");
      else
	iterate_over_threads (mi_output_running_pid, &ptid);
    }
  else
    {
      struct thread_info *ti = find_thread_ptid (ptid);

      gdb_assert (ti);
      fprintf_unfiltered (raw_stdout, "*running,thread-id=\"%d\"\n", ti->num);
    }

  if (!running_result_record_printed && mi_proceeded)
    {
      running_result_record_printed = 1;
      /* This is what gdb used to do historically -- printing prompt even if
	 it cannot actually accept any input.  This will be surely removed
	 for MI3, and may be removed even earlier.  SYNC_EXECUTION is
	 checked here because we only need to emit a prompt if a
	 synchronous command was issued when the target is async.  */
      if (!target_is_async_p () || sync_execution)
	fputs_unfiltered ("(gdb) \n", raw_stdout);
    }
  gdb_flush (raw_stdout);
}
コード例 #26
0
ファイル: inferiors.c プロジェクト: T-J-Teru/binutils-gdb
void
switch_to_thread (ptid_t ptid)
{
  gdb_assert (ptid != minus_one_ptid);
  current_thread = find_thread_ptid (ptid);
}
コード例 #27
0
ファイル: infcall.c プロジェクト: ArmstrongJ/insight-debugger
    {
      proceed (real_pc, TARGET_SIGNAL_0, 0);

      /* Inferior function calls are always synchronous, even if the
	 target supports asynchronous execution.  Do here what
	 `proceed' itself does in sync mode.  */
      if (target_can_async_p () && is_running (inferior_ptid))
	{
	  wait_for_inferior ();
	  normal_stop ();
	}
    }

  /* At this point the current thread may have changed.  Refresh
     CALL_THREAD as it could be invalid if its thread has exited.  */
  call_thread = find_thread_ptid (call_thread_ptid);

  enable_watchpoints_after_interactive_call_stop ();

  /* Call breakpoint_auto_delete on the current contents of the bpstat
     of inferior call thread.
     If all error()s out of proceed ended up calling normal_stop
     (and perhaps they should; it already does in the special case
     of error out of resume()), then we wouldn't need this.  */
  if (e.reason < 0)
    {
      if (call_thread != NULL)
	breakpoint_auto_delete (call_thread->control.stop_bpstat);
    }

  if (call_thread != NULL)
コード例 #28
0
ファイル: lynx-low.c プロジェクト: dcolascione/binutils
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;
}