This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

General ``monitor'' command; remote ``qRcmd,...'' packet


FYI,

I'm just checking in the attached patch.  It takes the ``monitor''
command found in monitor.c and generalizes it.

For remote.c, I've implemented ``monitor'' command using the recently
specified ``qRcmd'' packet.
In addition I've clarified a number of aspects of the ``qRcmd'' packet.

As an example:

	(gdb) monitor hello
	Sending packet: $qRcmd,68656c6c6f#ca...Ack
	Packet received: 68656c6c6f
	hello(gdb) quit

enjoy,
	Andrew


Thu Aug  5 16:22:10 1999  Andrew Cagney  <cagney@b1.cygnus.com>

        * remote.c (init_remote_ops): Initialize remote_ops.to_rcmd.
        (init_remote_async_ops): Initialize remote_async_ops.to_query.
        (remote_rcmd): New function.

        * monitor.c (monitor_rcmd): Rename monitor_command.
        (init_base_monitor_ops): Initialize monitor_ops.to_rcmd.
        (_initialize_remote_monitors): Move "monitor" command from here.
        * target.c (initialize_targets): To here.
        (monitor_command): New function.  Implement "monitor" command.

        * target.c (cleanup_target): de_fault to_rcmd.
        (update_current_target): INHERIT to_rcmd.
        (debug_to_rcmd): New function.
        (setup_target_debug): Initialize current_target.to_rcmd.

        * target.h (struct target_ops): Add field to_rcmd.
        (target_rcmd): Define.

Thu Aug  5 17:57:41 1999  Andrew Cagney  <cagney@b1.cygnus.com>

        * remote.texi (protocol qRcmd): Allow ``OK'' and ``O...''
response
        packets.
? diffs
Index: monitor.c
===================================================================
RCS file: /cvs/gdb/gdb/gdb/monitor.c,v
retrieving revision 1.1.1.5
diff -p -r1.1.1.5 monitor.c
*** monitor.c	1999/08/02 23:45:50	1.1.1.5
--- monitor.c	1999/08/05 08:27:09
*************** static void monitor_vsprintf PARAMS ((ch
*** 67,74 ****
  
  static int readchar PARAMS ((int timeout));
  
- static void monitor_command PARAMS ((char *args, int fromtty));
- 
  static void monitor_fetch_register PARAMS ((int regno));
  static void monitor_store_register PARAMS ((int regno));
  
--- 67,72 ----
*************** monitor_stop ()
*** 2261,2274 ****
      monitor_printf_noecho (current_monitor->stop);
  }
  
! /* Put a command string, in args, out to MONITOR.  Output from MONITOR
!    is placed on the users terminal until the prompt is seen. FIXME: We
!    read the characters ourseleves here cause of a nasty echo.  */
  
  static void
! monitor_command (args, from_tty)
!      char *args;
!      int from_tty;
  {
    char *p;
    int resp_len;
--- 2259,2271 ----
      monitor_printf_noecho (current_monitor->stop);
  }
  
! /* Put a COMMAND string out to MONITOR.  Output from MONITOR is placed
!    in OUTPUT until the prompt is seen. FIXME: We read the characters
!    ourseleves here cause of a nasty echo.  */
  
  static void
! monitor_rcmd (char *command,
! 	      struct gdb_file *outbuf)
  {
    char *p;
    int resp_len;
*************** monitor_command (args, from_tty)
*** 2282,2292 ****
    /* Send the command.  Note that if no args were supplied, then we're
       just sending the monitor a newline, which is sometimes useful.  */
  
!   monitor_printf ("%s\r", (args ? args : ""));
  
    resp_len = monitor_expect_prompt (buf, sizeof buf);
  
!   fputs_unfiltered (buf, gdb_stdout);	/* Output the response */
  }
  
  /* Convert hex digit A to a number.  */
--- 2279,2289 ----
    /* Send the command.  Note that if no args were supplied, then we're
       just sending the monitor a newline, which is sometimes useful.  */
  
!   monitor_printf ("%s\r", (command ? command : ""));
  
    resp_len = monitor_expect_prompt (buf, sizeof buf);
  
!   fputs_unfiltered (buf, outbuf);	/* Output the response */
  }
  
  /* Convert hex digit A to a number.  */
*************** init_base_monitor_ops (void)
*** 2369,2374 ****
--- 2366,2372 ----
    monitor_ops.to_notice_signals = 0;
    monitor_ops.to_thread_alive = 0;
    monitor_ops.to_stop = monitor_stop;
+   monitor_ops.to_rcmd = monitor_rcmd;
    monitor_ops.to_pid_to_exec_file = NULL;
    monitor_ops.to_core_file_to_sym_file = NULL;
    monitor_ops.to_stratum = process_stratum;
*************** _initialize_remote_monitors ()
*** 2407,2413 ****
  When enabled, a hashmark \'#\' is displayed.",
  				  &setlist),
  		     &showlist);
- 
-   add_com ("monitor", class_obscure, monitor_command,
- 	   "Send a command to the debug monitor.");
  }
--- 2405,2408 ----
Index: remote.c
===================================================================
RCS file: /cvs/gdb/gdb/gdb/remote.c,v
retrieving revision 1.1.1.13
diff -p -r1.1.1.13 remote.c
*** remote.c	1999/07/27 00:51:01	1.1.1.13
--- remote.c	1999/08/05 08:27:46
*************** remote_query (query_type, buf, outbuf, b
*** 4287,4292 ****
--- 4287,4345 ----
  }
  
  static void
+ remote_rcmd (char *command,
+ 	     struct gdb_file *outbuf)
+ {
+   int i;
+   char *buf = alloca (PBUFSIZ);
+   char *p = buf;
+ 
+   if (!remote_desc)
+     error ("remote rcmd is only available after target open");
+ 
+   /* The query prefix */
+   strcpy (buf, "qRcmd,");
+   p = strchr (buf, '\0');
+ 
+   if ((strlen (buf) + strlen (command) * 2) + 8/*misc*/)
+     error ("\"monitor\" command is too long\n");
+ 
+   /* Encode the actual command */
+   for (i = 0; command[i]; i++)
+     {
+       *p++ = tohex ((command[i] >> 4) & 0xf);
+       *p++ = tohex (command[i] & 0xf);
+     }
+   *p = '\0';
+ 
+   if (putpkt (buf) < 0)
+     error ("Communication problem with target\n");
+ 
+   /* get/display the response */
+   while (1)
+     {
+       /* XXX - see also tracepoint.c:remote_get_noisy_reply() */
+       buf[0] = '\0';
+       getpkt (buf, 0);
+       if (buf[0] == '\0')
+ 	error ("Target does not support this command\n");
+       if (buf[0] == 'O' && buf[1] != 'K')
+ 	{
+ 	  remote_console_output (buf + 1); /* 'O' message from stub */
+ 	  continue;
+ 	}
+       if (strcmp (buf, "OK") == 0)
+ 	break;
+       for (p = buf; p[0] != '\0' && p[1] != '\0'; p += 2)
+ 	{
+ 	  char c = (fromhex (p[0]) << 4) + fromhex (p[1]);
+ 	  fputc_unfiltered (c, outbuf);
+ 	}
+       break;
+     }
+ }
+ 
+ static void
  packet_command (args, from_tty)
       char *args;
       int from_tty;
*************** Specify the serial device it is connecte
*** 4498,4503 ****
--- 4551,4557 ----
    remote_ops.to_find_new_threads = remote_threads_info;
    remote_ops.to_stop = remote_stop;
    remote_ops.to_query = remote_query;
+   remote_ops.to_rcmd = remote_rcmd;
    remote_ops.to_stratum = process_stratum;
    remote_ops.to_has_all_memory = 1;
    remote_ops.to_has_memory = 1;
*************** Specify the serial device it is connecte
*** 4952,4957 ****
--- 5006,5012 ----
    remote_async_ops.to_find_new_threads = remote_threads_info;
    remote_async_ops.to_stop = remote_stop;
    remote_async_ops.to_query = remote_query;
+   remote_async_ops.to_rcmd = remote_rcmd;
    remote_async_ops.to_stratum = process_stratum;
    remote_async_ops.to_has_all_memory = 1;
    remote_async_ops.to_has_memory = 1;
Index: target.c
===================================================================
RCS file: /cvs/gdb/gdb/gdb/target.c,v
retrieving revision 1.1.1.9
diff -p -r1.1.1.9 target.c
*** target.c	1999/07/19 23:28:13	1.1.1.9
--- target.c	1999/08/05 08:28:06
*************** cleanup_target (t)
*** 444,449 ****
--- 444,450 ----
    de_fault (to_thread_alive, (int (*)PARAMS ((int))) target_ignore);
    de_fault (to_stop, (void (*)PARAMS ((void))) target_ignore);
    de_fault (to_query, (int (*)PARAMS ((int /*char */ , char *, char *, int *))) target_ignore);
+   de_fault (to_rcmd, (void (*) (char *, struct gdb_file *)) tcomplain);
    de_fault (to_enable_exception_callback, (struct symtab_and_line * (*)PARAMS ((enum exception_event_kind, int))) nosupport_runtime);
    de_fault (to_get_current_exception_event, (struct exception_event_record * (*)PARAMS ((void))) nosupport_runtime);
  
*************** update_current_target ()
*** 527,532 ****
--- 528,534 ----
        INHERIT (to_find_new_threads, t);
        INHERIT (to_stop, t);
        INHERIT (to_query, t);
+       INHERIT (to_rcmd, t);
        INHERIT (to_enable_exception_callback, t);
        INHERIT (to_get_current_exception_event, t);
        INHERIT (to_pid_to_exec_file, t);
*************** debug_to_query (type, req, resp, siz)
*** 2602,2607 ****
--- 2604,2617 ----
    return retval;
  }
  
+ static void
+ debug_to_rcmd (char *command,
+ 	       struct gdb_file *outbuf)
+ {
+   debug_target.to_rcmd (command, outbuf);
+   fprintf_unfiltered (gdb_stdlog, "target_rcmd (%s, ...)\n", command);
+ }
+ 
  static struct symtab_and_line *
  debug_to_enable_exception_callback (kind, enable)
       enum exception_event_kind kind;
*************** setup_target_debug ()
*** 2707,2712 ****
--- 2717,2723 ----
    current_target.to_thread_alive = debug_to_thread_alive;
    current_target.to_stop = debug_to_stop;
    current_target.to_query = debug_to_query;
+   current_target.to_rcmd = debug_to_rcmd;
    current_target.to_enable_exception_callback = debug_to_enable_exception_callback;
    current_target.to_get_current_exception_event = debug_to_get_current_exception_event;
    current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
*************** static char targ_desc[] =
*** 2720,2725 ****
--- 2731,2749 ----
  Shows the entire stack of targets currently in use (including the exec-file,\n\
  core-file, and process, if any), as well as the symbol file name.";
  
+ static void
+ do_monitor_command (char *cmd,
+ 		 int from_tty)
+ {
+   if ((current_target.to_rcmd == (void*) tcomplain)
+       || (current_target.to_rcmd == debug_to_rcmd
+ 	  && (debug_target.to_rcmd == (void*) tcomplain)))
+     {
+       error ("\"monitor\" command not supported by this target.\n");
+     }
+   target_rcmd (cmd, gdb_stdtarg);
+ }
+ 
  void
  initialize_targets ()
  {
*************** initialize_targets ()
*** 2735,2740 ****
--- 2759,2768 ----
  			     "Set target debugging.\n\
  When non-zero, target debugging is enabled.", &setlist),
  		      &showlist);
+ 
+ 
+   add_com ("monitor", class_obscure, do_monitor_command,
+ 	   "Send a command to the remote monitor (remote targets only).");
  
    if (!STREQ (signals[TARGET_SIGNAL_LAST].string, "TARGET_SIGNAL_MAGIC"))
      abort ();
Index: target.h
===================================================================
RCS file: /cvs/gdb/gdb/gdb/target.h,v
retrieving revision 1.1.1.6
diff -p -r1.1.1.6 target.h
*** target.h	1999/07/07 20:10:39	1.1.1.6
--- target.h	1999/08/05 08:28:19
*************** struct target_ops
*** 376,381 ****
--- 376,382 ----
      void (*to_find_new_threads) PARAMS ((void));
      void (*to_stop) PARAMS ((void));
      int (*to_query) PARAMS ((int /*char */ , char *, char *, int *));
+     void (*to_rcmd) (char *command, struct gdb_file *output);
      struct symtab_and_line *(*to_enable_exception_callback) PARAMS ((enum exception_event_kind, int));
      struct exception_event_record *(*to_get_current_exception_event) PARAMS ((void));
      char *(*to_pid_to_exec_file) PARAMS ((int pid));
*************** print_section_info PARAMS ((struct targe
*** 929,934 ****
--- 930,943 ----
  
  #define	target_query(query_type, query, resp_buffer, bufffer_size)	\
  	(*current_target.to_query) (query_type, query, resp_buffer, bufffer_size)
+ 
+ /* Send the specified COMMAND to the target's monitor
+    (shell,interpreter) for execution.  The result of the query is
+    placed in OUTBUF. */
+ 
+ #define target_rcmd(command, outbuf) \
+      (*current_target.to_rcmd) (command, outbuf)
+ 
  
  /* Get the symbol information for a breakpointable routine called when
     an exception event occurs. 
Index: doc/remote.texi
===================================================================
RCS file: /cvs/gdb/gdb/gdb/doc/remote.texi,v
retrieving revision 1.1.1.3
diff -p -r1.1.1.3 remote.texi
*** remote.texi	1999/06/28 16:02:16	1.1.1.3
--- remote.texi	1999/08/05 08:28:49
*************** See @code{remote.c:remote_unpack_thread_
*** 770,778 ****
  execution.  @emph{Implementors should note that providing access to a
  stubs's interpreter may have security implications}.
  @item
! @tab reply @var{OUTPUT}
  @tab
! The @var{OUTPUT} (hex encoded).  Must be non-empty.
  @item
  @tab reply @samp{}
  @tab
--- 770,781 ----
  execution.  @emph{Implementors should note that providing access to a
  stubs's interpreter may have security implications}.
  @item
! @tab reply @var{OUTPUT} or @var{OK}
  @tab
! The @var{OUTPUT} is the hex encoded output from the command.  @var{OK}
! is returned when the @var{OUTPUT} would have been empty.  The target may
! also respond with a number of intermediate @code{O}@var{OUTPUT} packets.
! 
  @item
  @tab reply @samp{}
  @tab


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]