Page MenuHomeFreeBSD

D35473.id106868.diff
No OneTemporary

D35473.id106868.diff

Index: sys/gdb/gdb_int.h
===================================================================
--- sys/gdb/gdb_int.h
+++ sys/gdb/gdb_int.h
@@ -130,6 +130,13 @@
*gdb_txp++ = *s++;
}
+static __inline void
+gdb_tx_hexstr(const char *s)
+{
+ while (*s)
+ gdb_tx_hex(*s++, 2);
+}
+
static __inline void
gdb_tx_varhex(uintmax_t n)
{
Index: sys/gdb/gdb_main.c
===================================================================
--- sys/gdb/gdb_main.c
+++ sys/gdb/gdb_main.c
@@ -47,6 +47,10 @@
SYSCTL_NODE(_debug, OID_AUTO, gdb, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"GDB settings");
+static bool gdb_can_resume = false;
+SYSCTL_BOOL(_debug_gdb, OID_AUTO, can_resume, CTLFLAG_RWTUN, &gdb_can_resume,
+ 0, "GDB can resume execution");
+
static dbbe_init_f gdb_init;
static dbbe_trap_f gdb_trap;
@@ -608,7 +612,7 @@
gdb_cur->gdb_term();
#ifdef DDB
- if (!gdb_return_to_ddb)
+ if (!gdb_return_to_ddb && gdb_can_resume)
return;
gdb_return_to_ddb = false;
@@ -712,6 +716,48 @@
return;
}
+/*
+ * Send a T packet. We currently do not support watchpoints (the awatch,
+ * rwatch, or watch elements).
+ */
+static void
+gdb_tx_stop(int type, int code, bool full)
+{
+ gdb_tx_begin('T');
+ gdb_tx_hex(gdb_cpu_signal(type, code), 2);
+ if (full) {
+ gdb_tx_varhex(GDB_REG_PC);
+ gdb_tx_char(':');
+ gdb_tx_reg(GDB_REG_PC);
+ gdb_tx_char(';');
+ gdb_cpu_stop_reason(type, code);
+ }
+ gdb_tx_str("thread:");
+ gdb_tx_varhex((long)kdb_thread->td_tid);
+ gdb_tx_char(';');
+ gdb_tx_end(); /* XXX check error condition. */
+}
+
+static bool
+gdb_allow_resume(int type, int code)
+{
+ if (gdb_can_resume)
+ return (true);
+
+ gdb_tx_begin('O');
+ gdb_tx_hexstr("GDB is not allowed to resume execution.\n");
+ gdb_tx_hexstr("Detach and use DDB, or: set gdb_can_resume = 1\n");
+ gdb_tx_end();
+
+ /*
+ * A strict reading of the protocol spec does not allow an error reply.
+ * Tell GDB the target stopped in the same way as last time.
+ */
+ gdb_tx_stop(type, code, true);
+
+ return (false);
+}
+
static int
gdb_trap(int type, int code)
{
@@ -731,35 +777,18 @@
gdb_listening = 0;
gdb_ackmode = true;
- /*
- * Send a T packet. We currently do not support watchpoints (the
- * awatch, rwatch or watch elements).
- */
- gdb_tx_begin('T');
- gdb_tx_hex(gdb_cpu_signal(type, code), 2);
- gdb_tx_varhex(GDB_REG_PC);
- gdb_tx_char(':');
- gdb_tx_reg(GDB_REG_PC);
- gdb_tx_char(';');
- gdb_cpu_stop_reason(type, code);
- gdb_tx_str("thread:");
- gdb_tx_varhex((uintmax_t)kdb_thread->td_tid);
- gdb_tx_char(';');
- gdb_tx_end(); /* XXX check error condition. */
+ gdb_tx_stop(type, code, true);
thr_iter = NULL;
while (gdb_rx_begin() == 0) {
/* printf("GDB: got '%s'\n", gdb_rxp); */
switch (gdb_rx_char()) {
case '?': /* Last signal. */
- gdb_tx_begin('T');
- gdb_tx_hex(gdb_cpu_signal(type, code), 2);
- gdb_tx_str("thread:");
- gdb_tx_varhex((long)kdb_thread->td_tid);
- gdb_tx_char(';');
- gdb_tx_end();
+ gdb_tx_stop(type, code, false);
break;
case 'c': { /* Continue. */
+ if (!gdb_allow_resume(type, code))
+ break;
uintmax_t addr;
register_t pc;
if (!gdb_rx_varhex(&addr)) {
@@ -771,6 +800,8 @@
return (1);
}
case 'C': { /* Continue with signal. */
+ if (!gdb_allow_resume(type, code))
+ break;
uintmax_t addr, sig;
register_t pc;
if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' &&
@@ -929,6 +960,8 @@
gdb_tx_empty();
break;
case 's': { /* Step. */
+ if (!gdb_allow_resume(type, code))
+ break;
uintmax_t addr;
register_t pc;
if (!gdb_rx_varhex(&addr)) {
@@ -940,6 +973,8 @@
return (1);
}
case 'S': { /* Step with signal. */
+ if (!gdb_allow_resume(type, code))
+ break;
uintmax_t addr, sig;
register_t pc;
if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' &&

File Metadata

Mime Type
text/plain
Expires
Tue, Jun 16, 10:39 PM (17 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34005466
Default Alt Text
D35473.id106868.diff (3 KB)

Event Timeline