qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Jason Wessel <jason.wessel@windriver.com>
To: "Edgar E. Iglesias" <edgar.iglesias@axis.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 2/5] gdbstub: gdb pass-through qemu	monitor support
Date: Mon, 19 May 2008 08:29:17 -0500	[thread overview]
Message-ID: <483180AD.40704@windriver.com> (raw)
In-Reply-To: <20080515221716.GC27300@edgar.se.axis.com>

[-- Attachment #1: Type: text/plain, Size: 1227 bytes --]

Edgar E. Iglesias wrote:
> On Thu, May 15, 2008 at 09:11:30AM -0500, Jason Wessel wrote:
>   
>> This patch adds a feature to the gdbstub to allow gdb to issue monitor
>> commands that can pass-through to the qemu monitor.
>>
>>     
>>  
>> +static void monitor_output(GDBState *s, const char *msg)
>> +{
>> +    monitor_output_len(s, msg, 0);
>> +}
>> +
>>     
>
>
> If you change the zero argument into a strlen(msg) you can drop the check in monitor_output_len().
>
>
>   

Sure.  That seems reasonable.

>>  static void monitor_help(GDBState *s)
>>  {
>>      monitor_output(s, "gdbstub specific monitor commands:\n");
>> @@ -258,6 +267,7 @@ static void monitor_help(GDBState *s)
>>      monitor_output(s, "set s_step <0|1> -- Single Stepping enabled\n");
>>      monitor_output(s, "set s_irq <0|1> --  Single Stepping with qemu irq handlers enabled\n");
>>      monitor_output(s, "set s_timer <0|1> -- Single Stepping with qemu timers enabled\n");
>> +    monitor_output(s, "qemu monitor pass-through commands:\n");
>>  }
>>     
>
>   

Seems reasonable too, see newly attached patch.

Obviously you need the new monitor patch applied prior to this one. 
This patch was updated against the prior patch.

Thanks,
Jason.

[-- Attachment #2: gdb_monitor_plus_qemu_monitor.patch --]
[-- Type: text/x-diff, Size: 6329 bytes --]

From: Jason Wessel <jason.wessel@windriver.com>
Subject: [PATCH] gdbstub: gdb pass-through qemu monitor support

This patch adds a feature to the gdbstub to allow gdb to issue monitor
commands that can pass-through to the qemu monitor.  

In order to make this work, the MAX_MON (the maximum number of monitor
connections) had to get incremented by 1 to support the case when the
gdbstub is setup along with all the other connections.  A small check
was added avoid strange crashes when you allocate too many qemu
monitor connections.

The monitor_handle_command had to be exported in order to allow
gdbstub to pass the strings directly to the monitor.  The gdbstub
registers as an output device of the qemu monitor such that no further
changes were needed to the monitor other than to have a global
variable in the gdbstub that controls when to transmit data from a
pass through monitor command to an attached debugger.

The qemu docs were updated to reflect this change.

Signed-off-by: Jason Wessel <jason.wessel@windriver.com>

---
 console.h     |    1 +
 gdbstub.c     |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 monitor.c     |    8 ++++++--
 qemu-doc.texi |   11 +++++++++++
 4 files changed, 74 insertions(+), 4 deletions(-)

--- a/gdbstub.c
+++ b/gdbstub.c
@@ -33,6 +33,7 @@
 #include "qemu-char.h"
 #include "sysemu.h"
 #include "gdbstub.h"
+#include "console.h"
 #endif
 
 #include "qemu_socket.h"
@@ -71,6 +72,8 @@ typedef struct GDBState {
     int running_state;
 #else
     CharDriverState *chr;
+    CharDriverState *mon;
+    int allow_monitor;
 #endif
 } GDBState;
 
@@ -260,6 +263,11 @@ static void monitor_output(GDBState *s, 
     put_packet_hex(s, msg, strlen(msg), 1);
 }
 
+static void monitor_output_len(GDBState *s, const char *msg, int len)
+{
+    put_packet_hex(s, msg, len, 1);
+}
+
 static void monitor_help(GDBState *s)
 {
     monitor_output(s, "gdbstub specific monitor commands:\n");
@@ -267,6 +275,10 @@ static void monitor_help(GDBState *s)
     monitor_output(s, "set sstep <0|1> -- Single Stepping enabled\n");
     monitor_output(s, "set sirq <0|1> --  Single Stepping with qemu irq handlers enabled\n");
     monitor_output(s, "set stimers <0|1> -- Single Stepping with qemu timers enabled\n");
+#ifndef CONFIG_USER_ONLY
+    monitor_output(s, "qemu monitor pass-through commands:\n");
+#endif
+
 }
 
 #if defined(TARGET_I386)
@@ -1005,8 +1017,14 @@ static void gdb_rcmd(GDBState *s, const 
         sstep_flags &= ~SSTEP_NOTIMER;
     } else if (!strcmp(mem_buf, "set stimers 0")) {
         sstep_flags |= SSTEP_NOTIMER;
-    } else if (!strcmp(mem_buf, "help") || !strcmp(mem_buf, "?")) {
-        monitor_help(s);
+    } else {
+        if (!strcmp(mem_buf, "help") || !strcmp(mem_buf, "?"))
+            monitor_help(s);
+#ifndef CONFIG_USER_ONLY
+        s->allow_monitor = 1;
+        monitor_handle_command(mem_buf);
+        s->allow_monitor = 0;
+#endif
     }
     put_packet(s, "OK");
 }
@@ -1572,6 +1590,39 @@ static void gdb_chr_event(void *opaque, 
     }
 }
 
+static int gdb_mon_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    int max_sz;
+    const uint8_t *p = buf;
+    GDBState *s = chr->opaque;
+
+    if (s->allow_monitor) {
+        max_sz = (sizeof(s->last_packet) - 2) / 2;
+        for (;;) {
+            if (len <= max_sz) {
+                monitor_output_len(s, p, len);
+                break;
+            }
+            monitor_output_len(s, p, max_sz);
+            p += max_sz;
+            len -= max_sz;
+        }
+    }
+    return len;
+}
+
+static CharDriverState *qemu_chr_open_gdb_mon(GDBState *s)
+{
+    CharDriverState *chr;
+
+    chr = qemu_mallocz(sizeof(CharDriverState));
+    if (!chr)
+        return NULL;
+    chr->chr_write = gdb_mon_chr_write;
+    chr->opaque = s;
+    return chr;
+}
+
 int gdbserver_start(const char *port)
 {
     GDBState *s;
@@ -1604,6 +1655,9 @@ int gdbserver_start(const char *port)
     qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
                           gdb_chr_event, s);
     qemu_add_vm_stop_handler(gdb_vm_stopped, s);
+    /* Initialize a monitor port for gdb */
+    s->mon = qemu_chr_open_gdb_mon(s);
+    monitor_init(s->mon, 0);
     return 0;
 }
 #endif
--- a/monitor.c
+++ b/monitor.c
@@ -69,7 +69,7 @@ typedef struct term_cmd_t {
     const char *help;
 } term_cmd_t;
 
-#define MAX_MON 4
+#define MAX_MON 5
 static CharDriverState *monitor_hd[MAX_MON];
 static int hide_banner;
 
@@ -2096,7 +2096,7 @@ static int default_fmt_size = 4;
 
 #define MAX_ARGS 16
 
-static void monitor_handle_command(const char *cmdline)
+void monitor_handle_command(const char *cmdline)
 {
     const char *p, *pstart, *typestr;
     char *q;
@@ -2649,6 +2649,10 @@ void monitor_init(CharDriverState *hd, i
             break;
         }
     }
+    if (i >= MAX_MON) {
+        fprintf(stderr, "ERROR too many monitor connections requested\n");
+        exit(0);
+    }
 
     hide_banner = !show_banner;
 
--- a/console.h
+++ b/console.h
@@ -159,6 +159,7 @@ extern uint8_t _translate_keycode(const 
    does not need to include console.h  */
 /* monitor.c */
 void monitor_init(CharDriverState *hd, int show_banner);
+void monitor_handle_command(const char *cmdline);
 void term_puts(const char *str);
 void term_vprintf(const char *fmt, va_list ap);
 void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -1979,6 +1979,17 @@ Turn off or on the the irq processing wh
 Turn off or on the the timer processing when single stepping, which is defaulted to off.
 @end table
 
+You may also use gdb to send pass-through monitor commands to the qemu monitor.  It is easiest to start off with using just using @code{monitor help} to display the list of commands in available from the monitor.  Then you can prefix the @code{monitor} key word prior to any command.  The example below shows the use of the qemu monitor's @code{info pci} command.
+
+@example
+(gdb) monitor info pci
+  Bus  0, device   0, function 0:
+    Host bridge: PCI device 1057:4801
+  Bus  0, device   1, function 0:
+    VGA controller: PCI device 1234:1111
+      BAR0: 32 bit memory at 0xf0000000 [0xf07fffff].
+@end example
+
 @node pcsys_os_specific
 @section Target OS specific information
 

  reply	other threads:[~2008-05-19 13:29 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-15 14:11 [Qemu-devel] [PATCH 0/5] gdbstub and single step improvments Jason Wessel
2008-05-15 14:11 ` [Qemu-devel] [PATCH 1/5] gdbstub: replace singlestep q packets with qRcmd packets Jason Wessel
2008-05-15 14:11   ` [Qemu-devel] [PATCH 2/5] gdbstub: gdb pass-through qemu monitor support Jason Wessel
2008-05-15 14:11     ` [Qemu-devel] [PATCH 3/5] vl.c: always run the real time timers when single stepping Jason Wessel
2008-05-15 14:11       ` [Qemu-devel] [PATCH 4/5] gdbstub: support for gdb "detach/kill/quit" Jason Wessel
2008-05-15 14:11         ` [Qemu-devel] [PATCH 5/5] ppc: fix crash in ppc system single step support Jason Wessel
2008-05-15 21:13         ` [Qemu-devel] [PATCH 4/5] gdbstub: support for gdb "detach/kill/quit" Edgar E. Iglesias
2008-05-15 22:17     ` [Qemu-devel] [PATCH 2/5] gdbstub: gdb pass-through qemu monitor support Edgar E. Iglesias
2008-05-19 13:29       ` Jason Wessel [this message]
2008-05-19 16:30         ` Paul Brook
2008-05-21 12:58         ` Maxim Gorbachyov
2008-05-21 17:03           ` Jason Wessel
2008-05-22 13:24             ` [Qemu-devel] " Jan Kiszka
2008-05-22 13:45               ` Jason Wessel
2008-05-22 13:53                 ` Jan Kiszka
2008-05-22 16:55                   ` Jason Wessel
2008-05-23 15:33                     ` Jan Kiszka
2008-05-15 21:33   ` [Qemu-devel] [PATCH 1/5] gdbstub: replace singlestep q packets with qRcmd packets Edgar E. Iglesias
2008-05-19 13:27     ` Jason Wessel
2008-05-19 15:14       ` Edgar E. Iglesias

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=483180AD.40704@windriver.com \
    --to=jason.wessel@windriver.com \
    --cc=edgar.iglesias@axis.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).