static void
metrowerks_step_command (char *args, int from_tty)
{
  int async_exec = 0;
  CORE_ADDR range_start = 0;
  CORE_ADDR range_stop = 0;
  int step_into = 0;
  int num_args = 0;
  char **argv = NULL;

  if (args != NULL)
    async_exec = strip_bg_char (&args);

  if (event_loop_p && async_exec && !target_can_async_p ())
    error ("Asynchronous execution not supported on this target.");

  /* If we do NOT get a request of running in the bg, then we need
   * to simulate synchronous (fg) execution. */
  if (event_loop_p && !async_exec && target_can_async_p ())
    {
      async_disable_stdin ();
    }

  argv = buildargv (args);

  if (argv == NULL)
    {
      num_args = 0;
    }
  else
    {
      num_args = 0;
      while (argv[num_args] != NULL)
	num_args++;
    }

  if (num_args != 3 && num_args != 5)
    error ("Usage: metrowerks-step <start> <stop> <step-into> ?<func_start> <func_end>?");

  range_start = strtoul (argv[0], NULL, 16);
  range_stop = strtoul (argv[1], NULL, 16);
  step_into = strtoul (argv[2], NULL, 16);

  if (num_args == 5)
    {
      metrowerks_step_func_start = strtoul (argv[3], NULL, 16);
      metrowerks_step_func_end = strtoul (argv[4], NULL, 16);
    }
  else
    {
      metrowerks_step_func_start = 0;
      metrowerks_step_func_end = 0;
    }

  if (!target_has_execution)
    error ("The program is not being run.");

  metrowerks_step (range_start, range_stop, step_into);
}
Beispiel #2
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 ();
	}
    }
Beispiel #3
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 ();
	}
    }
Beispiel #4
0
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;
    }
Beispiel #5
0
/* Quit GDB if SIGTERM is received.
   GDB would quit anyway, but this way it will clean up properly.  */
void
handle_sigterm (int sig)
{
    signal (sig, handle_sigterm);

    /* Call quit_force in a signal safe way.
       quit_force itself is not signal safe.  */
    if (target_can_async_p ())
        mark_async_signal_handler (async_sigterm_token);
    else
    {
        sync_quit_force_run = 1;
        set_quit_flag ();
    }
}
Beispiel #6
0
/* NOTE: 1999-04-30 This is the asynchronous version of the command_loop
   function.  The command_loop function will be obsolete when we
   switch to use the event loop at every execution of gdb. */
static void
command_handler (char *command)
{
  struct cleanup *old_chain;
  int stdin_is_tty = ISATTY (stdin);
  struct continuation_arg *arg1;
  struct continuation_arg *arg2;
  long time_at_cmd_start;
#ifdef HAVE_SBRK
  long space_at_cmd_start = 0;
#endif
  extern int display_time;
  extern int display_space;

  quit_flag = 0;
  if (instream == stdin && stdin_is_tty)
    reinitialize_more_filter ();
  old_chain = make_cleanup (null_cleanup, 0);

  /* If readline returned a NULL command, it means that the 
     connection with the terminal is gone. This happens at the
     end of a testsuite run, after Expect has hung up 
     but GDB is still alive. In such a case, we just quit gdb
     killing the inferior program too. */
  if (command == 0)
    quit_command ((char *) 0, stdin == instream);

  time_at_cmd_start = get_run_time ();

  if (display_space)
    {
#ifdef HAVE_SBRK
      char *lim = (char *) sbrk (0);
      space_at_cmd_start = lim - lim_at_start;
#endif
    }

  execute_command (command, instream == stdin);

  /* Set things up for this function to be compete later, once the
     execution has completed, if we are doing an execution command,
     otherwise, just go ahead and finish. */
  if (target_can_async_p () && target_executing)
    {
      arg1 =
	(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
      arg2 =
	(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
      arg1->next = arg2;
      arg2->next = NULL;
      arg1->data.longint = time_at_cmd_start;
#ifdef HAVE_SBRK
      arg2->data.longint = space_at_cmd_start;
#endif
      add_continuation (command_line_handler_continuation, arg1);
    }

  /* Do any commands attached to breakpoint we stopped at. Only if we
     are always running synchronously. Or if we have just executed a
     command that doesn't start the target. */
  if (!target_can_async_p () || !target_executing)
    {
      bpstat_do_actions (&stop_bpstat);
      do_cleanups (old_chain);

      if (display_time)
	{
	  long cmd_time = get_run_time () - time_at_cmd_start;

	  printf_unfiltered (_("Command execution time: %ld.%06ld\n"),
			     cmd_time / 1000000, cmd_time % 1000000);
	}

      if (display_space)
	{
#ifdef HAVE_SBRK
	  char *lim = (char *) sbrk (0);
	  long space_now = lim - lim_at_start;
	  long space_diff = space_now - space_at_cmd_start;

	  printf_unfiltered (_("Space used: %ld (%c%ld for this command)\n"),
			     space_now,
			     (space_diff >= 0 ? '+' : '-'),
			     space_diff);
#endif
	}
    }
}
Beispiel #7
0
enum mi_cmd_result
mi_execute_async_cli_command (char *mi, char *args, int from_tty)
{
  struct cleanup *old_cleanups;
  char *run;
  char *async_args;

  if (target_can_async_p ())
    {
      async_args = (char *) xmalloc (strlen (args) + 2);
      make_exec_cleanup (free, async_args);
      strcpy (async_args, args);
      strcat (async_args, "&");
      run = xstrprintf ("%s %s", mi, async_args);
      make_exec_cleanup (free, run);
      add_continuation (mi_exec_async_cli_cmd_continuation, NULL);
      old_cleanups = NULL;
    }
  else
    {
      run = xstrprintf ("%s %s", mi, args);
      old_cleanups = make_cleanup (xfree, run);
    }

  if (!target_can_async_p ())
    {
      /* NOTE: For synchronous targets asynchronous behavour is faked by
         printing out the GDB prompt before we even try to execute the
         command. */
      if (last_async_command)
	fputs_unfiltered (last_async_command, raw_stdout);
      fputs_unfiltered ("^running\n", raw_stdout);
      fputs_unfiltered ("(gdb) \n", raw_stdout);
      gdb_flush (raw_stdout);
    }
  else
    {
      /* FIXME: cagney/1999-11-29: Printing this message before
         calling execute_command is wrong.  It should only be printed
         once gdb has confirmed that it really has managed to send a
         run command to the target. */
      if (last_async_command)
	fputs_unfiltered (last_async_command, raw_stdout);
      fputs_unfiltered ("^running\n", raw_stdout);
    }

  execute_command ( /*ui */ run, 0 /*from_tty */ );

  if (!target_can_async_p ())
    {
      /* Do this before doing any printing.  It would appear that some
         print code leaves garbage around in the buffer. */
      do_cleanups (old_cleanups);
      /* If the target was doing the operation synchronously we fake
         the stopped message. */
      if (last_async_command)
	fputs_unfiltered (last_async_command, raw_stdout);
      fputs_unfiltered ("*stopped", raw_stdout);
      mi_out_put (uiout, raw_stdout);
      mi_out_rewind (uiout);
      fputs_unfiltered ("\n", raw_stdout);
      return MI_CMD_QUIET;
    }
  return MI_CMD_DONE;
}
Beispiel #8
0
static void
captured_mi_execute_command (struct ui_out *uiout, void *data)
{
  struct captured_mi_execute_command_args *args =
    (struct captured_mi_execute_command_args *) data;
  struct mi_parse *context = args->command;

  switch (context->op)
    {

    case MI_COMMAND:
      /* A MI command was read from the input stream */
      if (mi_debug_p)
	/* FIXME: gdb_???? */
	fprintf_unfiltered (raw_stdout, " token=`%s' command=`%s' args=`%s'\n",
			    context->token, context->command, context->args);
      /* FIXME: cagney/1999-09-25: Rather than this convoluted
         condition expression, each function should return an
         indication of what action is required and then switch on
         that. */
      args->action = EXECUTE_COMMAND_DISPLAY_PROMPT;
      args->rc = mi_cmd_execute (context);

      if (!target_can_async_p () || !target_executing)
	{
	  /* print the result if there were no errors

	     Remember that on the way out of executing a command, you have
	     to directly use the mi_interp's uiout, since the command could 
	     have reset the interpreter, in which case the current uiout 
	     will most likely crash in the mi_out_* routines.  */
	  if (args->rc == MI_CMD_DONE)
	    {
	      fputs_unfiltered (context->token, raw_stdout);
	      fputs_unfiltered ("^done", raw_stdout);
	      mi_out_put (uiout, raw_stdout);
	      mi_out_rewind (uiout);
	      fputs_unfiltered ("\n", raw_stdout);
	    }
	  else if (args->rc == MI_CMD_ERROR)
	    {
	      if (mi_error_message)
		{
		  fputs_unfiltered (context->token, raw_stdout);
		  fputs_unfiltered ("^error,msg=\"", raw_stdout);
		  fputstr_unfiltered (mi_error_message, '"', raw_stdout);
		  xfree (mi_error_message);
		  fputs_unfiltered ("\"\n", raw_stdout);
		}
	      mi_out_rewind (uiout);
	    }
	  else
	    mi_out_rewind (uiout);
	}
      else if (sync_execution)
	{
	  /* Don't print the prompt. We are executing the target in
	     synchronous mode. */
	  args->action = EXECUTE_COMMAND_SUPRESS_PROMPT;
	  return;
	}
      break;

    case CLI_COMMAND:
      {
	char *argv[2];
	/* A CLI command was read from the input stream.  */
	/* This "feature" will be removed as soon as we have a
	   complete set of mi commands.  */
	/* Echo the command on the console.  */
	fprintf_unfiltered (gdb_stdlog, "%s\n", context->command);
	/* Call the "console" interpreter.  */
	argv[0] = "console";
	argv[1] = context->command;
	args->rc = mi_cmd_interpreter_exec ("-interpreter-exec", argv, 2);

	/* If we changed interpreters, DON'T print out anything.  */
	if (current_interp_named_p (INTERP_MI)
	    || current_interp_named_p (INTERP_MI1)
	    || current_interp_named_p (INTERP_MI2)
	    || current_interp_named_p (INTERP_MI3))
	  {
	    if (args->rc == MI_CMD_DONE)
	      {
		fputs_unfiltered (context->token, raw_stdout);
		fputs_unfiltered ("^done", raw_stdout);
		mi_out_put (uiout, raw_stdout);
		mi_out_rewind (uiout);
		fputs_unfiltered ("\n", raw_stdout);
		args->action = EXECUTE_COMMAND_DISPLAY_PROMPT;
	      }
	    else if (args->rc == MI_CMD_ERROR)
	      {
		if (mi_error_message)
		  {
		    fputs_unfiltered (context->token, raw_stdout);
		    fputs_unfiltered ("^error,msg=\"", raw_stdout);
		    fputstr_unfiltered (mi_error_message, '"', raw_stdout);
		    xfree (mi_error_message);
		    fputs_unfiltered ("\"\n", raw_stdout);
		  }
		mi_out_rewind (uiout);
	      }
	    else
	      mi_out_rewind (uiout);
	  }
	break;
      }

    }

  return;
}
static int
async_background_execution_p (void)
{
    return (target_can_async_p () && !sync_execution);
}