static int target_event_stop_handler(struct target *target)
{
	int cnt;
	enum app_type_t app_type = target->app_type;

	LOGI("target[%p] close, pid(%d) : (remaining %d target)\n",
	     target, target_get_pid(target), target_cnt_get() - 1);

	ecore_main_fd_handler_del(target->handler);

	target_wait(target);
	target_dtor(target);
	// all target client are closed
	cnt = target_cnt_sub_and_fetch();
	if (0 == cnt) {
		switch (app_type) {
		case APP_TYPE_TIZEN:
		case APP_TYPE_COMMON:
			LOGI("all targets are stopped\n");
			if (stop_all() != ERR_NO)
				LOGE("Stop failed\n");
			return -11;
		}
	}

	return 0;
}
Ejemplo n.º 2
0
/* When running a stand-alone SPE executable, we may need to skip one more
   exec event on startup, to get past the binfmt_misc loader.  */
static void
spu_skip_standalone_loader (void)
{
  if (target_has_execution && !current_inferior ()->attach_flag)
    {
      struct target_waitstatus ws;

      /* Only some kernels report an extra SIGTRAP with the binfmt_misc
	 loader; others do not.  In addition, if we have attached to an
	 already running inferior instead of starting a new one, we will
	 not see the extra SIGTRAP -- and we cannot readily distinguish
	 the two cases, in particular with the extended-remote target.

	 Thus we issue a single-step here.  If no extra SIGTRAP was pending,
	 this will step past the first instruction of the stand-alone SPE
	 executable loader, but we don't care about that.  */

      inferior_thread ()->control.in_infcall = 1; /* Suppress MI messages.  */

      target_resume (inferior_ptid, 1, GDB_SIGNAL_0);
      target_wait (minus_one_ptid, &ws, 0);
      set_executing (minus_one_ptid, 0);

      inferior_thread ()->control.in_infcall = 0;
    }
}
void target_wait_all(void)
{
	int i;
	struct target *t;

	target_array_lock();
	for (i = 0; i < MAX_TARGET_COUNT; ++i) {
		if (target_use[i] == 0)
			continue;

		t = target_get(i);

		LOGI("join recv thread [%d] is started\n", i);
		target_wait(t);
		LOGI("join recv thread %d. done\n", i);
	}
	target_array_unlock();
}
Ejemplo n.º 4
0
/* Called when going to wait for the target.
   Leave curses mode and setup program mode.  */
static ptid_t
tui_target_wait_hook (ptid_t pid, struct target_waitstatus *status)
{
  ptid_t res;

  /* Leave tui mode (optional).  */
#if 0
  if (tui_active)
    {
      target_terminal_ours ();
      endwin ();
      target_terminal_inferior ();
    }
#endif
  tui_target_has_run = 1;
  res = target_wait (pid, status);

  if (tui_active)
    {
      /* TODO: need to refresh (optional).  */
    }
  return res;
}
Ejemplo n.º 5
0
void
startup_inferior (int ntraps)
{
  int pending_execs = ntraps;
  int terminal_initted = 0;
  ptid_t resume_ptid;

  if (target_supports_multi_process ())
    resume_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
  else
    resume_ptid = minus_one_ptid;

  /* The process was started by the fork that created it, but it will
     have stopped one instruction after execing the shell.  Here we
     must get it up to actual execution of the real program.  */

  if (exec_wrapper)
    pending_execs++;

  while (1)
    {
      enum target_signal resume_signal = TARGET_SIGNAL_0;
      ptid_t event_ptid;

      struct target_waitstatus ws;
      memset (&ws, 0, sizeof (ws));
      event_ptid = target_wait (resume_ptid, &ws, 0);

      if (ws.kind == TARGET_WAITKIND_IGNORE)
	/* The inferior didn't really stop, keep waiting.  */
	continue;

      switch (ws.kind)
	{
	  case TARGET_WAITKIND_SPURIOUS:
	  case TARGET_WAITKIND_LOADED:
	  case TARGET_WAITKIND_FORKED:
	  case TARGET_WAITKIND_VFORKED:
	  case TARGET_WAITKIND_SYSCALL_ENTRY:
	  case TARGET_WAITKIND_SYSCALL_RETURN:
	    /* Ignore gracefully during startup of the inferior.  */
	    switch_to_thread (event_ptid);
	    break;

	  case TARGET_WAITKIND_SIGNALLED:
	    target_terminal_ours ();
	    target_mourn_inferior ();
	    error (_("During startup program terminated with signal %s, %s."),
		   target_signal_to_name (ws.value.sig),
		   target_signal_to_string (ws.value.sig));
	    return;

	  case TARGET_WAITKIND_EXITED:
	    target_terminal_ours ();
	    target_mourn_inferior ();
	    if (ws.value.integer)
	      error (_("During startup program exited with code %d."),
		     ws.value.integer);
	    else
	      error (_("During startup program exited normally."));
	    return;

	  case TARGET_WAITKIND_EXECD:
	    /* Handle EXEC signals as if they were SIGTRAP signals.  */
	    xfree (ws.value.execd_pathname);
	    resume_signal = TARGET_SIGNAL_TRAP;
	    switch_to_thread (event_ptid);
	    break;

	  case TARGET_WAITKIND_STOPPED:
	    resume_signal = ws.value.sig;
	    switch_to_thread (event_ptid);
	    break;
	}

      if (resume_signal != TARGET_SIGNAL_TRAP)
	{
	  /* Let shell child handle its own signals in its own way.  */
	  target_resume (resume_ptid, 0, resume_signal);
	}
      else
	{
	  /* We handle SIGTRAP, however; it means child did an exec.  */
	  if (!terminal_initted)
	    {
	      /* Now that the child has exec'd we know it has already
	         set its process group.  On POSIX systems, tcsetpgrp
	         will fail with EPERM if we try it before the child's
	         setpgid.  */

	      /* Set up the "saved terminal modes" of the inferior
	         based on what modes we are starting it with.  */
	      target_terminal_init ();

	      /* Install inferior's terminal modes.  */
	      target_terminal_inferior ();

	      terminal_initted = 1;
	    }

	  if (--pending_execs == 0)
	    break;

	  /* Just make it go on.  */
	  target_resume (resume_ptid, 0, TARGET_SIGNAL_0);
	}
    }

  /* Mark all threads non-executing.  */
  set_executing (resume_ptid, 0);
}
Ejemplo n.º 6
0
int
agent_run_command (int pid, const char *cmd, int len)
{
  int fd;
  int tid = agent_get_helper_thread_id ();
  ptid_t ptid = ptid_build (pid, tid, 0);

#ifdef GDBSERVER
  int ret = write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
				   (const unsigned char *) cmd, len);
#else
  int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf, cmd, len);
#endif

  if (ret != 0)
    {
      warning (_("unable to write"));
      return -1;
    }

  DEBUG_AGENT ("agent: resumed helper thread\n");

  /* Resume helper thread.  */
#ifdef GDBSERVER
{
  struct thread_resume resume_info;

  resume_info.thread = ptid;
  resume_info.kind = resume_continue;
  resume_info.sig = GDB_SIGNAL_0;
  (*the_target->resume) (&resume_info, 1);
}
#else
 target_resume (ptid, 0, GDB_SIGNAL_0);
#endif

  fd = gdb_connect_sync_socket (pid);
  if (fd >= 0)
    {
      char buf[1] = "";
      int ret;

      DEBUG_AGENT ("agent: signalling helper thread\n");

      do
	{
	  ret = write (fd, buf, 1);
	} while (ret == -1 && errno == EINTR);

	DEBUG_AGENT ("agent: waiting for helper thread's response\n");

      do
	{
	  ret = read (fd, buf, 1);
	} while (ret == -1 && errno == EINTR);

      close (fd);

      DEBUG_AGENT ("agent: helper thread's response received\n");
    }
  else
    return -1;

  /* Need to read response with the inferior stopped.  */
  if (!ptid_equal (ptid, null_ptid))
    {
      struct target_waitstatus status;
      int was_non_stop = non_stop;
      /* Stop thread PTID.  */
      DEBUG_AGENT ("agent: stop helper thread\n");
#ifdef GDBSERVER
      {
	struct thread_resume resume_info;

	resume_info.thread = ptid;
	resume_info.kind = resume_stop;
	resume_info.sig = GDB_SIGNAL_0;
	(*the_target->resume) (&resume_info, 1);
      }

      non_stop = 1;
      mywait (ptid, &status, 0, 0);
#else
      non_stop = 1;
      target_stop (ptid);

      memset (&status, 0, sizeof (status));
      target_wait (ptid, &status, 0);
#endif
      non_stop = was_non_stop;
    }

  if (fd >= 0)
    {
#ifdef GDBSERVER
      if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
				(unsigned char *) cmd, IPA_CMD_BUF_SIZE))
#else
      if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd,
			      IPA_CMD_BUF_SIZE))
#endif
	{
	  warning (_("Error reading command response"));
	  return -1;
	}
    }

  return 0;
}