Hello, This patch makes it possible to debug signal handlers when simulating programs in user-mode. Without it, the session aborts as soon as a signal is delivered.
On CRIS I still cannot get GDB to unwind the stack beyond the signals return trampoline, but I'm pretty sure it's related to some error in the way I setup the trampoline in linux-user/signal.c. Tested on ARM and CRIS. Comments? Ok to check it in? Best regards -- Edgar E. Iglesias Axis Communications AB Index: gdbstub.c =================================================================== RCS file: /sources/qemu/qemu/gdbstub.c,v retrieving revision 1.75 diff -u -p -b -u -p -r1.75 gdbstub.c --- gdbstub.c 28 Feb 2008 08:28:31 -0000 1.75 +++ gdbstub.c 28 Feb 2008 17:15:33 -0000 @@ -65,6 +65,7 @@ typedef struct GDBState { int line_csum; uint8_t last_packet[4100]; int last_packet_len; + int signal; #ifdef CONFIG_USER_ONLY int fd; int running_state; @@ -121,6 +122,16 @@ int use_gdb_syscalls(void) return gdb_syscall_mode == GDB_SYS_ENABLED; } +/* Resume execution. */ +static inline void gdb_continue(GDBState *s) +{ +#ifdef CONFIG_USER_ONLY + s->running_state = 1; +#else + vm_start(); +#endif +} + static void put_buffer(GDBState *s, const uint8_t *buf, int len) { #ifdef CONFIG_USER_ONLY @@ -908,11 +919,11 @@ static int gdb_handle_packet(GDBState *s env->pc = addr; #endif } -#ifdef CONFIG_USER_ONLY - s->running_state = 1; -#else - vm_start(); -#endif + gdb_continue(s); + return RS_IDLE; + case 'C': + s->signal = strtoul(p, (char **)&p, 16); + gdb_continue(s); return RS_IDLE; case 's': if (*p != '\0') { @@ -935,11 +946,7 @@ static int gdb_handle_packet(GDBState *s #endif } cpu_single_step(env, 1); -#ifdef CONFIG_USER_ONLY - s->running_state = 1; -#else - vm_start(); -#endif + gdb_continue(s); return RS_IDLE; case 'F': { @@ -961,11 +968,7 @@ static int gdb_handle_packet(GDBState *s if (type == 'C') { put_packet(s, "T02"); } else { -#ifdef CONFIG_USER_ONLY - s->running_state = 1; -#else - vm_start(); -#endif + gdb_continue(s); } } break; @@ -1294,6 +1297,8 @@ gdb_handlesig (CPUState *env, int sig) return sig; } } + sig = s->signal; + s->signal = 0; return sig; }