[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 07/22] GDB stub for reverse execution
From: |
Pavel Dovgaluk |
Subject: |
[Qemu-devel] [RFC PATCH 07/22] GDB stub for reverse execution |
Date: |
Tue, 1 Jul 2014 15:23:05 +0400 |
Adding support of reverse-stepi and reverse-contunue for gdb remote protocol.
Signed-off-by: Pavel Dovgalyuk <address@hidden>
---
diff --git a/gdbstub.c b/gdbstub.c
index 8afe0b7..ca71f38
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -40,6 +40,7 @@
#include "cpu.h"
#include "qemu/sockets.h"
#include "sysemu/kvm.h"
+#include "replay/replay.h"
static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
uint8_t *buf, int len, bool is_write)
@@ -313,6 +314,18 @@ typedef struct GDBState {
*/
static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
+/*! Retrieves flags for single step mode. */
+static int get_sstep_flags(void)
+{
+ /* In replay mode all events written into the log should be replayed.
+ * That is why NOIRQ flag is removed in this mode.
+ */
+ if (replay_mode != REPLAY_NONE)
+ return SSTEP_ENABLE /*| SSTEP_NOTIMER*/;
+ else
+ return sstep_flags;
+}
+
static GDBState *gdbserver_state;
bool gdb_has_xml;
@@ -835,7 +848,7 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
s->c_cpu = cpu;
}
if (res == 's') {
- cpu_single_step(s->c_cpu, sstep_flags);
+ cpu_single_step(s->c_cpu, get_sstep_flags());
}
s->signal = res_signal;
gdb_continue(s);
@@ -863,9 +876,29 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
addr = strtoull(p, (char **)&p, 16);
gdb_set_cpu_pc(s, addr);
}
- cpu_single_step(s->c_cpu, sstep_flags);
+ cpu_single_step(s->c_cpu, get_sstep_flags());
gdb_continue(s);
return RS_IDLE;
+ case 'b':
+ /* backward debugging commands */
+ if (replay_mode == REPLAY_PLAY
+ && replay_get_play_submode() == REPLAY_PLAY_NORMAL) {
+ switch (*p) {
+ case 's':
+ replay_reverse_step();
+ gdb_continue(s);
+ return RS_IDLE;
+ case 'c':
+ replay_reverse_continue();
+ gdb_continue(s);
+ return RS_IDLE;
+ default:
+ goto unknown_command;
+ }
+ } else {
+ put_packet (s, "E22");
+ }
+ goto unknown_command;
case 'F':
{
target_ulong ret;
@@ -912,6 +945,7 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
len -= reg_size;
registers += reg_size;
}
+ replay_set_play_changed();
put_packet(s, "OK");
break;
case 'm':
@@ -938,6 +972,7 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
true) != 0) {
put_packet(s, "E14");
} else {
+ replay_set_play_changed();
put_packet(s, "OK");
}
break;
@@ -965,6 +1000,7 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
reg_size = strlen(p) / 2;
hextomem(mem_buf, p, reg_size);
gdb_write_register(s->g_cpu, mem_buf, addr);
+ replay_set_play_changed();
put_packet(s, "OK");
break;
case 'Z':
@@ -1035,18 +1071,23 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
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 */
- snprintf(buf, sizeof(buf), "0x%x", sstep_flags);
- put_packet(s, buf);
- break;
+ if (replay_mode == REPLAY_NONE) {
+ /* Display or change the sstep_flags */
+ p += 10;
+ if (*p != '=') {
+ /* Display current setting */
+ snprintf(buf, sizeof(buf), "0x%x", sstep_flags);
+ put_packet(s, buf);
+ break;
+ }
+ p++;
+ type = strtoul(p, (char **)&p, 16);
+ sstep_flags = type;
+ put_packet(s, "OK");
+ } else {
+ /* Cannot change sstep flags in replay mode */
+ put_packet(s, "E22");
}
- p++;
- type = strtoul(p, (char **)&p, 16);
- sstep_flags = type;
- put_packet(s, "OK");
break;
} else if (strcmp(p,"C") == 0) {
/* "Current thread" remains vague in the spec, so always return
@@ -1113,6 +1154,9 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
if (cc->gdb_core_xml_file != NULL) {
pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
}
+ if (replay_mode == REPLAY_PLAY) {
+ pstrcat(buf, sizeof(buf), ";ReverseStep+;ReverseContinue+");
+ }
put_packet(s, buf);
break;
}
@@ -1174,8 +1218,13 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
void gdb_set_stop_cpu(CPUState *cpu)
{
- gdbserver_state->c_cpu = cpu;
- gdbserver_state->g_cpu = cpu;
+ /* DEBUG interrupts are also used by replay module.
+ In some cases gdb is not connected, when replay is used.
+ This check is added to prevent faults in such cases. */
+ if (gdbserver_state) {
+ gdbserver_state->c_cpu = cpu;
+ gdbserver_state->g_cpu = cpu;
+ }
}
#ifndef CONFIG_USER_ONLY
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [RFC PATCH 07/22] GDB stub for reverse execution,
Pavel Dovgaluk <=