[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/5] gdbstub: replace singlestep q packets with qRcm
From: |
Jason Wessel |
Subject: |
[Qemu-devel] [PATCH 1/5] gdbstub: replace singlestep q packets with qRcmd packets |
Date: |
Thu, 15 May 2008 09:11:29 -0500 |
At the gdbserial protocol level, using the qRcmd packets allows gdb to
use the "monitor" command to access the controls for single stepping
behavior. Now you can use a gdb "monitor" command instead of a gdb
"maintenance" command.
The qemu docs were updated to reflect this change.
Signed-off-by: Jason Wessel <address@hidden>
---
gdbstub.c | 82 +++++++++++++++++++++++++++++++++++++++++----------------
qemu-doc.texi | 34 +++++++++++------------
2 files changed, 75 insertions(+), 41 deletions(-)
diff --git a/gdbstub.c b/gdbstub.c
index 9a361e3..4bc7999 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -239,6 +239,27 @@ static int put_packet(GDBState *s, char *buf)
return 0;
}
+static void monitor_output(GDBState *s, const char *msg)
+{
+ char *buf;
+ int len = strlen(msg);
+
+ buf = malloc(len * 2 + 2);
+ buf[0] = 'O';
+ memtohex(buf + 1, msg, len);
+ put_packet(s, buf);
+ free(buf);
+}
+
+static void monitor_help(GDBState *s)
+{
+ monitor_output(s, "gdbstub specific monitor commands:\n");
+ monitor_output(s, "s_show -- Show gdbstub Single Stepping variables\n");
+ 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");
+}
+
#if defined(TARGET_I386)
#ifdef TARGET_X86_64
@@ -943,6 +964,42 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t
*mem_buf, int size)
#endif
+static void gdb_rcmd(GDBState *s, const char *p, char *buf, char *mem_buf)
+{
+ int len = strlen(p);
+
+ if ((len % 2) != 0) {
+ put_packet(s, "E01");
+ return;
+ }
+ hextomem(mem_buf, p, len);
+ mem_buf[(len >> 1)] = 0;
+
+ if (!strcmp(mem_buf, "s_show")) {
+ sprintf(buf, "s_step == %i\n", (sstep_flags & SSTEP_ENABLE) != 0);
+ monitor_output(s, buf);
+ sprintf(buf, "s_irq == %i\n", (sstep_flags & SSTEP_NOIRQ) == 0);
+ monitor_output(s, buf);
+ sprintf(buf, "s_timer == %i\n", (sstep_flags & SSTEP_NOTIMER) == 0);
+ monitor_output(s, buf);
+ } else if (!strcmp(mem_buf, "s_step 1")) {
+ sstep_flags |= SSTEP_ENABLE;
+ } else if (!strcmp(mem_buf, "s_step 0")) {
+ sstep_flags &= ~SSTEP_ENABLE;
+ } else if (!strcmp(mem_buf, "s_irq 1")) {
+ sstep_flags &= ~SSTEP_NOIRQ;
+ } else if (!strcmp(mem_buf, "s_irq 0")) {
+ sstep_flags |= SSTEP_NOIRQ;
+ } else if (!strcmp(mem_buf, "s_timer 1")) {
+ sstep_flags &= ~SSTEP_NOTIMER;
+ } else if (!strcmp(mem_buf, "s_timer 0")) {
+ sstep_flags |= SSTEP_NOTIMER;
+ } else if (!strcmp(mem_buf, "help") || !strcmp(mem_buf, "?")) {
+ monitor_help(s);
+ }
+ put_packet(s, "OK");
+}
+
static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
{
const char *p;
@@ -1113,29 +1170,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env,
const char *line_buf)
}
break;
case 'q':
- case 'Q':
- /* parse any 'q' packets here */
- if (!strcmp(p,"qemu.sstepbits")) {
- /* Query Breakpoint bit definitions */
- sprintf(buf,"ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
- SSTEP_ENABLE,
- SSTEP_NOIRQ,
- SSTEP_NOTIMER);
- put_packet(s, buf);
- break;
- } else if (strncmp(p,"qemu.sstep",10) == 0) {
- /* Display or change the sstep_flags */
- p += 10;
- if (*p != '=') {
- /* Display current setting */
- sprintf(buf,"0x%x", sstep_flags);
- put_packet(s, buf);
- break;
- }
- p++;
- type = strtoul(p, (char **)&p, 16);
- sstep_flags = type;
- put_packet(s, "OK");
+ if (!strncmp(p, "Rcmd,", 5)) {
+ gdb_rcmd(s, p + 5, buf, mem_buf);
break;
}
#ifdef CONFIG_LINUX_USER
diff --git a/qemu-doc.texi b/qemu-doc.texi
index cca483c..11c7058 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -1950,32 +1950,30 @@ Use @code{set architecture i8086} to dump 16 bit code.
Then use
Advanced debugging options:
-The default single stepping behavior is step with the IRQs and timer service
routines off. It is set this way because when gdb executes a single step it
expects to advance beyond the current instruction. With the IRQs and and timer
service routines on, a single step might jump into the one of the interrupt or
exception vectors instead of executing the current instruction. This means you
may hit the same breakpoint a number of times before executing the instruction
gdb wants to have executed. Because there are rare circumstances where you
want to single step into an interrupt vector the behavior can be controlled
from GDB. There are three commands you can query and set the single step
behavior:
+The default single stepping behavior is to step with the IRQs and timer
service routines off. It is set this way because when gdb executes a single
step it expects to advance beyond the current instruction. With the IRQs and
and timer service routines on, a single step might jump into the one of the
interrupt or exception vectors instead of executing the current instruction.
This means you may hit the same breakpoint a number of times before executing
the instruction gdb wants execute. Because there are rare circumstances where
you want to single step into an interrupt vector the behavior can be controlled
from GDB. There are several commands you use to query and set the single step
behavior while inside gdb:
@table @code
address@hidden maintenance packet qqemu.sstepbits
address@hidden monitor s_show
-This will display the MASK bits used to control the single stepping IE:
+This will display the values of the single stepping controls IE:
@example
-(gdb) maintenance packet qqemu.sstepbits
-sending: "qqemu.sstepbits"
-received: "ENABLE=1,NOIRQ=2,NOTIMER=4"
+(gdb) monitor s_show
+s_step == 1
+s_irq == 0
+s_timer == 0
@end example
address@hidden maintenance packet qqemu.sstep
address@hidden monitor s_step <0|1>
-This will display the current value of the mask used when single stepping IE:
+Turn off or on the single stepping feature all together, which is defaulted to
on.
@example
-(gdb) maintenance packet qqemu.sstep
-sending: "qqemu.sstep"
-received: "0x7"
+(gdb) monitor s_step 1
+(gdb) monitor s_step 0
@end example
address@hidden maintenance packet Qqemu.sstep=HEX_VALUE
address@hidden monitor s_irq <0|1>
-This will change the single step mask, so if wanted to enable IRQs on the
single step, but not timers, you would use:
address@hidden
-(gdb) maintenance packet Qqemu.sstep=0x5
-sending: "qemu.sstep=0x5"
-received: "OK"
address@hidden example
+Turn off or on the the irq processing when single stepping, which is defaulted
to off.
address@hidden monitor s_timer <0|1>
+
+Turn off or on the the timer processing when single stepping, which is
defaulted to off.
@end table
@node pcsys_os_specific
--
1.5.5.1
- [Qemu-devel] [PATCH 0/5] gdbstub and single step improvments, Jason Wessel, 2008/05/15
- [Qemu-devel] [PATCH 1/5] gdbstub: replace singlestep q packets with qRcmd packets,
Jason Wessel <=
- Re: [Qemu-devel] [PATCH 2/5] gdbstub: gdb pass-through qemu monitor support, Edgar E. Iglesias, 2008/05/15
- Re: [Qemu-devel] [PATCH 2/5] gdbstub: gdb pass-through qemu monitor support, Jason Wessel, 2008/05/19
- Re: [Qemu-devel] [PATCH 2/5] gdbstub: gdb pass-through qemu monitor support, Paul Brook, 2008/05/19
- Re: [Qemu-devel] [PATCH 2/5] gdbstub: gdb pass-through qemu monitor support, Maxim Gorbachyov, 2008/05/21
- Re: [Qemu-devel] [PATCH 2/5] gdbstub: gdb pass-through qemu monitor support, Jason Wessel, 2008/05/21