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 762 int cpu_watchpoint_remove(CPUState *env, target_ulong addr);
763 763 int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
764 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 770 void cpu_single_step(CPUState *env, int enabled);
766 771 void cpu_reset(CPUState *s);
767 772  
... ...
cpu-exec.c
... ... @@ -421,7 +421,7 @@ int cpu_exec(CPUState *env1)
421 421 #if defined(TARGET_I386)
422 422 && env->hflags & HF_GIF_MASK
423 423 #endif
424   - ) {
  424 + && !(env->singlestep_enabled & SSTEP_NOIRQ)) {
425 425 if (interrupt_request & CPU_INTERRUPT_DEBUG) {
426 426 env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
427 427 env->exception_index = EXCP_DEBUG;
... ...
gdbstub.c
... ... @@ -73,6 +73,11 @@ typedef struct GDBState {
73 73 #endif
74 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 81 #ifdef CONFIG_USER_ONLY
77 82 /* XXX: This is not thread safe. Do we care? */
78 83 static int gdbserver_fd = -1;
... ... @@ -1072,7 +1077,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1072 1077 env->pc = addr;
1073 1078 #endif
1074 1079 }
1075   - cpu_single_step(env, 1);
  1080 + cpu_single_step(env, sstep_flags);
1076 1081 gdb_continue(s);
1077 1082 return RS_IDLE;
1078 1083 case 'F':
... ... @@ -1179,9 +1184,34 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1179 1184 goto breakpoint_error;
1180 1185 }
1181 1186 break;
1182   -#ifdef CONFIG_LINUX_USER
1183 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 1215 TaskState *ts = env->opaque;
1186 1216  
1187 1217 sprintf(buf,
... ... @@ -1193,10 +1223,9 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1193 1223 put_packet(s, buf);
1194 1224 break;
1195 1225 }
1196   - /* Fall through. */
1197 1226 #endif
  1227 + /* Fall through. */
1198 1228 default:
1199   - // unknown_command:
1200 1229 /* put empty packet */
1201 1230 buf[0] = '\0';
1202 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 1948 @code{x/10i $cs*16+$eip} to dump the code at the PC position.
1949 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 1981 @node pcsys_os_specific
1952 1982 @section Target OS specific information
1953 1983  
... ...