Commit 7d03f82f81e0e6c106ca0d2445a0fc49dc9ddc7b

Authored by edgar_igl
1 parent 6191b059

Add support for the 'k' (kill) and 'D' (detach) packets (Jason Wessel).

Implement the 'k' gdbserial packet which kills the qemu instance via
the debugger stub.

Implement the 'D' detach packet for the gdb stub such that you can
disconnect gdb with the "detach" command.  This required implementing
a cpu_breakpoint_remove_all() and a cpu_watchpoint_remove_all()
function to cleanup all the breakpoints and watchpoints prior to
leaving the gdb stub else simulation can stop with no debugger
attached.

On a '?' packet remove all the breakpoints and watchpoints.  This is
considered more of a safety net in case you force killed gdb or it
crashed and you are reconnecting.  The identical behavior exists for
kgdb in the linux kernel.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4478 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
@@ -760,8 +760,10 @@ void cpu_reset_interrupt(CPUState *env, int mask); @@ -760,8 +760,10 @@ void cpu_reset_interrupt(CPUState *env, int mask);
760 760
761 int cpu_watchpoint_insert(CPUState *env, target_ulong addr); 761 int cpu_watchpoint_insert(CPUState *env, target_ulong addr);
762 int cpu_watchpoint_remove(CPUState *env, target_ulong addr); 762 int cpu_watchpoint_remove(CPUState *env, target_ulong addr);
  763 +void cpu_watchpoint_remove_all(CPUState *env);
763 int cpu_breakpoint_insert(CPUState *env, target_ulong pc); 764 int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
764 int cpu_breakpoint_remove(CPUState *env, target_ulong pc); 765 int cpu_breakpoint_remove(CPUState *env, target_ulong pc);
  766 +void cpu_breakpoint_remove_all(CPUState *env);
765 767
766 #define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */ 768 #define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
767 #define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */ 769 #define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
@@ -1139,6 +1139,16 @@ int cpu_watchpoint_remove(CPUState *env, target_ulong addr) @@ -1139,6 +1139,16 @@ int cpu_watchpoint_remove(CPUState *env, target_ulong addr)
1139 return -1; 1139 return -1;
1140 } 1140 }
1141 1141
  1142 +/* Remove all watchpoints. */
  1143 +void cpu_watchpoint_remove_all(CPUState *env) {
  1144 + int i;
  1145 +
  1146 + for (i = 0; i < env->nb_watchpoints; i++) {
  1147 + tlb_flush_page(env, env->watchpoint[i].vaddr);
  1148 + }
  1149 + env->nb_watchpoints = 0;
  1150 +}
  1151 +
1142 /* add a breakpoint. EXCP_DEBUG is returned by the CPU loop if a 1152 /* add a breakpoint. EXCP_DEBUG is returned by the CPU loop if a
1143 breakpoint is reached */ 1153 breakpoint is reached */
1144 int cpu_breakpoint_insert(CPUState *env, target_ulong pc) 1154 int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
@@ -1162,6 +1172,17 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc) @@ -1162,6 +1172,17 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
1162 #endif 1172 #endif
1163 } 1173 }
1164 1174
  1175 +/* remove all breakpoints */
  1176 +void cpu_breakpoint_remove_all(CPUState *env) {
  1177 +#if defined(TARGET_HAS_ICE)
  1178 + int i;
  1179 + for(i = 0; i < env->nb_breakpoints; i++) {
  1180 + breakpoint_invalidate(env, env->breakpoints[i]);
  1181 + }
  1182 + env->nb_breakpoints = 0;
  1183 +#endif
  1184 +}
  1185 +
1165 /* remove a breakpoint */ 1186 /* remove a breakpoint */
1166 int cpu_breakpoint_remove(CPUState *env, target_ulong pc) 1187 int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
1167 { 1188 {
gdbstub.c
@@ -962,6 +962,12 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) @@ -962,6 +962,12 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
962 /* TODO: Make this return the correct value for user-mode. */ 962 /* TODO: Make this return the correct value for user-mode. */
963 snprintf(buf, sizeof(buf), "S%02x", SIGTRAP); 963 snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
964 put_packet(s, buf); 964 put_packet(s, buf);
  965 + /* Remove all the breakpoints when this query is issued,
  966 + * because gdb is doing and initial connect and the state
  967 + * should be cleaned up.
  968 + */
  969 + cpu_breakpoint_remove_all(env);
  970 + cpu_watchpoint_remove_all(env);
965 break; 971 break;
966 case 'c': 972 case 'c':
967 if (*p != '\0') { 973 if (*p != '\0') {
@@ -985,6 +991,17 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) @@ -985,6 +991,17 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
985 } 991 }
986 gdb_continue(s); 992 gdb_continue(s);
987 return RS_IDLE; 993 return RS_IDLE;
  994 + case 'k':
  995 + /* Kill the target */
  996 + fprintf(stderr, "\nQEMU: Terminated via GDBstub\n");
  997 + exit(0);
  998 + case 'D':
  999 + /* Detach packet */
  1000 + cpu_breakpoint_remove_all(env);
  1001 + cpu_watchpoint_remove_all(env);
  1002 + gdb_continue(s);
  1003 + put_packet(s, "OK");
  1004 + break;
988 case 's': 1005 case 's':
989 if (*p != '\0') { 1006 if (*p != '\0') {
990 addr = strtoull(p, (char **)&p, 16); 1007 addr = strtoull(p, (char **)&p, 16);