Commit 60897d369f10b464720d8a6de4553c47943ea927

Authored by edgar_igl
1 parent c5841166

Debugger single step without interrupts (Jason Wessel).

This patch allows the qemu backend debugger to single step an
instruction without running the hardware interrupts.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4391 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
@@ -762,6 +762,11 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong addr); @@ -762,6 +762,11 @@ 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 int cpu_breakpoint_insert(CPUState *env, target_ulong pc); 763 int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
764 int cpu_breakpoint_remove(CPUState *env, target_ulong pc); 764 int cpu_breakpoint_remove(CPUState *env, target_ulong pc);
  765 +
  766 +#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
  767 +#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
  768 +#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */
  769 +
765 void cpu_single_step(CPUState *env, int enabled); 770 void cpu_single_step(CPUState *env, int enabled);
766 void cpu_reset(CPUState *s); 771 void cpu_reset(CPUState *s);
767 772
cpu-exec.c
@@ -421,7 +421,7 @@ int cpu_exec(CPUState *env1) @@ -421,7 +421,7 @@ int cpu_exec(CPUState *env1)
421 #if defined(TARGET_I386) 421 #if defined(TARGET_I386)
422 && env->hflags & HF_GIF_MASK 422 && env->hflags & HF_GIF_MASK
423 #endif 423 #endif
424 - ) { 424 + && !(env->singlestep_enabled & SSTEP_NOIRQ)) {
425 if (interrupt_request & CPU_INTERRUPT_DEBUG) { 425 if (interrupt_request & CPU_INTERRUPT_DEBUG) {
426 env->interrupt_request &= ~CPU_INTERRUPT_DEBUG; 426 env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
427 env->exception_index = EXCP_DEBUG; 427 env->exception_index = EXCP_DEBUG;
gdbstub.c
@@ -73,6 +73,11 @@ typedef struct GDBState { @@ -73,6 +73,11 @@ typedef struct GDBState {
73 #endif 73 #endif
74 } GDBState; 74 } GDBState;
75 75
  76 +/* By default use no IRQs and no timers while single stepping so as to
  77 + * make single stepping like an ICE HW step.
  78 + */
  79 +static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
  80 +
76 #ifdef CONFIG_USER_ONLY 81 #ifdef CONFIG_USER_ONLY
77 /* XXX: This is not thread safe. Do we care? */ 82 /* XXX: This is not thread safe. Do we care? */
78 static int gdbserver_fd = -1; 83 static int gdbserver_fd = -1;
@@ -1072,7 +1077,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) @@ -1072,7 +1077,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1072 env->pc = addr; 1077 env->pc = addr;
1073 #endif 1078 #endif
1074 } 1079 }
1075 - cpu_single_step(env, 1); 1080 + cpu_single_step(env, sstep_flags);
1076 gdb_continue(s); 1081 gdb_continue(s);
1077 return RS_IDLE; 1082 return RS_IDLE;
1078 case 'F': 1083 case 'F':
@@ -1179,9 +1184,34 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) @@ -1179,9 +1184,34 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1179 goto breakpoint_error; 1184 goto breakpoint_error;
1180 } 1185 }
1181 break; 1186 break;
1182 -#ifdef CONFIG_LINUX_USER  
1183 case 'q': 1187 case 'q':
1184 - if (strncmp(p, "Offsets", 7) == 0) { 1188 + case 'Q':
  1189 + /* parse any 'q' packets here */
  1190 + if (!strcmp(p,"qemu.sstepbits")) {
  1191 + /* Query Breakpoint bit definitions */
  1192 + sprintf(buf,"ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
  1193 + SSTEP_ENABLE,
  1194 + SSTEP_NOIRQ,
  1195 + SSTEP_NOTIMER);
  1196 + put_packet(s, buf);
  1197 + break;
  1198 + } else if (strncmp(p,"qemu.sstep",10) == 0) {
  1199 + /* Display or change the sstep_flags */
  1200 + p += 10;
  1201 + if (*p != '=') {
  1202 + /* Display current setting */
  1203 + sprintf(buf,"0x%x", sstep_flags);
  1204 + put_packet(s, buf);
  1205 + break;
  1206 + }
  1207 + p++;
  1208 + type = strtoul(p, (char **)&p, 16);
  1209 + sstep_flags = type;
  1210 + put_packet(s, "OK");
  1211 + break;
  1212 + }
  1213 +#ifdef CONFIG_LINUX_USER
  1214 + else if (strncmp(p, "Offsets", 7) == 0) {
1185 TaskState *ts = env->opaque; 1215 TaskState *ts = env->opaque;
1186 1216
1187 sprintf(buf, 1217 sprintf(buf,
@@ -1193,10 +1223,9 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) @@ -1193,10 +1223,9 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1193 put_packet(s, buf); 1223 put_packet(s, buf);
1194 break; 1224 break;
1195 } 1225 }
1196 - /* Fall through. */  
1197 #endif 1226 #endif
  1227 + /* Fall through. */
1198 default: 1228 default:
1199 - // unknown_command:  
1200 /* put empty packet */ 1229 /* put empty packet */
1201 buf[0] = '\0'; 1230 buf[0] = '\0';
1202 put_packet(s, buf); 1231 put_packet(s, buf);
qemu-doc.texi
@@ -1948,6 +1948,36 @@ Use @code{set architecture i8086} to dump 16 bit code. Then use @@ -1948,6 +1948,36 @@ Use @code{set architecture i8086} to dump 16 bit code. Then use
1948 @code{x/10i $cs*16+$eip} to dump the code at the PC position. 1948 @code{x/10i $cs*16+$eip} to dump the code at the PC position.
1949 @end enumerate 1949 @end enumerate
1950 1950
  1951 +Advanced debugging options:
  1952 +
  1953 +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:
  1954 +@enumerate @code
  1955 +@item maintenance packet qqemu.sstepbits
  1956 +
  1957 +This will display the MASK bits used to control the single stepping IE:
  1958 +@example
  1959 +(gdb) maintenance packet qqemu.sstepbits
  1960 +sending: "qqemu.sstepbits"
  1961 +received: "ENABLE=1,NOIRQ=2,NOTIMER=4"
  1962 +@end example
  1963 +@item maintenance packet qqemu.sstep
  1964 +
  1965 +This will display the current value of the mask used when single stepping IE:
  1966 +@example
  1967 +(gdb) maintenance packet qqemu.sstep
  1968 +sending: "qqemu.sstep"
  1969 +received: "0x7"
  1970 +@end example
  1971 +@item maintenance packet Qqemu.sstep=HEX_VALUE
  1972 +
  1973 +This will change the single step mask, so if wanted to enable IRQs on the single step, but not timers, you would use:
  1974 +@example
  1975 +(gdb) maintenance packet Qqemu.sstep=0x5
  1976 +sending: "qemu.sstep=0x5"
  1977 +received: "OK"
  1978 +@end example
  1979 +@end enumerate
  1980 +
1951 @node pcsys_os_specific 1981 @node pcsys_os_specific
1952 @section Target OS specific information 1982 @section Target OS specific information
1953 1983