Esempio n. 1
0
static void
attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
               const td_thrinfo_t *ti_p, int verbose)
{
  td_err_e err;

  /* Add the thread to GDB's thread list.  */
  if (!in_thread_list (ptid)) {
    add_thread (ptid);
    if (verbose)
      printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid));
  }

  if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE)
    return;                     /* A zombie thread -- do not attach.  */

  if (! IS_THREAD(ptid))
    return;
  if (fbsd_thread_core != 0)
    return;
  /* Enable thread event reporting for this thread. */
  err = td_thr_event_enable_p (th_p, 1);
  if (err != TD_OK)
    error ("Cannot enable thread event reporting for %s: %s",
           target_pid_to_str (ptid), thread_db_err_str (err));
}
Esempio n. 2
0
static void
inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty)
{
  char *exec_file;
  pid_t pid;
  struct inferior *inf;

  /* Do not change either targets above or the same target if already present.
     The reason is the target stack is shared across multiple inferiors.  */
  int ops_already_pushed = target_is_pushed (ops);
  struct cleanup *back_to = NULL;

  pid = parse_pid_to_attach (args);

  if (pid == getpid ())		/* Trying to m********e?  */
    error (_("I refuse to debug myself!"));

  if (! ops_already_pushed)
    {
      /* target_pid_to_str already uses the target.  Also clear possible core
	 file with its process_stratum.  */
      push_target (ops);
      back_to = make_cleanup_unpush_target (ops);
    }

  if (from_tty)
    {
      exec_file = get_exec_file (0);

      if (exec_file)
	printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
			   target_pid_to_str (pid_to_ptid (pid)));
      else
	printf_unfiltered (_("Attaching to %s\n"),
			   target_pid_to_str (pid_to_ptid (pid)));

      gdb_flush (gdb_stdout);
    }

#ifdef PT_ATTACH
  errno = 0;
  ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
  if (errno != 0)
    perror_with_name (("ptrace"));
#else
  error (_("This system does not support attaching to a process"));
#endif

  inf = current_inferior ();
  inferior_appeared (inf, pid);
  inf->attach_flag = 1;
  inferior_ptid = pid_to_ptid (pid);

  /* Always add a main thread.  If some target extends the ptrace
     target, it should decorate the ptid later with more info.  */
  add_thread_silent (inferior_ptid);

  if (! ops_already_pushed)
    discard_cleanups (back_to);
}
Esempio n. 3
0
static void
child_detach_from_process (int pid, char *args, int from_tty, int after_fork)
{
#ifdef ATTACH_DETACH
  {
    int siggnal = 0;

    if (from_tty)
      {
	char *exec_file = get_exec_file (0);
	if (exec_file == 0)
	  exec_file = "";
	if (after_fork)
	  printf_unfiltered ("Detaching after fork from %s\n",
			     target_pid_to_str (pid_to_ptid (pid)));
	else
	  printf_unfiltered ("Detaching from program: %s, %s\n", exec_file,
			     target_pid_to_str (pid_to_ptid (pid)));
	gdb_flush (gdb_stdout);
      }
    if (args)
      siggnal = atoi (args);

    if (!after_fork)
      detach (siggnal);
    else
      REQUIRE_DETACH (pid, siggnal);
  }
#else
  error ("This version of Unix does not support detaching a process.");
#endif
}
static void
inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty)
{
  char *exec_file;
  pid_t pid;
  char *dummy;
  struct inferior *inf;

  if (!args)
    error_no_arg (_("process-id to attach"));

  dummy = args;
  pid = strtol (args, &dummy, 0);
  /* Some targets don't set errno on errors, grrr!  */
  if (pid == 0 && args == dummy)
    error (_("Illegal process-id: %s."), args);

  if (pid == getpid ())		/* Trying to m********e?  */
    error (_("I refuse to debug myself!"));

  if (from_tty)
    {
      exec_file = get_exec_file (0);

      if (exec_file)
	printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
			   target_pid_to_str (pid_to_ptid (pid)));
      else
	printf_unfiltered (_("Attaching to %s\n"),
			   target_pid_to_str (pid_to_ptid (pid)));

      gdb_flush (gdb_stdout);
    }

#ifdef PT_ATTACH
  errno = 0;
  ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
  if (errno != 0)
    perror_with_name (("ptrace"));
#else
  error (_("This system does not support attaching to a process"));
#endif

  inferior_ptid = pid_to_ptid (pid);

  inf = add_inferior (pid);
  inf->attach_flag = 1;

  /* Always add a main thread.  If some target extends the ptrace
     target, it should decorate the ptid later with more info.  */
  add_thread_silent (inferior_ptid);

  push_target(ops);
}
Esempio n. 5
0
static void
child_attach_to_process (char *args, int from_tty, int after_fork)
{
  if (!args)
    error_no_arg ("process-id to attach");

#ifndef ATTACH_DETACH
  error ("Can't attach to a process on this machine.");
#else
  {
    char *exec_file;
    int pid;
    char *dummy;

    dummy = args;
    pid = strtol (args, &dummy, 0);
    /* Some targets don't set errno on errors, grrr! */
    if ((pid == 0) && (args == dummy))
      error ("Illegal process-id: %s\n", args);

    if (pid == getpid ())	/* Trying to m********e? */
      error ("I refuse to debug myself!");

    if (from_tty)
      {
	exec_file = (char *) get_exec_file (0);

	if (after_fork)
	  printf_unfiltered ("Attaching after fork to %s\n",
			     target_pid_to_str (pid_to_ptid (pid)));
	else if (exec_file)
	  printf_unfiltered ("Attaching to program: %s, %s\n", exec_file,
			     target_pid_to_str (pid_to_ptid (pid)));
	else
	  printf_unfiltered ("Attaching to %s\n", 
	                     target_pid_to_str (pid_to_ptid (pid)));

	gdb_flush (gdb_stdout);
      }

    if (!after_fork)
      attach (pid);
    else
      REQUIRE_ATTACH (pid);

    inferior_ptid = pid_to_ptid (pid);
    push_target (&child_ops);
  }
#endif /* ATTACH_DETACH */
}
Esempio n. 6
0
static void
inf_ptrace_attach (char *args, int from_tty)
{
  char *exec_file;
  pid_t pid;
  char *dummy;

  if (!args)
    error_no_arg (_("process-id to attach"));

  dummy = args;
  pid = strtol (args, &dummy, 0);
  /* Some targets don't set errno on errors, grrr!  */
  if (pid == 0 && args == dummy)
    error (_("Illegal process-id: %s."), args);

  if (pid == getpid ())		/* Trying to m********e?  */
    error (_("I refuse to debug myself!"));

  if (from_tty)
    {
      exec_file = get_exec_file (0);

      if (exec_file)
	printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
			   target_pid_to_str (pid_to_ptid (pid)));
      else
	printf_unfiltered (_("Attaching to %s\n"),
			   target_pid_to_str (pid_to_ptid (pid)));

      gdb_flush (gdb_stdout);
    }

#ifdef PT_ATTACH
  errno = 0;
  ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
  if (errno != 0)
    perror_with_name (("ptrace"));
  attach_flag = 1;
#else
  error (_("This system does not support attaching to a process"));
#endif

  inferior_ptid = pid_to_ptid (pid);
  push_target (ptrace_ops_hack);

  /* Do this first, before anything has had a chance to query the
     inferior's symbol table or similar.  */
  observer_notify_inferior_created (&current_target, from_tty);
}
Esempio n. 7
0
void
btrace_clear (struct thread_info *tp)
{
  struct btrace_thread_info *btinfo;
  struct btrace_function *it, *trash;

  DEBUG ("clear thread %d (%s)", tp->num, target_pid_to_str (tp->ptid));

  /* Make sure btrace frames that may hold a pointer into the branch
     trace data are destroyed.  */
  reinit_frame_cache ();

  btinfo = &tp->btrace;

  it = btinfo->begin;
  while (it != NULL)
    {
      trash = it;
      it = it->flow.next;

      xfree (trash);
    }

  btinfo->begin = NULL;
  btinfo->end = NULL;
  btinfo->ngaps = 0;

  btrace_clear_history (btinfo);
}
Esempio n. 8
0
static void
inf_ptrace_detach (char *args, int from_tty)
{
  pid_t pid = ptid_get_pid (inferior_ptid);
  int sig = 0;

  if (from_tty)
    {
      char *exec_file = get_exec_file (0);
      if (exec_file == 0)
	exec_file = "";
      printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
			 target_pid_to_str (pid_to_ptid (pid)));
      gdb_flush (gdb_stdout);
    }
  if (args)
    sig = atoi (args);

#ifdef PT_DETACH
  /* We'd better not have left any breakpoints in the program or it'll
     die when it hits one.  Alsno note that this may only work if we
     previously attached to the inferior.  It *might* work if we
     started the process ourselves.  */
  errno = 0;
  ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, sig);
  if (errno != 0)
    perror_with_name (("ptrace"));
  attach_flag = 0;
#else
  error (_("This system does not support detaching from a process"));
#endif

  inferior_ptid = null_ptid;
  unpush_target (ptrace_ops_hack);
}
Esempio n. 9
0
static void
inf_ptrace_files_info (struct target_ops *ignore)
{
  printf_filtered (_("\tUsing the running image of %s %s.\n"),
		   attach_flag ? "attached" : "child",
		   target_pid_to_str (inferior_ptid));
}
Esempio n. 10
0
void
inf_ptrace_target::files_info ()
{
  struct inferior *inf = current_inferior ();

  printf_filtered (_("\tUsing the running image of %s %s.\n"),
		   inf->attach_flag ? "attached" : "child",
		   target_pid_to_str (inferior_ptid));
}
Esempio n. 11
0
/* Fetch register REGNO, or all regs if REGNO is -1.  */
static void
gnu_fetch_registers (struct target_ops *ops,
		     struct regcache *regcache, int regno)
{
  struct proc *thread;

  /* Make sure we know about new threads.  */
  inf_update_procs (gnu_current_inf);

  thread = inf_tid_to_thread (gnu_current_inf,
			      ptid_get_tid (inferior_ptid));
  if (!thread)
    error (_("Can't fetch registers from thread %s: No such thread"),
	   target_pid_to_str (inferior_ptid));

  if (regno < I386_NUM_GREGS || regno == -1)
    {
      thread_state_t state;

      /* This does the dirty work for us.  */
      state = proc_get_state (thread, 0);
      if (!state)
	{
	  warning (_("Couldn't fetch registers from %s"),
		   proc_string (thread));
	  return;
	}

      if (regno == -1)
	{
	  int i;

	  proc_debug (thread, "fetching all register");

	  for (i = 0; i < I386_NUM_GREGS; i++)
	    regcache_raw_supply (regcache, i, REG_ADDR (state, i));
	  thread->fetched_regs = ~0;
	}
      else
	{
	  proc_debug (thread, "fetching register %s",
		      gdbarch_register_name (get_regcache_arch (regcache),
					     regno));

	  regcache_raw_supply (regcache, regno,
			       REG_ADDR (state, regno));
	  thread->fetched_regs |= (1 << regno);
	}
    }

  if (regno >= I386_NUM_GREGS || regno == -1)
    {
      proc_debug (thread, "fetching floating-point registers");

      fetch_fpregs (regcache, thread);
    }
}
Esempio n. 12
0
static ptid_t
record_btrace_wait (struct target_ops *ops, ptid_t ptid,
		    struct target_waitstatus *status, int options)
{
  struct thread_info *tp, *other;

  DEBUG ("wait %s (0x%x)", target_pid_to_str (ptid), options);

  /* As long as we're not replaying, just forward the request.  */
  if (!record_btrace_is_replaying (ops) && execution_direction != EXEC_REVERSE)
    {
      for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
	if (ops->to_wait != NULL)
	  return ops->to_wait (ops, ptid, status, options);

      error (_("Cannot find target for waiting."));
    }

  /* Let's find a thread to move.  */
  tp = record_btrace_find_thread_to_move (ptid);
  if (tp == NULL)
    {
      DEBUG ("wait %s: no thread", target_pid_to_str (ptid));

      status->kind = TARGET_WAITKIND_IGNORE;
      return minus_one_ptid;
    }

  /* We only move a single thread.  We're not able to correlate threads.  */
  *status = record_btrace_step_thread (tp);

  /* Stop all other threads. */
  if (!non_stop)
    ALL_THREADS (other)
      other->btrace.flags &= ~BTHR_MOVE;

  /* Start record histories anew from the current position.  */
  record_btrace_clear_histories (&tp->btrace);

  /* We moved the replay position but did not update registers.  */
  registers_changed_ptid (tp->ptid);

  return tp->ptid;
}
Esempio n. 13
0
static void
child_attach (char *args, int from_tty)
{
  char *exec_file;
  int pid;
  char *dummy;

  if (!args)
    error_no_arg (_("process-id to attach"));

  dummy = args;
  pid = strtol (args, &dummy, 0);
  /* Some targets don't set errno on errors, grrr! */
  if ((pid == 0) && (args == dummy))
      error (_("Illegal process-id: %s."), args);
  
  if (pid == getpid ())	/* Trying to m********e? */
    error (_("I refuse to debug myself!"));
  
  if (from_tty)
    {
      exec_file = (char *) get_exec_file (0);
      
      if (exec_file)
	printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
			   target_pid_to_str (pid_to_ptid (pid)));
      else
	printf_unfiltered (_("Attaching to %s\n"),
			   target_pid_to_str (pid_to_ptid (pid)));
      
      gdb_flush (gdb_stdout);
    }

  attach (pid);
  
  inferior_ptid = pid_to_ptid (pid);
  push_target (&deprecated_child_ops);

  /* Do this first, before anything has had a chance to query the
     inferior's symbol table or similar.  */
  observer_notify_inferior_created (&current_target, from_tty);
}
Esempio n. 14
0
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);
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
struct address_space *
process_stratum_target::thread_address_space (ptid_t ptid)
{
  /* Fall-back to the "main" address space of the inferior.  */
  inferior *inf = find_inferior_ptid (ptid);

  if (inf == NULL || inf->aspace == NULL)
    internal_error (__FILE__, __LINE__,
		    _("Can't determine the current "
		      "address space of thread %s\n"),
		    target_pid_to_str (ptid).c_str ());

  return inf->aspace;
}
Esempio n. 17
0
struct btrace_target_info *
x86_linux_nat_target::enable_btrace (ptid_t ptid,
				     const struct btrace_config *conf)
{
  struct btrace_target_info *tinfo = nullptr;
  TRY
    {
      tinfo = linux_enable_btrace (ptid, conf);
    }
  CATCH (exception, RETURN_MASK_ERROR)
    {
      error (_("Could not enable branch tracing for %s: %s"),
	     target_pid_to_str (ptid), exception.message);
    }
Esempio n. 18
0
static struct btrace_target_info *
x86_linux_enable_btrace (struct target_ops *self, ptid_t ptid,
                         const struct btrace_config *conf)
{
    struct btrace_target_info *tinfo;

    errno = 0;
    tinfo = linux_enable_btrace (ptid, conf);

    if (tinfo == NULL)
        error (_("Could not enable branch tracing for %s: %s."),
               target_pid_to_str (ptid), safe_strerror (errno));

    return tinfo;
}
Esempio n. 19
0
void
btrace_teardown (struct thread_info *tp)
{
  struct btrace_thread_info *btp = &tp->btrace;
  int errcode = 0;

  if (btp->target == NULL)
    return;

  DEBUG ("teardown thread %d (%s)", tp->num, target_pid_to_str (tp->ptid));

  target_teardown_btrace (btp->target);
  btp->target = NULL;

  btrace_clear (tp);
}
Esempio n. 20
0
static void
record_btrace_resume_thread (struct thread_info *tp,
			     enum btrace_thread_flag flag)
{
  struct btrace_thread_info *btinfo;

  DEBUG ("resuming %d (%s): %u", tp->num, target_pid_to_str (tp->ptid), flag);

  btinfo = &tp->btrace;

  if ((btinfo->flags & BTHR_MOVE) != 0)
    error (_("Thread already moving."));

  /* Fetch the latest branch trace.  */
  btrace_fetch (tp);

  btinfo->flags |= flag;
}
Esempio n. 21
0
void
btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
{
  if (tp->btrace.target != NULL)
    return;

  if (!target_supports_btrace (conf->format))
    error (_("Target does not support branch tracing."));

  DEBUG ("enable thread %d (%s)", tp->num, target_pid_to_str (tp->ptid));

  tp->btrace.target = target_enable_btrace (tp->ptid, conf);

  /* Add an entry for the current PC so we start tracing from where we
     enabled it.  */
  if (tp->btrace.target != NULL)
    btrace_add_pc (tp);
}
Esempio n. 22
0
static void
record_btrace_resume (struct target_ops *ops, ptid_t ptid, int step,
		      enum gdb_signal signal)
{
  struct thread_info *tp, *other;
  enum btrace_thread_flag flag;

  DEBUG ("resume %s: %s", target_pid_to_str (ptid), step ? "step" : "cont");

  tp = record_btrace_find_resume_thread (ptid);
  if (tp == NULL)
    error (_("Cannot find thread to resume."));

  /* Stop replaying other threads if the thread to resume is not replaying.  */
  if (!btrace_is_replaying (tp) && execution_direction != EXEC_REVERSE)
    ALL_THREADS (other)
      record_btrace_stop_replaying (other);

  /* As long as we're not replaying, just forward the request.  */
  if (!record_btrace_is_replaying (ops) && execution_direction != EXEC_REVERSE)
    {
      for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
	if (ops->to_resume != NULL)
	  return ops->to_resume (ops, ptid, step, signal);

      error (_("Cannot find target for stepping."));
    }

  /* Compute the btrace thread flag for the requested move.  */
  if (step == 0)
    flag = execution_direction == EXEC_REVERSE ? BTHR_RCONT : BTHR_CONT;
  else
    flag = execution_direction == EXEC_REVERSE ? BTHR_RSTEP : BTHR_STEP;

  /* At the moment, we only move a single thread.  We could also move
     all threads in parallel by single-stepping each resumed thread
     until the first runs into an event.
     When we do that, we would want to continue all other threads.
     For now, just resume one thread to not confuse to_wait.  */
  record_btrace_resume_thread (tp, flag);

  /* We just indicate the resume intent here.  The actual stepping happens in
     record_btrace_wait below.  */
}
Esempio n. 23
0
static struct btrace_target_info *
amd64_linux_enable_btrace (struct target_ops *self, ptid_t ptid)
{
  struct btrace_target_info *tinfo;
  struct gdbarch *gdbarch;

  errno = 0;
  tinfo = linux_enable_btrace (ptid);

  if (tinfo == NULL)
    error (_("Could not enable branch tracing for %s: %s."),
	   target_pid_to_str (ptid), safe_strerror (errno));

  /* Fill in the size of a pointer in bits.  */
  gdbarch = target_thread_architecture (ptid);
  tinfo->ptr_bits = gdbarch_ptr_bit (gdbarch);

  return tinfo;
}
Esempio n. 24
0
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));
}
Esempio n. 25
0
static void
child_detach (char *args, int from_tty)
{
  int siggnal = 0;
  int pid = PIDGET (inferior_ptid);
  
  if (from_tty)
    {
      char *exec_file = get_exec_file (0);
      if (exec_file == 0)
	exec_file = "";
      printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
			 target_pid_to_str (pid_to_ptid (pid)));
      gdb_flush (gdb_stdout);
    }
  if (args)
    siggnal = atoi (args);
  
  detach (siggnal);
  
  inferior_ptid = null_ptid;
  unpush_target (&deprecated_child_ops);
}
Esempio n. 26
0
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));
}
Esempio n. 27
0
static void
detach_thread (ptid_t ptid, int verbose)
{
  if (verbose)
    printf_unfiltered ("[%s exited]\n", target_pid_to_str (ptid));
}
Esempio n. 28
0
/* Store at least register REGNO, or all regs if REGNO == -1.  */
static void
gnu_store_registers (struct target_ops *ops,
		     struct regcache *regcache, int regno)
{
  struct proc *thread;
  struct gdbarch *gdbarch = get_regcache_arch (regcache);

  /* Make sure we know about new threads.  */
  inf_update_procs (gnu_current_inf);

  thread = inf_tid_to_thread (gnu_current_inf,
			      ptid_get_tid (inferior_ptid));
  if (!thread)
    error (_("Couldn't store registers into thread %s: No such thread"),
	   target_pid_to_str (inferior_ptid));

  if (regno < I386_NUM_GREGS || regno == -1)
    {
      thread_state_t state;
      thread_state_data_t old_state;
      int was_aborted = thread->aborted;
      int was_valid = thread->state_valid;
      int trace;

      if (!was_aborted && was_valid)
	memcpy (&old_state, &thread->state, sizeof (old_state));

      state = proc_get_state (thread, 1);
      if (!state)
	{
	  warning (_("Couldn't store registers into %s"), proc_string (thread));
	  return;
	}

      /* Save the T bit.  We might try to restore the %eflags register
         below, but changing the T bit would seriously confuse GDB.  */
      trace = ((struct i386_thread_state *)state)->efl & 0x100;

      if (!was_aborted && was_valid)
	/* See which registers have changed after aborting the thread.  */
	{
	  int check_regno;

	  for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++)
	    if ((thread->fetched_regs & (1 << check_regno))
		&& memcpy (REG_ADDR (&old_state, check_regno),
			   REG_ADDR (state, check_regno),
			   register_size (gdbarch, check_regno)))
	      /* Register CHECK_REGNO has changed!  Ack!  */
	      {
		warning (_("Register %s changed after the thread was aborted"),
			 gdbarch_register_name (gdbarch, check_regno));
		if (regno >= 0 && regno != check_regno)
		  /* Update GDB's copy of the register.  */
		  regcache_raw_supply (regcache, check_regno,
				       REG_ADDR (state, check_regno));
		else
		  warning (_("... also writing this register!  Suspicious..."));
	      }
	}

      if (regno == -1)
	{
	  int i;

	  proc_debug (thread, "storing all registers");

	  for (i = 0; i < I386_NUM_GREGS; i++)
	    if (regcache_valid_p (regcache, i))
	      regcache_raw_collect (regcache, i, REG_ADDR (state, i));
	}
      else
	{
	  proc_debug (thread, "storing register %s",
		      gdbarch_register_name (gdbarch, regno));

	  gdb_assert (regcache_valid_p (regcache, regno));
	  regcache_raw_collect (regcache, regno, REG_ADDR (state, regno));
	}

      /* Restore the T bit.  */
      ((struct i386_thread_state *)state)->efl &= ~0x100;
      ((struct i386_thread_state *)state)->efl |= trace;
    }

  if (regno >= I386_NUM_GREGS || regno == -1)
    {
      proc_debug (thread, "storing floating-point registers");

      store_fpregs (regcache, thread, regno);
    }
}
Esempio n. 29
0
/* Create the status line to display as much information as we can on
   this single line: target name, process number, current function,
   current line, current PC, SingleKey mode.  */
static char*
tui_make_status_line (struct tui_locator_element *loc)
{
  char *string;
  char line_buf[50], *pname;
  char *buf;
  int status_size;
  int i, proc_width;
  const char *pid_name;
  int target_width;
  int pid_width;
  int line_width;

  if (ptid_equal (inferior_ptid, null_ptid))
    pid_name = "No process";
  else
    pid_name = target_pid_to_str (inferior_ptid);

  target_width = strlen (target_shortname);
  if (target_width > MAX_TARGET_WIDTH)
    target_width = MAX_TARGET_WIDTH;

  pid_width = strlen (pid_name);
  if (pid_width > MAX_PID_WIDTH)
    pid_width = MAX_PID_WIDTH;

  status_size = tui_term_width ();
  string = (char *) xmalloc (status_size + 1);
  buf = (char*) alloca (status_size + 1);

  /* Translate line number and obtain its size.  */
  if (loc->line_no > 0)
    xsnprintf (line_buf, sizeof (line_buf), "%d", loc->line_no);
  else
    strcpy (line_buf, "??");
  line_width = strlen (line_buf);
  if (line_width < MIN_LINE_WIDTH)
    line_width = MIN_LINE_WIDTH;

  /* Translate PC address.  */
  string_file pc_out;

  fputs_filtered (loc->gdbarch? paddress (loc->gdbarch, loc->addr) : "??",
		  &pc_out);

  const char *pc_buf = pc_out.c_str ();
  int pc_width = pc_out.size ();

  /* First determine the amount of proc name width we have available.
     The +1 are for a space separator between fields.
     The -1 are to take into account the \0 counted by sizeof.  */
  proc_width = (status_size
                - (target_width + 1)
                - (pid_width + 1)
                - (sizeof (PROC_PREFIX) - 1 + 1)
                - (sizeof (LINE_PREFIX) - 1 + line_width + 1)
                - (sizeof (PC_PREFIX) - 1 + pc_width + 1)
                - (tui_current_key_mode == TUI_SINGLE_KEY_MODE
                   ? (sizeof (SINGLE_KEY) - 1 + 1)
                   : 0));

  /* If there is no room to print the function name, try by removing
     some fields.  */
  if (proc_width < MIN_PROC_WIDTH)
    {
      proc_width += target_width + 1;
      target_width = 0;
      if (proc_width < MIN_PROC_WIDTH)
        {
          proc_width += pid_width + 1;
          pid_width = 0;
          if (proc_width <= MIN_PROC_WIDTH)
            {
              proc_width += pc_width + sizeof (PC_PREFIX) - 1 + 1;
              pc_width = 0;
              if (proc_width < 0)
                {
                  proc_width += line_width + sizeof (LINE_PREFIX) - 1 + 1;
                  line_width = 0;
                  if (proc_width < 0)
                    proc_width = 0;
                }
            }
        }
    }

  /* Now convert elements to string form.  */
  pname = loc->proc_name;

  /* Now create the locator line from the string version of the
     elements.  We could use sprintf() here but that wouldn't ensure
     that we don't overrun the size of the allocated buffer.
     strcat_to_buf() will.  */
  *string = (char) 0;

  if (target_width > 0)
    {
      sprintf (buf, "%*.*s ",
               -target_width, target_width, target_shortname);
      strcat_to_buf (string, status_size, buf);
    }
  if (pid_width > 0)
    {
      sprintf (buf, "%*.*s ",
               -pid_width, pid_width, pid_name);
      strcat_to_buf (string, status_size, buf);
    }
  
  /* Show whether we are in SingleKey mode.  */
  if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
    {
      strcat_to_buf (string, status_size, SINGLE_KEY);
      strcat_to_buf (string, status_size, " ");
    }

  /* Procedure/class name.  */
  if (proc_width > 0)
    {
      if (strlen (pname) > proc_width)
        sprintf (buf, "%s%*.*s* ", PROC_PREFIX,
                 1 - proc_width, proc_width - 1, pname);
      else
        sprintf (buf, "%s%*.*s ", PROC_PREFIX,
                 -proc_width, proc_width, pname);
      strcat_to_buf (string, status_size, buf);
    }

  if (line_width > 0)
    {
      sprintf (buf, "%s%*.*s ", LINE_PREFIX,
               -line_width, line_width, line_buf);
      strcat_to_buf (string, status_size, buf);
    }
  if (pc_width > 0)
    {
      strcat_to_buf (string, status_size, PC_PREFIX);
      strcat_to_buf (string, status_size, pc_buf);
    }
  
  
  for (i = strlen (string); i < status_size; i++)
    string[i] = ' ';
  string[status_size] = (char) 0;

  return string;
}
Esempio n. 30
0
void
inf_ptrace_target::attach (const char *args, int from_tty)
{
  char *exec_file;
  pid_t pid;
  struct inferior *inf;

  /* Do not change either targets above or the same target if already present.
     The reason is the target stack is shared across multiple inferiors.  */
  int ops_already_pushed = target_is_pushed (this);

  pid = parse_pid_to_attach (args);

  if (pid == getpid ())		/* Trying to m********e?  */
    error (_("I refuse to debug myself!"));

  target_unpush_up unpusher;
  if (! ops_already_pushed)
    {
      /* target_pid_to_str already uses the target.  Also clear possible core
	 file with its process_stratum.  */
      push_target (this);
      unpusher.reset (this);
    }

  if (from_tty)
    {
      exec_file = get_exec_file (0);

      if (exec_file)
	printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
			   target_pid_to_str (ptid_t (pid)));
      else
	printf_unfiltered (_("Attaching to %s\n"),
			   target_pid_to_str (ptid_t (pid)));

      gdb_flush (gdb_stdout);
    }

#ifdef PT_ATTACH
  errno = 0;
  ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
  if (errno != 0)
    perror_with_name (("ptrace"));
#else
  error (_("This system does not support attaching to a process"));
#endif

  inf = current_inferior ();
  inferior_appeared (inf, pid);
  inf->attach_flag = 1;
  inferior_ptid = ptid_t (pid);

  /* Always add a main thread.  If some target extends the ptrace
     target, it should decorate the ptid later with more info.  */
  thread_info *thr = add_thread_silent (inferior_ptid);
  /* Don't consider the thread stopped until we've processed its
     initial SIGSTOP stop.  */
  set_executing (thr->ptid, true);

  unpusher.release ();
}