Esempio n. 1
0
static struct gdb_exception
run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc)
{
  volatile struct gdb_exception e;
  int saved_in_infcall = call_thread->control.in_infcall;
  ptid_t call_thread_ptid = call_thread->ptid;

  call_thread->control.in_infcall = 1;

  clear_proceed_status ();

  disable_watchpoints_before_interactive_call_start ();

  /* We want stop_registers, please...  */
  call_thread->control.proceed_to_finish = 1;

  TRY_CATCH (e, RETURN_MASK_ALL)
    {
      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 ();
	}
    }
static void
osf_solib_create_inferior_hook (void)
{
  /* Nothing to do for statically bound executables.  */

  if (symfile_objfile == NULL
      || symfile_objfile->obfd == NULL
      || ((bfd_get_file_flags (symfile_objfile->obfd) & DYNAMIC) == 0))
    return;

  /* Now run the target.  It will eventually get a SIGTRAP, at
     which point all of the libraries will have been mapped in and we
     can go groveling around in the rld structures to find
     out what we need to know about them. */

  clear_proceed_status ();
  stop_soon = STOP_QUIETLY;
  stop_signal = TARGET_SIGNAL_0;
  do
    {
      target_resume (minus_one_ptid, 0, stop_signal);
      wait_for_inferior (0);
    }
  while (stop_signal != TARGET_SIGNAL_TRAP);

  /*  solib_add will call reinit_frame_cache.
     But we are stopped in the runtime loader and we do not have symbols
     for the runtime loader. So heuristic_proc_start will be called
     and will put out an annoying warning.
     Delaying the resetting of stop_soon until after symbol loading
     suppresses the warning.  */
  solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
  stop_soon = NO_STOP_QUIETLY;
}
Esempio n. 3
0
static void
e7000_create_inferior (char *execfile, char *args, char **env)
{
  int entry_pt;

  if (args && *args)
    error ("Can't pass arguments to remote E7000DEBUG process");

  if (execfile == 0 || exec_bfd == 0)
    error ("No executable file specified");

  entry_pt = (int) bfd_get_start_address (exec_bfd);

#ifdef CREATE_INFERIOR_HOOK
  CREATE_INFERIOR_HOOK (0);	/* No process-ID */
#endif

  /* The "process" (board) is already stopped awaiting our commands, and
     the program is already downloaded.  We just set its PC and go.  */

  clear_proceed_status ();

  /* Tell wait_for_inferior that we've started a new process.  */
  init_wait_for_inferior ();

  /* 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 ();

  /* insert_step_breakpoint ();  FIXME, do we need this?  */
  proceed ((CORE_ADDR) entry_pt, -1, 0);	/* Let 'er rip... */
}
Esempio n. 4
0
void
startup_inferior (int ntraps)
{
  int pending_execs = ntraps;
  int terminal_initted = 0;

  /* 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.  */

  clear_proceed_status ();

  init_wait_for_inferior ();

  inferior_ignoring_leading_exec_events =
    target_reported_exec_events_per_exec_call () - 1;

  while (1)
    {
      /* Make wait_for_inferior be quiet. */
      stop_soon = STOP_QUIETLY;
      wait_for_inferior ();
      if (stop_signal != TARGET_SIGNAL_TRAP)
	{
	  /* Let shell child handle its own signals in its own way.
	     FIXME: what if child has exited?  Must exit loop
	     somehow.  */
	  resume (0, stop_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;

	  resume (0, TARGET_SIGNAL_0);	/* Just make it go on.  */
	}
    }
  stop_soon = NO_STOP_QUIETLY;
}
Esempio n. 5
0
static void
osf_solib_create_inferior_hook (int from_tty)
{
    struct inferior *inf;
    struct thread_info *tp;

    inf = current_inferior ();

    /* If we are attaching to the inferior, the shared libraries
       have already been mapped, so nothing more to do.  */
    if (inf->attach_flag)
        return;

    /* Nothing to do for statically bound executables.  */

    if (symfile_objfile == NULL
            || symfile_objfile->obfd == NULL
            || ((bfd_get_file_flags (symfile_objfile->obfd) & DYNAMIC) == 0))
        return;

    /* Now run the target.  It will eventually get a SIGTRAP, at
       which point all of the libraries will have been mapped in and we
       can go groveling around in the rld structures to find
       out what we need to know about them.

       If debugging from a core file, we cannot resume the execution
       of the inferior.  But this is actually not an issue, because
       shared libraries have already been mapped anyways, which means
       we have nothing more to do.  */
    if (!target_can_run (&current_target))
        return;

    tp = inferior_thread ();
    clear_proceed_status ();
    inf->stop_soon = STOP_QUIETLY;
    tp->stop_signal = TARGET_SIGNAL_0;
    do
    {
        target_resume (minus_one_ptid, 0, tp->stop_signal);
        wait_for_inferior (0);
    }
    while (tp->stop_signal != TARGET_SIGNAL_TRAP);

    /*  solib_add will call reinit_frame_cache.
       But we are stopped in the runtime loader and we do not have symbols
       for the runtime loader. So heuristic_proc_start will be called
       and will put out an annoying warning.
       Delaying the resetting of stop_soon until after symbol loading
       suppresses the warning.  */
    solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
    inf->stop_soon = NO_STOP_QUIETLY;
}
Esempio n. 6
0
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 ();
}
static void
metrowerks_step (CORE_ADDR range_start, CORE_ADDR range_stop, int step_into)
{
  struct frame_info *frame = NULL;
  CORE_ADDR pc = 0;

  /* When single stepping in assembly, the plugin passes (start + 1)
     as the stop address. Round the stop address up to the next valid
     instruction */

  if ((range_stop & ~0x3) != range_stop)
      range_stop = ((range_stop + 4) & ~0x3);

  pc = read_pc();

  if (range_start >= range_stop)
    error ("invalid step range (the stop address must be greater than the start address)");

  if (pc < range_start)
    error ("invalid step range ($pc is 0x%lx, less than the stop address of 0x%lx)",
	   (unsigned long) pc, (unsigned long) range_start);
  if (pc == range_stop)
    error ("invalid step range ($pc is 0x%lx, equal to the stop address of 0x%lx)",
	   (unsigned long) pc, (unsigned long) range_stop);
  if (pc > range_stop)
    error ("invalid step range ($pc is 0x%lx, greater than the stop address of 0x%lx)",
	   (unsigned long) pc, (unsigned long) range_stop);

  clear_proceed_status ();

  frame = get_current_frame ();
  if (frame == NULL)
    error ("No current frame");
  step_frame_address = FRAME_FP (frame);
  step_sp = read_sp ();

  step_range_start = range_start;
  step_range_end = range_stop;
  step_over_calls = step_into ? STEP_OVER_NONE : STEP_OVER_ALL;

  step_multi = 0;

  metrowerks_stepping = 1;
  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
  make_exec_cleanup (metrowerks_stepping_cleanup, NULL);
}
Esempio n. 8
0
static void
gdbsim_create_inferior (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 (sr_get_debug ())
    printf_filtered ("gdbsim_create_inferior: exec_file \"%s\", args \"%s\"\n",
		     (exec_file ? exec_file : "(NULL)"),
		     args);

  gdbsim_kill ();
  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 = buildargv (arg_buf);
      make_cleanup_freeargv (argv);
    }
  else
    argv = NULL;
  sim_create_inferior (gdbsim_desc, exec_bfd, argv, env);

  inferior_ptid = pid_to_ptid (42);
  insert_breakpoints ();	/* Needed to get correct instruction in cache */

  clear_proceed_status ();

  /* NB: Entry point already set by sim_create_inferior. */
  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
}
Esempio n. 9
0
static struct gdb_exception
run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc)
{
  volatile struct gdb_exception e;
  int saved_in_infcall = call_thread->control.in_infcall;
  ptid_t call_thread_ptid = call_thread->ptid;
  int saved_sync_execution = sync_execution;

  /* Infcalls run synchronously, in the foreground.  */
  if (target_can_async_p ())
    sync_execution = 1;

  call_thread->control.in_infcall = 1;

  clear_proceed_status ();

  disable_watchpoints_before_interactive_call_start ();

  /* We want stop_registers, please...  */
  call_thread->control.proceed_to_finish = 1;

  TRY_CATCH (e, RETURN_MASK_ALL)
    {
      int was_sync = sync_execution;

      proceed (real_pc, GDB_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 ())
	{
	  wait_for_inferior ();
	  normal_stop ();
	  /* If GDB was previously in sync execution mode, then ensure
	     that it remains so.  normal_stop calls
	     async_enable_stdin, so reset it again here.  In other
	     cases, stdin will be re-enabled by
	     inferior_event_handler, when an exception is thrown.  */
	  if (was_sync)
	    async_disable_stdin ();
	}
    }
Esempio n. 10
0
static void
haiku_init_child_debugging (thread_id threadID, bool debugThread)
{
	thread_info threadInfo;
	status_t result;
	port_id nubPort;

	// get a thread info
	result = get_thread_info(threadID, &threadInfo);
	if (result != B_OK)
		error("Thread with ID %ld not found: %s", threadID, strerror(result));

	// init our team debug structure
	sTeamDebugInfo.team = threadInfo.team;
	sTeamDebugInfo.debugger_port = -1;
	sTeamDebugInfo.context.nub_port = -1;
	sTeamDebugInfo.context.reply_port = -1;
	sTeamDebugInfo.threads = NULL;
	sTeamDebugInfo.events.head = NULL;
	sTeamDebugInfo.events.tail = NULL;

	// create the debugger port
	sTeamDebugInfo.debugger_port = create_port(10, "gdb debug");
	if (sTeamDebugInfo.debugger_port < 0) {
		error("Failed to create debugger port: %s",
			strerror(sTeamDebugInfo.debugger_port));
	}

	// install ourselves as the team debugger
	nubPort = install_team_debugger(sTeamDebugInfo.team,
		sTeamDebugInfo.debugger_port);
	if (nubPort < 0) {
		error("Failed to install ourselves as debugger for team %ld: %s",
			sTeamDebugInfo.team, strerror(nubPort));
	}

	// get the nub thread
	{
		team_info teamInfo;
		result = get_team_info(sTeamDebugInfo.team, &teamInfo);
		if (result != B_OK) {
			error("Failed to get info for team %ld: %s\n",
				sTeamDebugInfo.team, strerror(result));
		}

		sTeamDebugInfo.nub_thread = teamInfo.debugger_nub_thread;
	}

	// init the debug context
	result = init_debug_context(&sTeamDebugInfo.context, sTeamDebugInfo.team,
		nubPort);
	if (result != B_OK) {
		error("Failed to init debug context for team %ld: %s\n",
			sTeamDebugInfo.team, strerror(result));
	}

	// start debugging the thread
	if (debugThread) {
		result = debug_thread(threadID);
		if (result != B_OK) {
			error("Failed to start debugging thread %ld: %s", threadID,
				strerror(result));
		}
	}

	// set the team debug flags
	{
		debug_nub_set_team_flags message;
		message.flags = B_TEAM_DEBUG_SIGNALS /*| B_TEAM_DEBUG_PRE_SYSCALL
			| B_TEAM_DEBUG_POST_SYSCALL*/ | B_TEAM_DEBUG_TEAM_CREATION
			| B_TEAM_DEBUG_THREADS | B_TEAM_DEBUG_IMAGES;
			// TODO: We probably don't need all events

		haiku_send_debugger_message(&sTeamDebugInfo,
			B_DEBUG_MESSAGE_SET_TEAM_FLAGS, &message, sizeof(message), NULL, 0);
	}


	// the fun can start: push the target and init the rest
	push_target(sHaikuTarget);

	haiku_init_thread_list(&sTeamDebugInfo);
	haiku_init_image_list(&sTeamDebugInfo);

	disable_breakpoints_in_shlibs (1);

//	child_clear_solibs ();
		// TODO: Implement? Do we need this?

	clear_proceed_status ();
	init_wait_for_inferior ();

	target_terminal_init ();
	target_terminal_inferior ();
}
Esempio n. 11
0
static void
haiku_init_debug_create_inferior(int pid)
{
	extern int stop_after_trap;

	// fix inferior_ptid -- fork_inferior() sets the process ID only
	inferior_ptid = ptid_build (pid, 0, pid);
		// team ID == team main thread ID under Haiku

	haiku_init_child_debugging(pid, false);

	// eat the initial `debugged' event caused by wait_for_inferior()
// TODO: Maybe we should just dequeue the event and continue the thread instead
// of using gdb's mechanism, since I don't know what undesired side-effects
// they may have.
	clear_proceed_status ();
	init_wait_for_inferior ();

	if (STARTUP_WITH_SHELL)
		inferior_ignoring_startup_exec_events = 2;
	else
		inferior_ignoring_startup_exec_events = 1;
	inferior_ignoring_leading_exec_events = 0;

	while (true) {
		thread_debug_info *thread;

		stop_soon = STOP_QUIETLY;
		wait_for_inferior();

		if (stop_signal == TARGET_SIGNAL_TRAP) {
			thread = haiku_find_thread(&sTeamDebugInfo, pid);

			if (thread && thread->stopped
				&& thread->last_event->message
					== B_DEBUGGER_MESSAGE_IMAGE_CREATED
				&& thread->last_event->data.image_created.info.type
					== B_APP_IMAGE
				&& thread->reprocess_event == 0
				&& inferior_ignoring_startup_exec_events <= 0) {
				// This is the trap for the last (second, if started via shell)
				// `load app image' event. Be done.
				break;
			}
		}

		resume(0, stop_signal);
	}
	stop_soon = NO_STOP_QUIETLY;

	// load shared library symbols
	target_terminal_ours_for_output ();
	SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
	target_terminal_inferior ();

//	startup_inferior (START_INFERIOR_TRAPS_EXPECTED);

//while (1) {
//	stop_after_trap = 1;
//	wait_for_inferior ();
//	if (debugThread && stop_signal != TARGET_SIGNAL_TRAP)
//		resume (0, stop_signal);
//	else
//		break;
//}
//stop_after_trap = 0;



//	while (1) {
//		thread_debug_info *thread;
//
//		stop_after_trap = 1;
//		wait_for_inferior ();
//// TODO: Catch deadly events, so that we won't block here.
//
//		thread = haiku_find_thread(&sTeamDebugInfo, pid);
//TRACE(("haiku_init_debug_create_inferior(): wait_for_inferior() returned: "
//"thread: %p (%ld)\n", thread, (thread ? thread->thread : -1)));
//		if (thread && thread->stopped
//			&& thread->last_event->message
//				== B_DEBUGGER_MESSAGE_IMAGE_CREATED
//			&& thread->last_event->data.image_created.info.type
//				== B_APP_IMAGE) {
//TRACE(("haiku_init_debug_create_inferior(): Got an `app image created' "
//"message\n"));
//			break;
//		}
//
//		resume (0, stop_signal);
//	}
}