Ejemplo n.º 1
0
void
mi_execute_command (char *cmd, int from_tty)
{
  struct mi_parse *command;
  struct captured_mi_execute_command_args args;
  struct ui_out *saved_uiout = uiout;

  /* This is to handle EOF (^D). We just quit gdb.  */
  /* FIXME: we should call some API function here.  */
  if (cmd == 0)
    quit_force (NULL, from_tty);

  command = mi_parse (cmd);

  if (command != NULL)
    {
      struct gdb_exception result;

      if (do_timings)
	{
	  command->cmd_start = (struct mi_timestamp *)
	    xmalloc (sizeof (struct mi_timestamp));
	  timestamp (command->cmd_start);
	}

      /* FIXME: cagney/1999-11-04: Can this use of catch_exceptions either
         be pushed even further down or even eliminated?  */
      args.command = command;
      result = catch_exception (uiout, captured_mi_execute_command, &args,
				RETURN_MASK_ALL);
      exception_print (gdb_stderr, result);

      if (args.action == EXECUTE_COMMAND_SUPRESS_PROMPT)
	{
	  /* The command is executing synchronously.  Bail out early
	     suppressing the finished prompt.  */
	  mi_parse_free (command);
	  return;
	}
      if (result.reason < 0)
	{
	  /* The command execution failed and error() was called
	     somewhere.  */
	  fputs_unfiltered (command->token, raw_stdout);
	  fputs_unfiltered ("^error,msg=\"", raw_stdout);
	  if (result.message == NULL)
	    fputs_unfiltered ("unknown error", raw_stdout);
	  else
	      fputstr_unfiltered (result.message, '"', raw_stdout);
	  fputs_unfiltered ("\"\n", raw_stdout);
	  mi_out_rewind (uiout);
	}
      mi_parse_free (command);
    }

  fputs_unfiltered ("(gdb) \n", raw_stdout);
  gdb_flush (raw_stdout);
  /* Print any buffered hook code.  */
  /* ..... */
}
Ejemplo n.º 2
0
/* Connect to the remote target. */
enum mi_cmd_result
mi_cmd_target_select (char *args, int from_tty)
{
  char *run;
  struct cleanup *old_cleanups = NULL;

  run = xstrprintf ("target %s", args);
  old_cleanups = make_cleanup (xfree, run);

  /* target-select is always synchronous.  once the call has returned
     we know that we are connected. */
  /* NOTE: At present all targets that are connected are also
     (implicitly) talking to a halted target.  In the future this may
     change. */
  execute_command (run, from_tty);

  do_cleanups (old_cleanups);

  /* Issue the completion message here. */
  if (last_async_command)
    fputs_unfiltered (last_async_command, raw_stdout);
  fputs_unfiltered ("^connected", raw_stdout);
  mi_out_put (uiout, raw_stdout);
  mi_out_rewind (uiout);
  fputs_unfiltered ("\n", raw_stdout);
  do_exec_cleanups (ALL_CLEANUPS);
  return MI_CMD_QUIET;
}
Ejemplo n.º 3
0
static void
mi_on_normal_stop (struct bpstats *bs, int print_frame)
{
    /* Since this can be called when CLI command is executing,
       using cli interpreter, be sure to use MI uiout for output,
       not the current one.  */
    struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());

    if (print_frame)
    {
        int core;

        if (current_uiout != mi_uiout)
        {
            /* The normal_stop function has printed frame information
               into CLI uiout, or some other non-MI uiout.  There's no
               way we can extract proper fields from random uiout
               object, so we print the frame again.  In practice, this
               can only happen when running a CLI command in MI.  */
            struct ui_out *saved_uiout = current_uiout;
            struct target_waitstatus last;
            ptid_t last_ptid;

            current_uiout = mi_uiout;

            get_last_target_status (&last_ptid, &last);
            bpstat_print (bs, last.kind);

            print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
            current_uiout = saved_uiout;
        }

        ui_out_field_int (mi_uiout, "thread-id",
                          pid_to_thread_id (inferior_ptid));
        if (non_stop)
        {
            struct cleanup *back_to = make_cleanup_ui_out_list_begin_end
                                      (mi_uiout, "stopped-threads");

            ui_out_field_int (mi_uiout, NULL,
                              pid_to_thread_id (inferior_ptid));
            do_cleanups (back_to);
        }
        else
            ui_out_field_string (mi_uiout, "stopped-threads", "all");

        core = target_core_of_thread (inferior_ptid);
        if (core != -1)
            ui_out_field_int (mi_uiout, "core", core);
    }

    fputs_unfiltered ("*stopped", raw_stdout);
    mi_out_put (mi_uiout, raw_stdout);
    mi_out_rewind (mi_uiout);
    mi_print_timing_maybe ();
    fputs_unfiltered ("\n", raw_stdout);
    gdb_flush (raw_stdout);
}
Ejemplo n.º 4
0
/* Interrupt the execution of the target. Note how we must play around
   with the token varialbes, in order to display the current token in
   the result of the interrupt command, and the previous execution
   token when the target finally stops. See comments in
   mi_cmd_execute. */
enum mi_cmd_result
mi_cmd_exec_interrupt (char *args, int from_tty)
{
  if (!target_executing)
    {
      mi_error_message = xstrprintf ("mi_cmd_exec_interrupt: Inferior not executing.");
      return MI_CMD_ERROR;
    }
  interrupt_target_command (args, from_tty);
  if (last_async_command)
    fputs_unfiltered (last_async_command, raw_stdout);
  fputs_unfiltered ("^done", raw_stdout);
  xfree (last_async_command);
  if (previous_async_command)
    last_async_command = xstrdup (previous_async_command);
  xfree (previous_async_command);
  previous_async_command = NULL;
  mi_out_put (uiout, raw_stdout);
  mi_out_rewind (uiout);
  fputs_unfiltered ("\n", raw_stdout);
  return MI_CMD_QUIET;
}
Ejemplo n.º 5
0
static void
mi_on_normal_stop (struct bpstats *bs, int print_frame)
{
  /* Since this can be called when CLI command is executing,
     using cli interpreter, be sure to use MI uiout for output,
     not the current one.  */
  struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());

  if (print_frame)
    {
      int core;

      if (current_uiout != mi_uiout)
	{
	  /* The normal_stop function has printed frame information
	     into CLI uiout, or some other non-MI uiout.  There's no
	     way we can extract proper fields from random uiout
	     object, so we print the frame again.  In practice, this
	     can only happen when running a CLI command in MI.  */
	  struct ui_out *saved_uiout = current_uiout;
	  struct target_waitstatus last;
	  ptid_t last_ptid;

	  current_uiout = mi_uiout;

	  get_last_target_status (&last_ptid, &last);
	  print_stop_event (&last);

	  current_uiout = saved_uiout;
	}
      /* Otherwise, frame information has already been printed by
	 normal_stop.  */
      else
	{
	  /* Breakpoint hits should always be mirrored to the console.
	     Deciding what to mirror to the console wrt to breakpoints
	     and random stops gets messy real fast.  E.g., say "s"
	     trips on a breakpoint.  We'd clearly want to mirror the
	     event to the console in this case.  But what about more
	     complicated cases like "s&; thread n; s&", and one of
	     those steps spawning a new thread, and that thread
	     hitting a breakpoint?  It's impossible in general to
	     track whether the thread had any relation to the commands
	     that had been executed.  So we just simplify and always
	     mirror breakpoints and random events to the console.

	     Also, CLI execution commands (-interpreter-exec console
	     "next", for example) in async mode have the opposite
	     issue as described in the "then" branch above --
	     normal_stop has already printed frame information to MI
	     uiout, but nothing has printed the same information to
	     the CLI channel.  We should print the source line to the
	     console when stepping or other similar commands, iff the
	     step was started by a console command (but not if it was
	     started with -exec-step or similar).  */
	  struct thread_info *tp = inferior_thread ();

	  if ((!tp->control.stop_step
		  && !tp->control.proceed_to_finish)
	      || (tp->control.command_interp != NULL
		  && tp->control.command_interp != top_level_interpreter ()))
	    {
	      struct mi_interp *mi = top_level_interpreter_data ();
	      struct target_waitstatus last;
	      ptid_t last_ptid;
	      struct cleanup *old_chain;

	      /* Set the current uiout to CLI uiout temporarily.  */
	      old_chain = make_cleanup (restore_current_uiout_cleanup,
					current_uiout);
	      current_uiout = mi->cli_uiout;

	      get_last_target_status (&last_ptid, &last);
	      print_stop_event (&last);

	      do_cleanups (old_chain);
	    }
	}

      ui_out_field_int (mi_uiout, "thread-id",
			pid_to_thread_id (inferior_ptid));
      if (non_stop)
	{
	  struct cleanup *back_to = make_cleanup_ui_out_list_begin_end 
	    (mi_uiout, "stopped-threads");

	  ui_out_field_int (mi_uiout, NULL,
			    pid_to_thread_id (inferior_ptid));
	  do_cleanups (back_to);
	}
      else
	ui_out_field_string (mi_uiout, "stopped-threads", "all");

      core = target_core_of_thread (inferior_ptid);
      if (core != -1)
	ui_out_field_int (mi_uiout, "core", core);
    }
  
  fputs_unfiltered ("*stopped", raw_stdout);
  mi_out_put (mi_uiout, raw_stdout);
  mi_out_rewind (mi_uiout);
  mi_print_timing_maybe ();
  fputs_unfiltered ("\n", raw_stdout);
  gdb_flush (raw_stdout);
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
static void
mi_on_normal_stop (struct bpstats *bs, int print_frame)
{
  /* Since this can be called when CLI command is executing,
     using cli interpreter, be sure to use MI uiout for output,
     not the current one.  */
  struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());

  if (print_frame)
    {
      struct thread_info *tp;
      int core;

      tp = inferior_thread ();

      if (tp->thread_fsm != NULL
	  && thread_fsm_finished_p (tp->thread_fsm))
	{
	  enum async_reply_reason reason;

	  reason = thread_fsm_async_reply_reason (tp->thread_fsm);
	  ui_out_field_string (mi_uiout, "reason",
			       async_reason_lookup (reason));
	}
      print_stop_event (mi_uiout);

      /* Breakpoint hits should always be mirrored to the console.
	 Deciding what to mirror to the console wrt to breakpoints and
	 random stops gets messy real fast.  E.g., say "s" trips on a
	 breakpoint.  We'd clearly want to mirror the event to the
	 console in this case.  But what about more complicated cases
	 like "s&; thread n; s&", and one of those steps spawning a
	 new thread, and that thread hitting a breakpoint?  It's
	 impossible in general to track whether the thread had any
	 relation to the commands that had been executed.  So we just
	 simplify and always mirror breakpoints and random events to
	 the console.

	 OTOH, we should print the source line to the console when
	 stepping or other similar commands, iff the step was started
	 by a console command, but not if it was started with
	 -exec-step or similar.  */
      if ((bpstat_what (tp->control.stop_bpstat).main_action
	   == BPSTAT_WHAT_STOP_NOISY)
	  || !(tp->thread_fsm != NULL
	       && thread_fsm_finished_p (tp->thread_fsm))
	  || (tp->control.command_interp != NULL
	      && tp->control.command_interp != top_level_interpreter ()))
	{
	  struct mi_interp *mi
	    = (struct mi_interp *) top_level_interpreter_data ();

	  print_stop_event (mi->cli_uiout);
	}

      ui_out_field_int (mi_uiout, "thread-id",
			pid_to_thread_id (inferior_ptid));
      if (non_stop)
	{
	  struct cleanup *back_to = make_cleanup_ui_out_list_begin_end 
	    (mi_uiout, "stopped-threads");

	  ui_out_field_int (mi_uiout, NULL,
			    pid_to_thread_id (inferior_ptid));
	  do_cleanups (back_to);
	}
      else
	ui_out_field_string (mi_uiout, "stopped-threads", "all");

      core = target_core_of_thread (inferior_ptid);
      if (core != -1)
	ui_out_field_int (mi_uiout, "core", core);
    }
  
  fputs_unfiltered ("*stopped", raw_stdout);
  mi_out_put (mi_uiout, raw_stdout);
  mi_out_rewind (mi_uiout);
  mi_print_timing_maybe ();
  fputs_unfiltered ("\n", raw_stdout);
  gdb_flush (raw_stdout);
}