Skip to contentSkip to conversation

Add single stepping option for all targets

PATCH Applied Stefan Weil 5 participants 16 messages Dec 20, 2008 – Apr 5, 2009

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Add single stepping option for all targets

This patch replaces the compile time options SH4_SINGLE_STEP, DO_SINGLE_STEP and MIPS_SINGLE_STEP
by a command line option -singlestep.

It also adds single step mode for targets which did not have a compile time option,
so all system emulations can be used with -singlestep. Please note that I did only
run a short test for i386 and mips targets.

A new monitor command is provided to enable or disable single step mode. The monitor command "info status" was modified to display single step mode when activated.

Single stepping in Qemu's system emulation mode is useful to see the cpu state
for each cpu instruction when used with -d in_asm,cpu. It is also a simple way to
slow down the emulation.

The patch does not add single step mode for Qemu's user mode emulation. Would this be useful, too?

Kind regards
Stefan Weil

Add new command line option for tcg single stepping.
This replaces a compile time options for some targets
and adds this feature to targets which did not have a compile time option.

Add monitor command to enable or disable single step mode.

Modify monitor command "info status" to display single step mode.

target-sh4/translate.c +5 -10
Index: trunk/target-sh4/translate.c
===================================================================
@@ -17,22 +17,18 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
+
 #include <assert.h>
 
 #define DEBUG_DISAS
 #define SH4_DEBUG_DISAS
-//#define SH4_SINGLE_STEP
 
+#include "qemu-common.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "sysemu.h"
 #include "tcg-op.h"
-#include "qemu-common.h"
 
 #include "helper.h"
 #define GEN_HELPER 1
@@ -1882,9 +1878,8 @@
 	    break;
         if (num_insns >= max_insns)
             break;
-#ifdef SH4_SINGLE_STEP
-	break;
-#endif
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-cris/translate.c +3 -6
Index: trunk/target-cris/translate.c
===================================================================
@@ -24,20 +24,16 @@
  * The condition code translation is in need of attention.
  */
 
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
 #include <assert.h>
 
+#include "qemu-common.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "sysemu.h"
 #include "tcg-op.h"
 #include "helper.h"
 #include "crisv32-decode.h"
-#include "qemu-common.h"
 
 #define GEN_HELPER 1
 #include "helper.h"
@@ -3379,6 +3375,7 @@
 			break;
 	} while (!dc->is_jmp && !dc->cpustate_changed
 		 && gen_opc_ptr < gen_opc_end
+		 && !vm_singlestep
 		 && (dc->pc < next_page_start)
                  && num_insns < max_insns);
 
target-alpha/translate.c +5 -10
Index: trunk/target-alpha/translate.c
===================================================================
@@ -18,22 +18,18 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-
+#include "qemu-common.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "host-utils.h"
+#include "sysemu.h"
 #include "tcg-op.h"
-#include "qemu-common.h"
 
 #include "helper.h"
 #define GEN_HELPER 1
 #include "helper.h"
 
-/* #define DO_SINGLE_STEP */
 #define ALPHA_DEBUG_DISAS
 /* #define DO_TB_FLUSH */
 
@@ -2414,11 +2410,10 @@
         if (env->singlestep_enabled) {
             gen_excp(&ctx, EXCP_DEBUG, 0);
             break;
-	}
+        }
 
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+        if (vm_singlestep)
+            break;
     }
     if (ret != 1 && ret != 3) {
         tcg_gen_movi_i64(cpu_pc, ctx.pc);
linux-user/main.c +7 -1
Index: trunk/linux-user/main.c
===================================================================
@@ -2271,6 +2271,8 @@
             }
             cpu_set_log(mask);
         } else if (!strcmp(r, "s")) {
+            if (optind >= argc)
+                break;
             r = argv[optind++];
             x86_stack_size = strtol(r, (char **)&r, 0);
             if (x86_stack_size <= 0)
@@ -2282,6 +2284,8 @@
         } else if (!strcmp(r, "L")) {
             interp_prefix = argv[optind++];
         } else if (!strcmp(r, "p")) {
+            if (optind >= argc)
+                break;
             qemu_host_page_size = atoi(argv[optind++]);
             if (qemu_host_page_size == 0 ||
                 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
@@ -2289,12 +2293,14 @@
                 exit(1);
             }
         } else if (!strcmp(r, "g")) {
+            if (optind >= argc)
+                break;
             gdbstub_port = atoi(argv[optind++]);
 	} else if (!strcmp(r, "r")) {
 	    qemu_uname_release = argv[optind++];
         } else if (!strcmp(r, "cpu")) {
             cpu_model = argv[optind++];
-            if (strcmp(cpu_model, "?") == 0) {
+            if (cpu_model == NULL || strcmp(cpu_model, "?") == 0) {
 /* XXX: implement xxx_cpu_list for targets that still miss it */
 #if defined(cpu_list)
                     cpu_list(stdout, &fprintf);
vl.c +7 -0
Index: trunk/vl.c
===================================================================
@@ -189,6 +189,7 @@
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int vm_running;
+int vm_singlestep;
 static int rtc_utc = 1;
 static int rtc_date_offset = -1; /* -1 means no change */
 int cirrus_vga_enabled = 1;
@@ -3933,6 +3934,7 @@
            "-serial dev     redirect the serial port to char device 'dev'\n"
            "-parallel dev   redirect the parallel port to char device 'dev'\n"
            "-pidfile file   Write PID to 'file'\n"
+           "-singlestep     always run in singlestep mode\n"
            "-S              freeze CPU at startup (use 'c' to start execution)\n"
            "-s              wait gdb connection to port\n"
            "-p port         set gdb connection port [default=%s]\n"
@@ -4031,6 +4033,7 @@
     QEMU_OPTION_append,
     QEMU_OPTION_initrd,
 
+    QEMU_OPTION_singlestep,
     QEMU_OPTION_S,
     QEMU_OPTION_s,
     QEMU_OPTION_p,
@@ -4132,6 +4135,7 @@
     { "append", HAS_ARG, QEMU_OPTION_append },
     { "initrd", HAS_ARG, QEMU_OPTION_initrd },
 
+    { "singlestep", 0, QEMU_OPTION_singlestep },
     { "S", 0, QEMU_OPTION_S },
     { "s", 0, QEMU_OPTION_s },
     { "p", HAS_ARG, QEMU_OPTION_p },
@@ -4874,6 +4878,9 @@
             case QEMU_OPTION_bios:
                 bios_name = optarg;
                 break;
+            case QEMU_OPTION_singlestep:
+                vm_singlestep = 1;
+                break;
             case QEMU_OPTION_S:
                 autostart = 0;
                 break;
target-ppc/translate.c +5 -10
Index: trunk/target-ppc/translate.c
===================================================================
@@ -17,17 +17,13 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
 
+#include "qemu-common.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "sysemu.h"
 #include "tcg-op.h"
-#include "qemu-common.h"
 
 #include "helper.h"
 #define GEN_HELPER 1
@@ -38,7 +34,6 @@
 #define GDBSTUB_SINGLE_STEP 0x4
 
 /* Include definitions for instructions classes and implementations flags */
-//#define DO_SINGLE_STEP
 //#define PPC_DEBUG_DISAS
 //#define DO_PPC_STATISTICS
 
@@ -7902,9 +7897,9 @@
              */
             break;
         }
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-mips/translate.c +5 -11
Index: trunk/target-mips/translate.c
===================================================================
@@ -20,17 +20,12 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
+#include "qemu-common.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "sysemu.h"
 #include "tcg-op.h"
-#include "qemu-common.h"
 
 #include "helper.h"
 #define GEN_HELPER 1
@@ -38,7 +33,6 @@
 
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS
-//#define MIPS_SINGLE_STEP
 
 /* MIPS major opcodes */
 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
@@ -8330,9 +8324,9 @@
 
         if (num_insns >= max_insns)
             break;
-#if defined (MIPS_SINGLE_STEP)
-        break;
-#endif
+
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
monitor.c +21 -3
Index: trunk/monitor.c
===================================================================
@@ -489,6 +489,18 @@
     cpu_set_log(mask);
 }
 
+static void do_singlestep(const char *option)
+{
+    qemu_printf("setting vm_singlestep to %s\n", option);
+    if (!option) {
+        vm_singlestep = 1;
+    } else if (!strcmp(option, "off")) {
+        vm_singlestep = 0;
+    } else {
+        term_printf("unexpected option %s\n", option);
+    }
+}
+
 static void do_stop(void)
 {
     vm_stop(EXCP_INTERRUPT);
@@ -1403,9 +1415,13 @@
 
 static void do_info_status(void)
 {
-    if (vm_running)
-       term_printf("VM status: running\n");
-    else
+    if (vm_running) {
+        if (vm_singlestep) {
+            term_printf("VM status: running (single step mode)\n");
+        } else {
+            term_printf("VM status: running\n");
+        }
+    } else
        term_printf("VM status: paused\n");
 }
 
@@ -1454,6 +1470,8 @@
       "tag|id", "restore a VM snapshot from its tag or id" },
     { "delvm", "s", do_delvm,
       "tag|id", "delete a VM snapshot from its tag or id" },
+    { "singlestep", "s?", do_singlestep,
+      "[off]", "run emulation in singlestep mode or switch to normal mode", },
     { "stop", "", do_stop,
       "", "stop emulation", },
     { "c|cont", "", do_cont,
sysemu.h +6 -0
Index: trunk/sysemu.h
===================================================================
@@ -6,7 +6,13 @@
 extern const char *bios_name;
 extern const char *bios_dir;
 
+#if defined(CONFIG_USER_ONLY)
+# define vm_singlestep 0
+#else
 extern int vm_running;
+extern int vm_singlestep;
+#endif
+
 extern const char *qemu_name;
 extern uint8_t qemu_uuid[];
 #define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
target-i386/translate.c +8 -6
Index: trunk/target-i386/translate.c
===================================================================
@@ -17,17 +17,14 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <signal.h>
+
 #include <assert.h>
 
+#include "qemu-common.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "sysemu.h"
 #include "tcg-op.h"
 
 #include "helper.h"
@@ -7661,6 +7658,11 @@
             gen_eob(dc);
             break;
         }
+        if (vm_singlestep) {
+            gen_jmp_im(pc_ptr - dc->cs_base);
+            gen_eob(dc);
+            break;
+        }
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-arm/translate.c +3 -6
Index: trunk/target-arm/translate.c
===================================================================
@@ -19,15 +19,12 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
 
+#include "qemu-common.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "sysemu.h"
 #include "tcg-op.h"
 #include "qemu-log.h"
 
@@ -8788,7 +8785,7 @@
          * ensures prefetch aborts occur at the right place.  */
         num_insns ++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !env->singlestep_enabled && !vm_singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
 
target-m68k/translate.c +4 -6
Index: trunk/target-m68k/translate.c
===================================================================
@@ -18,17 +18,15 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
+
 #include <assert.h>
 
+#include "qemu-common.h"
 #include "config.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "sysemu.h"
 #include "tcg-op.h"
 #include "qemu-log.h"
 
@@ -3028,7 +3026,7 @@
 	disas_m68k_insn(env, dc);
         num_insns++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !env->singlestep_enabled && !vm_singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 
target-sparc/translate.c +3 -7
Index: trunk/target-sparc/translate.c
===================================================================
@@ -19,16 +19,12 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
+#include "qemu-common.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "helper.h"
+#include "sysemu.h"
 #include "tcg-op.h"
 
 #define GEN_HELPER 1
@@ -4859,7 +4855,7 @@
             break;
         /* if single step mode, we generate only one instruction and
            generate an exception */
-        if (env->singlestep_enabled) {
+        if (env->singlestep_enabled || vm_singlestep) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
             tcg_gen_exit_tb(0);
             break;
qemu-doc.texi +6 -0
Index: trunk/qemu-doc.texi
===================================================================
@@ -1027,6 +1027,8 @@
 to specify a TCP port, or a host device (same devices as the serial port).
 @item -S
 Do not start CPU at startup (you must type 'c' in the monitor).
+@item -singlestep
+Run the emulation in single step mode.
 @item -d
 Output log in /tmp/qemu.log
 @item -hdachs @var{c},@var{h},@var{s},[,@var{t}]
@@ -1306,6 +1308,10 @@
 @item delvm @var{tag}|@var{id}
 Delete the snapshot identified by @var{tag} or @var{id}.
 
+@item singlestep [off]
+Run the emulation in single step mode.
+If called with option off, the emulation returns to normal mode.
+
 @item stop
 Stop emulation.
 
#1 lore raw
Quoted 20 lines · Stefan Weil

This patch replaces the compile time options SH4_SINGLE_STEP, DO_SINGLE_STEP and MIPS_SINGLE_STEP
by a command line option -singlestep.

It also adds single step mode for targets which did not have a compile time option,
so all system emulations can be used with -singlestep. Please note that I did only
run a short test for i386 and mips targets.

A new monitor command is provided to enable or disable single step mode. The monitor command "info status" was modified to display single step mode when activated.

Single stepping in Qemu's system emulation mode is useful to see the cpu state
for each cpu instruction when used with -d in_asm,cpu. It is also a simple way to
slow down the emulation.

Quoted 7 lines

The patch does not add single step mode for Qemu's user mode emulation. Would this be useful, too?

Kind regards
Stefan Weil

Are there no comments?

#2 lore raw
In reply to Stefan Weil
Quoted 2 lines · Stefan Weil

The patch does not add single step mode for Qemu's user mode emulation. Would this be useful, too?

Single stepping in user mode emulation could be quite useful for the development of any target that doesn't have system emulation yet, so I imagine that I'll need it at some point for this very reason.

(You didn't actually say, but I would assume that the extra check for single stepping after the translation of each instruction has a negligable effect on performance.)

I expect that many of the existing targets are stable enough that single stepping isn't really needed for those targets per se, but I've found that single stepping can be very helpful when debugging host support, and it can generally be quite annoying to have to keep rebuilding with different #defines uncommented.

Cheers,

Signature · 1 line
Stuart Brady
#3 lore raw
In reply to Stefan Weil
Quoted 18 lines · Stefan Weil

This patch replaces the compile time options SH4_SINGLE_STEP, DO_SINGLE_STEP and MIPS_SINGLE_STEP
by a command line option -singlestep.

It also adds single step mode for targets which did not have a compile time option,
so all system emulations can be used with -singlestep. Please note that I did only run a short test for i386 and mips targets.

A new monitor command is provided to enable or disable single step mode. The monitor command "info status" was modified to display single step mode when activated.

Single stepping in Qemu's system emulation mode is useful to see the cpu state
for each cpu instruction when used with -d in_asm,cpu. It is also a simple way to slow down the emulation.

Quoted 7 lines

The patch does not add single step mode for Qemu's user mode emulation. Would this be useful, too?

Kind regards
Stefan Weil

Hello,

here is an update of the patch. Please apply it to Qemu trunk.

Regards
Stefan Weil

Add new command line option for tcg single stepping. This replaces a compile time option for some targets and adds this feature to targets which did not have a compile time option.

Add monitor command to enable or disable single step mode.

Modify monitor command "info status" to display single step mode.

target-sh4/translate.c +2 -3
Index: trunk/target-sh4/translate.c
===================================================================
@@ -1896,9 +1896,8 @@
 	    break;
         if (num_insns >= max_insns)
             break;
-#ifdef SH4_SINGLE_STEP
-	break;
-#endif
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-cris/translate.c +1 -0
Index: trunk/target-cris/translate.c
===================================================================
@@ -3271,6 +3271,7 @@
 			break;
 	} while (!dc->is_jmp && !dc->cpustate_changed
 		 && gen_opc_ptr < gen_opc_end
+		 && !vm_singlestep
 		 && (dc->pc < next_page_start)
                  && num_insns < max_insns);
 
target-alpha/translate.c +3 -4
Index: trunk/target-alpha/translate.c
===================================================================
@@ -2413,11 +2413,10 @@
         if (env->singlestep_enabled) {
             gen_excp(&ctx, EXCP_DEBUG, 0);
             break;
-	}
+        }
 
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+        if (vm_singlestep)
+            break;
     }
     if (ret != 1 && ret != 3) {
         tcg_gen_movi_i64(cpu_pc, ctx.pc);
vl.c +4 -0
Index: trunk/vl.c
===================================================================
@@ -193,6 +193,7 @@
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int vm_running;
+int vm_singlestep;
 static int rtc_utc = 1;
 static int rtc_date_offset = -1; /* -1 means no change */
 int cirrus_vga_enabled = 1;
@@ -3984,6 +3985,7 @@
            "-parallel dev   redirect the parallel port to char device 'dev'\n"
            "-monitor dev    redirect the monitor to char device 'dev'\n"
            "-pidfile file   write PID to 'file'\n"
+           "-singlestep     always run in singlestep mode\n"
            "-S              freeze CPU at startup (use 'c' to start execution)\n"
            "-s              wait gdb connection to port\n"
            "-p port         set gdb connection port [default=%s]\n"
@@ -4119,6 +4121,7 @@
     QEMU_OPTION_parallel,
     QEMU_OPTION_monitor,
     QEMU_OPTION_pidfile,
+    QEMU_OPTION_singlestep,
     QEMU_OPTION_S,
     QEMU_OPTION_s,
     QEMU_OPTION_p,
@@ -4238,6 +4241,7 @@
     { "parallel", HAS_ARG, QEMU_OPTION_parallel },
     { "monitor", HAS_ARG, QEMU_OPTION_monitor },
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
+    { "singlestep", 0, QEMU_OPTION_singlestep },
     { "S", 0, QEMU_OPTION_S },
     { "s", 0, QEMU_OPTION_s },
     { "p", HAS_ARG, QEMU_OPTION_p },
target-ppc/translate.c +3 -4
Index: trunk/target-ppc/translate.c
===================================================================
@@ -38,7 +38,6 @@
 #define GDBSTUB_SINGLE_STEP 0x4
 
 /* Include definitions for instructions classes and implementations flags */
-//#define DO_SINGLE_STEP
 //#define PPC_DEBUG_DISAS
 //#define DO_PPC_STATISTICS
 
@@ -8305,9 +8304,9 @@
              */
             break;
         }
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-mips/translate.c +3 -4
Index: trunk/target-mips/translate.c
===================================================================
@@ -38,7 +38,6 @@
 
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS
-//#define MIPS_SINGLE_STEP
 
 /* MIPS major opcodes */
 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
@@ -8247,9 +8246,9 @@
 
         if (num_insns >= max_insns)
             break;
-#if defined (MIPS_SINGLE_STEP)
-        break;
-#endif
+
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
monitor.c +21 -3
Index: trunk/monitor.c
===================================================================
@@ -489,6 +489,18 @@
     cpu_set_log(mask);
 }
 
+static void do_singlestep(const char *option)
+{
+    qemu_printf("setting vm_singlestep to %s\n", option);
+    if (!option) {
+        vm_singlestep = 1;
+    } else if (!strcmp(option, "off")) {
+        vm_singlestep = 0;
+    } else {
+        term_printf("unexpected option %s\n", option);
+    }
+}
+
 static void do_stop(void)
 {
     vm_stop(EXCP_INTERRUPT);
@@ -1403,9 +1415,13 @@
 
 static void do_info_status(void)
 {
-    if (vm_running)
-       term_printf("VM status: running\n");
-    else
+    if (vm_running) {
+        if (vm_singlestep) {
+            term_printf("VM status: running (single step mode)\n");
+        } else {
+            term_printf("VM status: running\n");
+        }
+    } else
        term_printf("VM status: paused\n");
 }
 
@@ -1455,6 +1471,8 @@
       "tag|id", "restore a VM snapshot from its tag or id" },
     { "delvm", "s", do_delvm,
       "tag|id", "delete a VM snapshot from its tag or id" },
+    { "singlestep", "s?", do_singlestep,
+      "[off]", "run emulation in singlestep mode or switch to normal mode", },
     { "stop", "", do_stop,
       "", "stop emulation", },
     { "c|cont", "", do_cont,
target-i386/translate.c +5 -0
Index: trunk/target-i386/translate.c
===================================================================
@@ -7661,6 +7661,11 @@
             gen_eob(dc);
             break;
         }
+        if (vm_singlestep) {
+            gen_jmp_im(pc_ptr - dc->cs_base);
+            gen_eob(dc);
+            break;
+        }
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-arm/translate.c +1 -1
Index: trunk/target-arm/translate.c
===================================================================
@@ -8788,7 +8788,7 @@
          * ensures prefetch aborts occur at the right place.  */
         num_insns ++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !env->singlestep_enabled && !vm_singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
 
target-m68k/translate.c +1 -1
Index: trunk/target-m68k/translate.c
===================================================================
@@ -3028,7 +3028,7 @@
 	disas_m68k_insn(env, dc);
         num_insns++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !env->singlestep_enabled && !vm_singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 
target-sparc/translate.c +1 -1
Index: trunk/target-sparc/translate.c
===================================================================
@@ -4858,7 +4858,7 @@
             break;
         /* if single step mode, we generate only one instruction and
            generate an exception */
-        if (env->singlestep_enabled) {
+        if (env->singlestep_enabled || vm_singlestep) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
             tcg_gen_exit_tb(0);
             break;
qemu-doc.texi +7 -0
Index: trunk/qemu-doc.texi
===================================================================
@@ -1064,6 +1064,9 @@
 @item -s
 Wait gdb connection to port 1234 (@pxref{gdb_usage}).
 
+@item -singlestep
+Run the emulation in single step mode.
+
 @item -p @var{port}
 Change gdb connection port.  @var{port} can be either a decimal number
 to specify a TCP port, or a host device (same devices as the serial port).
@@ -1383,6 +1386,10 @@
 @item delvm @var{tag}|@var{id}
 Delete the snapshot identified by @var{tag} or @var{id}.
 
+@item singlestep [off]
+Run the emulation in single step mode.
+If called with option off, the emulation returns to normal mode.
+
 @item stop
 Stop emulation.
 
exec-all.h +6 -0
Index: trunk/exec-all.h
===================================================================
@@ -386,6 +386,12 @@
 
 #endif
 
+#if defined(CONFIG_USER_ONLY)
+# define vm_singlestep 0
+#else
+extern int vm_singlestep;
+#endif
+
 typedef void (CPUDebugExcpHandler)(CPUState *env);
 
 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
#4 lore raw
Quoted 22 lines · Stefan Weil
Quoted 21 lines · Stefan Weil

This patch replaces the compile time options SH4_SINGLE_STEP, DO_SINGLE_STEP and MIPS_SINGLE_STEP
by a command line option -singlestep.

It also adds single step mode for targets which did not have a compile time option,
so all system emulations can be used with -singlestep. Please note that I did only run a short test for i386 and mips targets.

A new monitor command is provided to enable or disable single step mode. The monitor command "info status" was modified to display single step mode when activated.

Single stepping in Qemu's system emulation mode is useful to see the cpu state
for each cpu instruction when used with -d in_asm,cpu. It is also a simple way to slow down the emulation.

The patch does not add single step mode for Qemu's user mode emulation. Would this be useful, too?

Quoted 8 lines
Quoted 4 lines

Kind regards
Stefan Weil

Hello,

here is an update of the patch. Please apply it to Qemu trunk.

I have two comments:

- as Stuart previously wrote, user mode would be useful to have

- shouldn't you also prevent block chaining from being done for this feature to be really useful?

Laurent

#5 lore raw
Quoted 4 lines · Laurent Desnogues

I have two comments:
- as Stuart previously wrote, user mode would be useful to have

Right. A quick-and-dirty solution to set the flag for user mode is very simple
but also dirty: Today, bsd-user, darwin-user and linux-user would need the same kind of patch in main.c. There is already too much code duplication (or triplication) in these three directories, so a common code basis for all user modes would help. I suggest to take the current patch first, then clean the user mode code in a second step, then add single stepping for user mode in a third step.

Quoted 3 lines

- shouldn't you also prevent block chaining from being done for this feature to be really useful?

The current implementation replaces conditional compilations for several system emulations and adds the same feature to those system emulations which did not have a conditional compilation.

I (and other users, especially those who added the conditional compilation) use this feature, so it is really useful.

Maybe it can be improved the way you suggested. Do you have code for this?

Quoted 6 lines

Laurent

Regards
Stefan

#6 lore raw
In reply to Stefan Weil
Quoted 18 lines · Stefan Weil
Quoted 18 lines

This patch replaces the compile time options SH4_SINGLE_STEP, DO_SINGLE_STEP and MIPS_SINGLE_STEP
by a command line option -singlestep.

It also adds single step mode for targets which did not have a compile time option,
so all system emulations can be used with -singlestep. Please note that I did only run a short test for i386 and mips targets.

A new monitor command is provided to enable or disable single step mode. The monitor command "info status" was modified to display single step mode when activated.

Single stepping in Qemu's system emulation mode is useful to see the cpu state
for each cpu instruction when used with -d in_asm,cpu. It is also a simple way to slow down the emulation.

Quoted 8 lines
Quoted 8 lines

The patch does not add single step mode for Qemu's user mode emulation. Would this be useful, too?

Kind regards
Stefan Weil

The patch is still missing in Qemu trunk. There was some feedback, but not from a maintainer, so I don't know why the patch is not integrated. Do you need an update of the patch? Do you need more information? Do you want something changed or added?

Regards
Stefan Weil

#7 lore raw
Quoted 28 lines · Stefan Weil
Quoted 18 lines · Stefan Weil
Quoted 18 lines

This patch replaces the compile time options SH4_SINGLE_STEP, DO_SINGLE_STEP and MIPS_SINGLE_STEP
by a command line option -singlestep.

It also adds single step mode for targets which did not have a compile time option,
so all system emulations can be used with -singlestep. Please note that I did only run a short test for i386 and mips targets.

A new monitor command is provided to enable or disable single step mode. The monitor command "info status" was modified to display single step mode when activated.

Single stepping in Qemu's system emulation mode is useful to see the cpu state
for each cpu instruction when used with -d in_asm,cpu. It is also a simple way to slow down the emulation.

Quoted 8 lines
Quoted 8 lines

The patch does not add single step mode for Qemu's user mode emulation. Would this be useful, too?

Kind regards
Stefan Weil

Quoted 5 lines

The patch is still missing in Qemu trunk. There was some feedback, but not from a maintainer, so I don't know why the patch is not integrated. Do you need an update of the patch? Do you need more information? Do you want something changed or added?

Sorry, I didn't found time to look at it. But someone else can probably commit it.

Signature · 2 lines
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
[email protected]                 http://www.aurel32.net
#8 lore raw
In reply to Stefan Weil
Quoted 36 lines · Stefan Weil
Quoted 18 lines · Stefan Weil

This patch replaces the compile time options SH4_SINGLE_STEP, DO_SINGLE_STEP and MIPS_SINGLE_STEP
by a command line option -singlestep.

It also adds single step mode for targets which did not have a compile time option,
so all system emulations can be used with -singlestep. Please note that I did only run a short test for i386 and mips targets.

A new monitor command is provided to enable or disable single step mode. The monitor command "info status" was modified to display single step mode when activated.

Single stepping in Qemu's system emulation mode is useful to see the cpu state
for each cpu instruction when used with -d in_asm,cpu. It is also a simple way to slow down the emulation.

Quoted 7 lines

The patch does not add single step mode for Qemu's user mode emulation. Would this be useful, too?

Kind regards
Stefan Weil

Hello,

here is an update of the patch. Please apply it to Qemu trunk.

Regards
Stefan Weil

Quoted 7 lines

Add new command line option for tcg single stepping. This replaces a compile time option for some targets and adds this feature to targets which did not have a compile time option.

Add monitor command to enable or disable single step mode.

Modify monitor command "info status" to display single step mode.

Please find my comments below.

Quoted 79 lines

Index: trunk/target-sh4/translate.c
===================================================================

target-sh4/translate.c +2 -3
@@ -1896,9 +1896,8 @@
 	    break;
         if (num_insns >= max_insns)
             break;
-#ifdef SH4_SINGLE_STEP
-	break;
-#endif
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/target-cris/translate.c
===================================================================

target-cris/translate.c +1 -0
@@ -3271,6 +3271,7 @@
 			break;
 	} while (!dc->is_jmp && !dc->cpustate_changed
 		 && gen_opc_ptr < gen_opc_end
+		 && !vm_singlestep
 		 && (dc->pc < next_page_start)
                  && num_insns < max_insns);
 

Index: trunk/target-alpha/translate.c
===================================================================

target-alpha/translate.c +3 -4
@@ -2413,11 +2413,10 @@
         if (env->singlestep_enabled) {
             gen_excp(&ctx, EXCP_DEBUG, 0);
             break;
-	}
+        }
 
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+        if (vm_singlestep)
+            break;
     }
     if (ret != 1 && ret != 3) {
         tcg_gen_movi_i64(cpu_pc, ctx.pc);

Index: trunk/vl.c
===================================================================

vl.c +3 -0
@@ -193,6 +193,7 @@
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int vm_running;
+int vm_singlestep;
 static int rtc_utc = 1;
 static int rtc_date_offset = -1; /* -1 means no change */
 int cirrus_vga_enabled = 1;
@@ -3984,6 +3985,7 @@
            "-parallel dev   redirect the parallel port to char device 'dev'\n"
            "-monitor dev    redirect the monitor to char device 'dev'\n"
            "-pidfile file   write PID to 'file'\n"
+           "-singlestep     always run in singlestep mode\n"
            "-S              freeze CPU at startup (use 'c' to start execution)\n"
            "-s              wait gdb connection to port\n"
            "-p port         set gdb connection port [default=%s]\n"
@@ -4119,6 +4121,7 @@
     QEMU_OPTION_parallel,
     QEMU_OPTION_monitor,
     QEMU_OPTION_pidfile,
+    QEMU_OPTION_singlestep,
     QEMU_OPTION_S,
     QEMU_OPTION_s,
     QEMU_OPTION_p,

vl.c line 4247

Quoted 7 lines
vl.c +1 -0
@@ -4238,6 +4241,7 @@
     { "parallel", HAS_ARG, QEMU_OPTION_parallel },
     { "monitor", HAS_ARG, QEMU_OPTION_monitor },
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
+    { "singlestep", 0, QEMU_OPTION_singlestep },
     { "S", 0, QEMU_OPTION_S },
     { "s", 0, QEMU_OPTION_s },
     { "p", HAS_ARG, QEMU_OPTION_p },

It might be a good idea to provide that as a subset of the -d option, as it is clearly something only useful for debugging.

Quoted 186 lines

Index: trunk/target-ppc/translate.c
===================================================================

target-ppc/translate.c +3 -4
@@ -38,7 +38,6 @@
 #define GDBSTUB_SINGLE_STEP 0x4
 
 /* Include definitions for instructions classes and implementations flags */
-//#define DO_SINGLE_STEP
 //#define PPC_DEBUG_DISAS
 //#define DO_PPC_STATISTICS
 
@@ -8305,9 +8304,9 @@
              */
             break;
         }
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/target-mips/translate.c
===================================================================

target-mips/translate.c +3 -4
@@ -38,7 +38,6 @@
 
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS
-//#define MIPS_SINGLE_STEP
 
 /* MIPS major opcodes */
 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
@@ -8247,9 +8246,9 @@
 
         if (num_insns >= max_insns)
             break;
-#if defined (MIPS_SINGLE_STEP)
-        break;
-#endif
+
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/monitor.c
===================================================================

monitor.c +21 -3
@@ -489,6 +489,18 @@
     cpu_set_log(mask);
 }
 
+static void do_singlestep(const char *option)
+{
+    qemu_printf("setting vm_singlestep to %s\n", option);
+    if (!option) {
+        vm_singlestep = 1;
+    } else if (!strcmp(option, "off")) {
+        vm_singlestep = 0;
+    } else {
+        term_printf("unexpected option %s\n", option);
+    }
+}
+
 static void do_stop(void)
 {
     vm_stop(EXCP_INTERRUPT);
@@ -1403,9 +1415,13 @@
 
 static void do_info_status(void)
 {
-    if (vm_running)
-       term_printf("VM status: running\n");
-    else
+    if (vm_running) {
+        if (vm_singlestep) {
+            term_printf("VM status: running (single step mode)\n");
+        } else {
+            term_printf("VM status: running\n");
+        }
+    } else
        term_printf("VM status: paused\n");
 }
 
@@ -1455,6 +1471,8 @@
       "tag|id", "restore a VM snapshot from its tag or id" },
     { "delvm", "s", do_delvm,
       "tag|id", "delete a VM snapshot from its tag or id" },
+    { "singlestep", "s?", do_singlestep,
+      "[off]", "run emulation in singlestep mode or switch to normal mode", },
     { "stop", "", do_stop,
       "", "stop emulation", },
     { "c|cont", "", do_cont,

Index: trunk/target-i386/translate.c
===================================================================

target-i386/translate.c +5 -0
@@ -7661,6 +7661,11 @@
             gen_eob(dc);
             break;
         }
+        if (vm_singlestep) {
+            gen_jmp_im(pc_ptr - dc->cs_base);
+            gen_eob(dc);
+            break;
+        }
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/target-arm/translate.c
===================================================================

target-arm/translate.c +1 -1
@@ -8788,7 +8788,7 @@
          * ensures prefetch aborts occur at the right place.  */
         num_insns ++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !env->singlestep_enabled && !vm_singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
 

Index: trunk/target-m68k/translate.c
===================================================================

target-m68k/translate.c +1 -1
@@ -3028,7 +3028,7 @@
 	disas_m68k_insn(env, dc);
         num_insns++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !env->singlestep_enabled && !vm_singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 

Index: trunk/target-sparc/translate.c
===================================================================

target-sparc/translate.c +1 -1
@@ -4858,7 +4858,7 @@
             break;
         /* if single step mode, we generate only one instruction and
            generate an exception */
-        if (env->singlestep_enabled) {
+        if (env->singlestep_enabled || vm_singlestep) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
             tcg_gen_exit_tb(0);
             break;

Index: trunk/qemu-doc.texi
===================================================================

qemu-doc.texi +7 -0
@@ -1064,6 +1064,9 @@
 @item -s
 Wait gdb connection to port 1234 (@pxref{gdb_usage}).
 
+@item -singlestep
+Run the emulation in single step mode.
+
 @item -p @var{port}
 Change gdb connection port.  @var{port} can be either a decimal number
 to specify a TCP port, or a host device (same devices as the serial port).
@@ -1383,6 +1386,10 @@
 @item delvm @var{tag}|@var{id}
 Delete the snapshot identified by @var{tag} or @var{id}.
 
+@item singlestep [off]
+Run the emulation in single step mode.
+If called with option off, the emulation returns to normal mode.
+
 @item stop
 Stop emulation.
 

Index: trunk/exec-all.h
===================================================================

exec-all.h +0 -0
@@ -386,6 +386,12 @@
 
 #endif

exec-all.h line 397

Quoted 10 lines
exec-all.h +6 -0
 
+#if defined(CONFIG_USER_ONLY)
+# define vm_singlestep 0
+#else
+extern int vm_singlestep;
+#endif
+
 typedef void (CPUDebugExcpHandler)(CPUState *env);
 
 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);

Why only on system emulation mode? During my debugging session, I mostly used single stepping by hardcoding it in the code on user mode.

Signature · 2 lines
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
[email protected]                 http://www.aurel32.net
#9 lore raw

This is an update of my patch which adds a new command line option -singlestep, now for both system and user mode.

So it now respects the feedback from Stuart, Laurent and Aurelien who all wanted user mode support, too.

There remains one open feedback point which I did not understand - see below.

I hope the patch will be added to trunk finally...

Regards
Stefan Weil

Quoted 57 lines · Aurelien Jarno
Quoted 14 lines · Stefan Weil
Quoted 13 lines · Stefan Weil

This patch replaces the compile time options SH4_SINGLE_STEP, DO_SINGLE_STEP and MIPS_SINGLE_STEP
by a command line option -singlestep.

It also adds single step mode for targets which did not have a compile time option,
so all system emulations can be used with -singlestep. Please note that I did only run a short test for i386 and mips targets.

A new monitor command is provided to enable or disable single step mode. The monitor command "info status" was modified to display single step mode when activated.

Quoted 6 lines
Quoted 6 lines

Single stepping in Qemu's system emulation mode is useful to see the cpu state
for each cpu instruction when used with -d in_asm,cpu. It is also a simple way to slow down the emulation.

Please find my comments below.

Quoted 33 lines

...
Index: trunk/vl.c
===================================================================

vl.c 2009-02-01 19:18:33.000000000 +0100 renamed from vl.c 2009-02-01 19:12:41.000000000 +0100 +1 -0
@@ -193,6 +193,7 @@
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int vm_running;
+int vm_singlestep;
 static int rtc_utc = 1;

static int rtc_date_offset = -1; /* -1 means no change */ int cirrus_vga_enabled = 1;

vl.c 2009-02-01 19:18:33.000000000 +0100 renamed from vl.c 2009-02-01 19:12:41.000000000 +0100 +0 -0
@@ -3984,6 +3985,7 @@

"-parallel dev redirect the parallel port to char device 'dev'\n" "-monitor dev redirect the monitor to char device 'dev'\n" "-pidfile file write PID to 'file'\n"
+ "-singlestep always run in singlestep mode\n"
"-S freeze CPU at startup (use 'c' to start execution)\n" "-s wait gdb connection to port\n"
"-p port set gdb connection port [default=%s]\n"

vl.c 2009-02-01 19:18:33.000000000 +0100 renamed from vl.c 2009-02-01 19:12:41.000000000 +0100 +1 -0
@@ -4119,6 +4121,7 @@
 QEMU_OPTION_parallel,
 QEMU_OPTION_monitor,
 QEMU_OPTION_pidfile,
+ QEMU_OPTION_singlestep,
 QEMU_OPTION_S,
 QEMU_OPTION_s,
 QEMU_OPTION_p,
@@ -4238,6 +4241,7 @@
 { "parallel", HAS_ARG, QEMU_OPTION_parallel },
 { "monitor", HAS_ARG, QEMU_OPTION_monitor },
Quoted 8 lines

vl.c 2009-02-01 19:18:33.000000000 +0100 line 4247

Quoted 5 lines
vl.c 2009-02-01 19:18:33.000000000 +0100 renamed from vl.c 2009-02-01 19:12:41.000000000 +0100 +1 -0
 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
+ { "singlestep", 0, QEMU_OPTION_singlestep },
 { "S", 0, QEMU_OPTION_S },
 { "s", 0, QEMU_OPTION_s },
 { "p", HAS_ARG, QEMU_OPTION_p },

It might be a good idea to provide that as a subset of the -d option, as it is clearly something only useful for debugging.

Today -d does not take suboptions.
Could you please explain your proposal with more details?

Stefan

Add new command line option -singlestep for tcg single stepping.

This replaces a compile time option for some targets and adds this feature to targets which did not have a compile time option.

Add monitor command to enable or disable single step mode.

Modify monitor command "info status" to display single step mode.

target-sh4/translate.c +2 -3
Index: trunk/target-sh4/translate.c
===================================================================
@@ -1929,9 +1929,8 @@
 	    break;
         if (num_insns >= max_insns)
             break;
-#ifdef SH4_SINGLE_STEP
-	break;
-#endif
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-cris/translate.c +1 -0
Index: trunk/target-cris/translate.c
===================================================================
@@ -3272,6 +3272,7 @@
 			break;
 	} while (!dc->is_jmp && !dc->cpustate_changed
 		 && gen_opc_ptr < gen_opc_end
+		 && !vm_singlestep
 		 && (dc->pc < next_page_start)
                  && num_insns < max_insns);
 
target-alpha/translate.c +3 -4
Index: trunk/target-alpha/translate.c
===================================================================
@@ -2413,11 +2413,10 @@
         if (env->singlestep_enabled) {
             gen_excp(&ctx, EXCP_DEBUG, 0);
             break;
-	}
+        }
 
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+        if (vm_singlestep)
+            break;
     }
     if (ret != 1 && ret != 3) {
         tcg_gen_movi_i64(cpu_pc, ctx.pc);
vl.c +4 -0
Index: trunk/vl.c
===================================================================
@@ -211,6 +211,7 @@
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int vm_running;
+int vm_singlestep;
 static int autostart;
 static int rtc_utc = 1;
 static int rtc_date_offset = -1; /* -1 means no change */
@@ -4081,6 +4082,7 @@
            "-parallel dev   redirect the parallel port to char device 'dev'\n"
            "-monitor dev    redirect the monitor to char device 'dev'\n"
            "-pidfile file   write PID to 'file'\n"
+           "-singlestep     always run in singlestep mode\n"
            "-S              freeze CPU at startup (use 'c' to start execution)\n"
            "-s              wait gdb connection to port\n"
            "-p port         set gdb connection port [default=%s]\n"
@@ -4221,6 +4223,7 @@
     QEMU_OPTION_parallel,
     QEMU_OPTION_monitor,
     QEMU_OPTION_pidfile,
+    QEMU_OPTION_singlestep,
     QEMU_OPTION_S,
     QEMU_OPTION_s,
     QEMU_OPTION_p,
@@ -4345,6 +4348,7 @@
     { "parallel", HAS_ARG, QEMU_OPTION_parallel },
     { "monitor", HAS_ARG, QEMU_OPTION_monitor },
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
+    { "singlestep", 0, QEMU_OPTION_singlestep },
     { "S", 0, QEMU_OPTION_S },
     { "s", 0, QEMU_OPTION_s },
     { "p", HAS_ARG, QEMU_OPTION_p },
target-ppc/translate.c +3 -4
Index: trunk/target-ppc/translate.c
===================================================================
@@ -39,7 +39,6 @@
 #define GDBSTUB_SINGLE_STEP 0x4
 
 /* Include definitions for instructions classes and implementations flags */
-//#define DO_SINGLE_STEP
 //#define PPC_DEBUG_DISAS
 //#define DO_PPC_STATISTICS
 
@@ -8294,9 +8293,9 @@
              */
             break;
         }
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-mips/translate.c +3 -4
Index: trunk/target-mips/translate.c
===================================================================
@@ -38,7 +38,6 @@
 
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS
-//#define MIPS_SINGLE_STEP
 
 /* MIPS major opcodes */
 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
@@ -8245,9 +8244,9 @@
 
         if (num_insns >= max_insns)
             break;
-#if defined (MIPS_SINGLE_STEP)
-        break;
-#endif
+
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
monitor.c +21 -3
Index: trunk/monitor.c
===================================================================
@@ -527,6 +527,18 @@
     cpu_set_log(mask);
 }
 
+static void do_singlestep(Monitor *mon, const char *option)
+{
+    qemu_printf("setting vm_singlestep to %s\n", option);
+    if (!option) {
+        vm_singlestep = 1;
+    } else if (!strcmp(option, "off")) {
+        vm_singlestep = 0;
+    } else {
+        monitor_printf(mon, "unexpected option %s\n", option);
+    }
+}
+
 static void do_stop(Monitor *mon)
 {
     vm_stop(EXCP_INTERRUPT);
@@ -1508,9 +1520,13 @@
 
 static void do_info_status(Monitor *mon)
 {
-    if (vm_running)
-       monitor_printf(mon, "VM status: running\n");
-    else
+    if (vm_running) {
+        if (vm_singlestep) {
+            monitor_printf(mon, "VM status: running (single step mode)\n");
+        } else {
+            monitor_printf(mon, "VM status: running\n");
+        }
+    } else
        monitor_printf(mon, "VM status: paused\n");
 }
 
@@ -1641,6 +1657,8 @@
       "tag|id", "restore a VM snapshot from its tag or id" },
     { "delvm", "s", do_delvm,
       "tag|id", "delete a VM snapshot from its tag or id" },
+    { "singlestep", "s?", do_singlestep,
+      "[off]", "run emulation in singlestep mode or switch to normal mode", },
     { "stop", "", do_stop,
       "", "stop emulation", },
     { "c|cont", "", do_cont,
target-i386/translate.c +5 -0
Index: trunk/target-i386/translate.c
===================================================================
@@ -7651,6 +7651,11 @@
             gen_eob(dc);
             break;
         }
+        if (vm_singlestep) {
+            gen_jmp_im(pc_ptr - dc->cs_base);
+            gen_eob(dc);
+            break;
+        }
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-arm/translate.c +1 -1
Index: trunk/target-arm/translate.c
===================================================================
@@ -8788,7 +8788,7 @@
          * ensures prefetch aborts occur at the right place.  */
         num_insns ++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !env->singlestep_enabled && !vm_singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
 
target-m68k/translate.c +1 -1
Index: trunk/target-m68k/translate.c
===================================================================
@@ -3030,7 +3030,7 @@
 	disas_m68k_insn(env, dc);
         num_insns++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !env->singlestep_enabled && !vm_singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 
target-sparc/translate.c +1 -1
Index: trunk/target-sparc/translate.c
===================================================================
@@ -4858,7 +4858,7 @@
             break;
         /* if single step mode, we generate only one instruction and
            generate an exception */
-        if (env->singlestep_enabled) {
+        if (env->singlestep_enabled || vm_singlestep) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
             tcg_gen_exit_tb(0);
             break;
qemu-doc.texi +7 -0
Index: trunk/qemu-doc.texi
===================================================================
@@ -1100,6 +1100,9 @@
 @item -s
 Wait gdb connection to port 1234 (@pxref{gdb_usage}).
 
+@item -singlestep
+Run the emulation in single step mode.
+
 @item -p @var{port}
 Change gdb connection port.  @var{port} can be either a decimal number
 to specify a TCP port, or a host device (same devices as the serial port).
@@ -1463,6 +1466,10 @@
 @item delvm @var{tag}|@var{id}
 Delete the snapshot identified by @var{tag} or @var{id}.
 
+@item singlestep [off]
+Run the emulation in single step mode.
+If called with option off, the emulation returns to normal mode.
+
 @item stop
 Stop emulation.
 
exec-all.h +2 -0
Index: trunk/exec-all.h
===================================================================
@@ -381,6 +381,8 @@
 
 #endif
 
+extern int vm_singlestep;
+
 typedef void (CPUDebugExcpHandler)(CPUState *env);
 
 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
bsd-user/main.c +5 -0
Index: trunk/bsd-user/main.c
===================================================================
@@ -33,6 +33,8 @@
 
 #define DEBUG_LOGFILE "/tmp/qemu.log"
 
+int vm_singlestep;
+
 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 extern char **environ;
@@ -378,6 +380,7 @@
            "Debug options:\n"
            "-d options   activate log (logfile=%s)\n"
            "-p pagesize  set the host page size to 'pagesize'\n"
+           "-singlestep  always run in singlestep mode\n"
            "-strace      log system calls\n"
            "\n"
            "Environment variables:\n"
@@ -500,6 +503,8 @@
                 usage();
             }
             optind++;
+        } else if (!strcmp(r, "singlestep")) {
+            vm_singlestep = 1;
         } else if (!strcmp(r, "strace")) {
             do_strace = 1;
         } else
darwin-user/main.c +5 -0
Index: trunk/darwin-user/main.c
===================================================================
@@ -41,6 +41,8 @@
 #include <mach/mach_init.h>
 #include <mach/vm_map.h>
 
+int vm_singlestep;
+
 const char *interp_prefix = "";
 
 asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000");
@@ -751,6 +753,7 @@
            "-d options   activate log (logfile='%s')\n"
            "-g wait for gdb on port 1234\n"
            "-p pagesize  set the host page size to 'pagesize'\n",
+           "-singlestep  always run in singlestep mode\n"
            TARGET_ARCH,
            TARGET_ARCH,
            interp_prefix,
@@ -842,6 +845,8 @@
 #endif
                 exit(1);
             }
+        } else if (!strcmp(r, "singlestep")) {
+            vm_singlestep = 1;
         } else
         {
             usage();
linux-user/main.c +5 -0
Index: trunk/linux-user/main.c
===================================================================
@@ -39,6 +39,8 @@
 
 char *exec_path;
 
+int vm_singlestep;
+
 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 
@@ -2217,6 +2219,7 @@
            "Debug options:\n"
            "-d options   activate log (logfile=%s)\n"
            "-p pagesize  set the host page size to 'pagesize'\n"
+           "-singlestep  always run in singlestep mode\n"
            "-strace      log system calls\n"
            "\n"
            "Environment variables:\n"
@@ -2359,6 +2362,8 @@
             }
         } else if (!strcmp(r, "drop-ld-preload")) {
             (void) envlist_unsetenv(envlist, "LD_PRELOAD");
+        } else if (!strcmp(r, "singlestep")) {
+            vm_singlestep = 1;
         } else if (!strcmp(r, "strace")) {
             do_strace = 1;
         } else
#10 lore raw
Quoted 7 lines · Stefan Weil
Quoted 3 lines

It might be a good idea to provide that as a subset of the -d option, as it is clearly something only useful for debugging.

Today -d does not take suboptions.
Could you please explain your proposal with more details?

It kind of does by using cpu_str_to_log_mask. On the other hand I'm not sure your option belongs to -d as all of -d suboptions are there to enable some kind of output log.

Laurent

#11 lore raw
Quoted 10 lines · Laurent Desnogues
Quoted 5 lines · Stefan Weil
Quoted 2 lines

It might be a good idea to provide that as a subset of the -d option, as it is clearly something only useful for debugging.

Today -d does not take suboptions.
Could you please explain your proposal with more details?

It kind of does by using cpu_str_to_log_mask. On the other hand I'm not sure your option belongs to -d as all of -d suboptions are there to enable some kind of output log.

Agreed. -d doesn't mean "debugging" but, as its monitor equivalent "log" suggests, "logging". This option is more in the category of -S, and that's a top-level option, too.

Jan

Signature · 2 lines
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
#12 lore raw
In reply to Stefan Weil
Quoted 6 lines · Stefan Weil

This is an update of my patch which adds a new command line option -singlestep, now for both system and user mode.

So it now respects the feedback from Stuart, Laurent and Aurelien who all wanted user mode support, too.

Quoted 7 lines

There remains one open feedback point which I did not understand - see below.

I hope the patch will be added to trunk finally...

Regards
Stefan Weil

Hello,

there is still no new feedback and integration in trunk is missing. Do we need more maintainers? I offer my help!

Regards
Stefan Weil

#13 lore raw
In reply to Stefan Weil
Quoted 84 lines · Stefan Weil

This is an update of my patch which adds a new command line option -singlestep, now for both system and user mode.

So it now respects the feedback from Stuart, Laurent and Aurelien who all wanted user mode support, too.

There remains one open feedback point which I did not understand - see below.

I hope the patch will be added to trunk finally...

Regards
Stefan Weil

Quoted 57 lines · Aurelien Jarno
Quoted 14 lines · Stefan Weil
Quoted 13 lines · Stefan Weil

This patch replaces the compile time options SH4_SINGLE_STEP, DO_SINGLE_STEP and MIPS_SINGLE_STEP
by a command line option -singlestep.

It also adds single step mode for targets which did not have a compile time option,
so all system emulations can be used with -singlestep. Please note that I did only run a short test for i386 and mips targets.

A new monitor command is provided to enable or disable single step mode. The monitor command "info status" was modified to display single step mode when activated.

Quoted 6 lines
Quoted 6 lines

Single stepping in Qemu's system emulation mode is useful to see the cpu state
for each cpu instruction when used with -d in_asm,cpu. It is also a simple way to slow down the emulation.

Please find my comments below.

Quoted 33 lines

...
Index: trunk/vl.c
===================================================================

vl.c 2009-02-01 19:18:33.000000000 +0100 renamed from vl.c 2009-02-01 19:12:41.000000000 +0100 +1 -0
@@ -193,6 +193,7 @@
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int vm_running;
+int vm_singlestep;
 static int rtc_utc = 1;

static int rtc_date_offset = -1; /* -1 means no change */ int cirrus_vga_enabled = 1;

vl.c 2009-02-01 19:18:33.000000000 +0100 renamed from vl.c 2009-02-01 19:12:41.000000000 +0100 +0 -0
@@ -3984,6 +3985,7 @@

"-parallel dev redirect the parallel port to char device 'dev'\n" "-monitor dev redirect the monitor to char device 'dev'\n" "-pidfile file write PID to 'file'\n"
+ "-singlestep always run in singlestep mode\n"
"-S freeze CPU at startup (use 'c' to start execution)\n" "-s wait gdb connection to port\n"
"-p port set gdb connection port [default=%s]\n"

vl.c 2009-02-01 19:18:33.000000000 +0100 renamed from vl.c 2009-02-01 19:12:41.000000000 +0100 +1 -0
@@ -4119,6 +4121,7 @@
 QEMU_OPTION_parallel,
 QEMU_OPTION_monitor,
 QEMU_OPTION_pidfile,
+ QEMU_OPTION_singlestep,
 QEMU_OPTION_S,
 QEMU_OPTION_s,
 QEMU_OPTION_p,
@@ -4238,6 +4241,7 @@
 { "parallel", HAS_ARG, QEMU_OPTION_parallel },
 { "monitor", HAS_ARG, QEMU_OPTION_monitor },
Quoted 8 lines

vl.c 2009-02-01 19:18:33.000000000 +0100 line 4247

Quoted 5 lines
vl.c 2009-02-01 19:18:33.000000000 +0100 renamed from vl.c 2009-02-01 19:12:41.000000000 +0100 +1 -0
 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
+ { "singlestep", 0, QEMU_OPTION_singlestep },
 { "S", 0, QEMU_OPTION_S },
 { "s", 0, QEMU_OPTION_s },
 { "p", HAS_ARG, QEMU_OPTION_p },

It might be a good idea to provide that as a subset of the -d option, as it is clearly something only useful for debugging.

Quoted 5 lines

Today -d does not take suboptions.
Could you please explain your proposal with more details?

Stefan

Given those explanations and the comments from other people, I am fine with this option. I still have some comments though (see below).

Quoted 63 lines

Add new command line option -singlestep for tcg single stepping.

This replaces a compile time option for some targets and adds this feature to targets which did not have a compile time option.

Add monitor command to enable or disable single step mode.

Modify monitor command "info status" to display single step mode.

Index: trunk/target-sh4/translate.c
===================================================================

target-sh4/translate.c +2 -3
@@ -1929,9 +1929,8 @@
 	    break;
         if (num_insns >= max_insns)
             break;
-#ifdef SH4_SINGLE_STEP
-	break;
-#endif
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/target-cris/translate.c
===================================================================

target-cris/translate.c +1 -0
@@ -3272,6 +3272,7 @@
 			break;
 	} while (!dc->is_jmp && !dc->cpustate_changed
 		 && gen_opc_ptr < gen_opc_end
+		 && !vm_singlestep
 		 && (dc->pc < next_page_start)
                  && num_insns < max_insns);
 

Index: trunk/target-alpha/translate.c
===================================================================

target-alpha/translate.c +3 -4
@@ -2413,11 +2413,10 @@
         if (env->singlestep_enabled) {
             gen_excp(&ctx, EXCP_DEBUG, 0);
             break;
-	}
+        }
 
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+        if (vm_singlestep)
+            break;
     }
     if (ret != 1 && ret != 3) {
         tcg_gen_movi_i64(cpu_pc, ctx.pc);

Index: trunk/vl.c
===================================================================

vl.c line 214

Quoted 4 lines
vl.c +1 -0
@@ -211,6 +211,7 @@
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int vm_running;
+int vm_singlestep;

You create a new variable. By the way, I think that calling it singlestep is better, and matches the naming of other options variable (like daemonize, graphic_rotate). You should define it to a default value of 0.

Quoted 20 lines
vl.c +2 -0
 static int autostart;
 static int rtc_utc = 1;
 static int rtc_date_offset = -1; /* -1 means no change */
@@ -4081,6 +4082,7 @@
            "-parallel dev   redirect the parallel port to char device 'dev'\n"
            "-monitor dev    redirect the monitor to char device 'dev'\n"
            "-pidfile file   write PID to 'file'\n"
+           "-singlestep     always run in singlestep mode\n"
            "-S              freeze CPU at startup (use 'c' to start execution)\n"
            "-s              wait gdb connection to port\n"
            "-p port         set gdb connection port [default=%s]\n"
@@ -4221,6 +4223,7 @@
     QEMU_OPTION_parallel,
     QEMU_OPTION_monitor,
     QEMU_OPTION_pidfile,
+    QEMU_OPTION_singlestep,
     QEMU_OPTION_S,
     QEMU_OPTION_s,
     QEMU_OPTION_p,

vl.c line 4354

Quoted 7 lines
vl.c +1 -0
@@ -4345,6 +4348,7 @@
     { "parallel", HAS_ARG, QEMU_OPTION_parallel },
     { "monitor", HAS_ARG, QEMU_OPTION_monitor },
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
+    { "singlestep", 0, QEMU_OPTION_singlestep },
     { "S", 0, QEMU_OPTION_S },
     { "s", 0, QEMU_OPTION_s },
     { "p", HAS_ARG, QEMU_OPTION_p },

This option is never parsed, so the -singlestep option doesn't work.

Quoted 282 lines

Index: trunk/target-ppc/translate.c
===================================================================

target-ppc/translate.c +3 -4
@@ -39,7 +39,6 @@
 #define GDBSTUB_SINGLE_STEP 0x4
 
 /* Include definitions for instructions classes and implementations flags */
-//#define DO_SINGLE_STEP
 //#define PPC_DEBUG_DISAS
 //#define DO_PPC_STATISTICS
 
@@ -8294,9 +8293,9 @@
              */
             break;
         }
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/target-mips/translate.c
===================================================================

target-mips/translate.c +3 -4
@@ -38,7 +38,6 @@
 
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS
-//#define MIPS_SINGLE_STEP
 
 /* MIPS major opcodes */
 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
@@ -8245,9 +8244,9 @@
 
         if (num_insns >= max_insns)
             break;
-#if defined (MIPS_SINGLE_STEP)
-        break;
-#endif
+
+        if (vm_singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/monitor.c
===================================================================

monitor.c +21 -3
@@ -527,6 +527,18 @@
     cpu_set_log(mask);
 }
 
+static void do_singlestep(Monitor *mon, const char *option)
+{
+    qemu_printf("setting vm_singlestep to %s\n", option);
+    if (!option) {
+        vm_singlestep = 1;
+    } else if (!strcmp(option, "off")) {
+        vm_singlestep = 0;
+    } else {
+        monitor_printf(mon, "unexpected option %s\n", option);
+    }
+}
+
 static void do_stop(Monitor *mon)
 {
     vm_stop(EXCP_INTERRUPT);
@@ -1508,9 +1520,13 @@
 
 static void do_info_status(Monitor *mon)
 {
-    if (vm_running)
-       monitor_printf(mon, "VM status: running\n");
-    else
+    if (vm_running) {
+        if (vm_singlestep) {
+            monitor_printf(mon, "VM status: running (single step mode)\n");
+        } else {
+            monitor_printf(mon, "VM status: running\n");
+        }
+    } else
        monitor_printf(mon, "VM status: paused\n");
 }
 
@@ -1641,6 +1657,8 @@
       "tag|id", "restore a VM snapshot from its tag or id" },
     { "delvm", "s", do_delvm,
       "tag|id", "delete a VM snapshot from its tag or id" },
+    { "singlestep", "s?", do_singlestep,
+      "[off]", "run emulation in singlestep mode or switch to normal mode", },
     { "stop", "", do_stop,
       "", "stop emulation", },
     { "c|cont", "", do_cont,

Index: trunk/target-i386/translate.c
===================================================================

target-i386/translate.c +5 -0
@@ -7651,6 +7651,11 @@
             gen_eob(dc);
             break;
         }
+        if (vm_singlestep) {
+            gen_jmp_im(pc_ptr - dc->cs_base);
+            gen_eob(dc);
+            break;
+        }
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/target-arm/translate.c
===================================================================

target-arm/translate.c +1 -1
@@ -8788,7 +8788,7 @@
          * ensures prefetch aborts occur at the right place.  */
         num_insns ++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !env->singlestep_enabled && !vm_singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
 

Index: trunk/target-m68k/translate.c
===================================================================

target-m68k/translate.c +1 -1
@@ -3030,7 +3030,7 @@
 	disas_m68k_insn(env, dc);
         num_insns++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !env->singlestep_enabled && !vm_singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 

Index: trunk/target-sparc/translate.c
===================================================================

target-sparc/translate.c +1 -1
@@ -4858,7 +4858,7 @@
             break;
         /* if single step mode, we generate only one instruction and
            generate an exception */
-        if (env->singlestep_enabled) {
+        if (env->singlestep_enabled || vm_singlestep) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
             tcg_gen_exit_tb(0);
             break;

Index: trunk/qemu-doc.texi
===================================================================

qemu-doc.texi +7 -0
@@ -1100,6 +1100,9 @@
 @item -s
 Wait gdb connection to port 1234 (@pxref{gdb_usage}).
 
+@item -singlestep
+Run the emulation in single step mode.
+
 @item -p @var{port}
 Change gdb connection port.  @var{port} can be either a decimal number
 to specify a TCP port, or a host device (same devices as the serial port).
@@ -1463,6 +1466,10 @@
 @item delvm @var{tag}|@var{id}
 Delete the snapshot identified by @var{tag} or @var{id}.
 
+@item singlestep [off]
+Run the emulation in single step mode.
+If called with option off, the emulation returns to normal mode.
+
 @item stop
 Stop emulation.
 

Index: trunk/exec-all.h
===================================================================

exec-all.h +2 -0
@@ -381,6 +381,8 @@
 
 #endif
 
+extern int vm_singlestep;
+
 typedef void (CPUDebugExcpHandler)(CPUState *env);
 
 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);

Index: trunk/bsd-user/main.c
===================================================================

bsd-user/main.c +5 -0
@@ -33,6 +33,8 @@
 
 #define DEBUG_LOGFILE "/tmp/qemu.log"
 
+int vm_singlestep;
+
 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 extern char **environ;
@@ -378,6 +380,7 @@
            "Debug options:\n"
            "-d options   activate log (logfile=%s)\n"
            "-p pagesize  set the host page size to 'pagesize'\n"
+           "-singlestep  always run in singlestep mode\n"
            "-strace      log system calls\n"
            "\n"
            "Environment variables:\n"
@@ -500,6 +503,8 @@
                 usage();
             }
             optind++;
+        } else if (!strcmp(r, "singlestep")) {
+            vm_singlestep = 1;
         } else if (!strcmp(r, "strace")) {
             do_strace = 1;
         } else

Index: trunk/darwin-user/main.c
===================================================================

darwin-user/main.c +5 -0
@@ -41,6 +41,8 @@
 #include <mach/mach_init.h>
 #include <mach/vm_map.h>
 
+int vm_singlestep;
+
 const char *interp_prefix = "";
 
 asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000");
@@ -751,6 +753,7 @@
            "-d options   activate log (logfile='%s')\n"
            "-g wait for gdb on port 1234\n"
            "-p pagesize  set the host page size to 'pagesize'\n",
+           "-singlestep  always run in singlestep mode\n"
            TARGET_ARCH,
            TARGET_ARCH,
            interp_prefix,
@@ -842,6 +845,8 @@
 #endif
                 exit(1);
             }
+        } else if (!strcmp(r, "singlestep")) {
+            vm_singlestep = 1;
         } else
         {
             usage();

Index: trunk/linux-user/main.c
===================================================================

linux-user/main.c +5 -0
@@ -39,6 +39,8 @@
 
 char *exec_path;
 
+int vm_singlestep;
+
 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 
@@ -2217,6 +2219,7 @@
            "Debug options:\n"
            "-d options   activate log (logfile=%s)\n"
            "-p pagesize  set the host page size to 'pagesize'\n"
+           "-singlestep  always run in singlestep mode\n"
            "-strace      log system calls\n"
            "\n"
            "Environment variables:\n"
@@ -2359,6 +2362,8 @@
             }
         } else if (!strcmp(r, "drop-ld-preload")) {
             (void) envlist_unsetenv(envlist, "LD_PRELOAD");
+        } else if (!strcmp(r, "singlestep")) {
+            vm_singlestep = 1;
         } else if (!strcmp(r, "strace")) {
             do_strace = 1;
         } else
Signature · 2 lines
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
[email protected]                 http://www.aurel32.net
#14 lore raw
Quoted 3 lines · Aurelien Jarno

Given those explanations and the comments from other people, I am fine with this option. I still have some comments though (see below).

Please see my comments and an updated patch below.

Quoted 18 lines

vl.c 2009-03-13 17:08:01.000000000 +0100 line 214

Quoted 12 lines

...
Index: trunk/vl.c
===================================================================

vl.c 2009-03-13 17:08:01.000000000 +0100 renamed from vl.c 2009-03-13 17:07:47.000000000 +0100 +1 -0
@@ -211,6 +211,7 @@
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int vm_running;
+int vm_singlestep;

You create a new variable. By the way, I think that calling it singlestep is better, and matches the naming of other options variable (like daemonize, graphic_rotate). You should define it to a default value of 0.

Calling those option variables option_singlestep, option_daemonize might even be a better solution...

I called it vm_singlestep because it is somehow similar to vm_running. It is a variable which indicates a certain state of QEMU's VM. Nevertheless I renamed it to singlestep in my new patch.

The default value is already 0 because all globals in C/C++ have this default value (BSS segment). An explicit value just increases the size of the executable (only by 4 (or 8) bytes in this case, I admit).

Today, there is no consistent usage of global default values. Some globals are explicitly set to zero, others not. I personally use explicit default values only when they are needed (!= 0).

Please feel free to add a "= 0" if you think this should be QEMU's standard.

Quoted 10 lines
Quoted 10 lines
vl.c 2009-03-13 17:08:01.000000000 +0100 renamed from vl.c 2009-03-13 17:07:47.000000000 +0100 +1 -0
@@ -4221,6 +4223,7 @@
 QEMU_OPTION_parallel,
 QEMU_OPTION_monitor,
 QEMU_OPTION_pidfile,
+ QEMU_OPTION_singlestep,
 QEMU_OPTION_S,
 QEMU_OPTION_s,
 QEMU_OPTION_p,
@@ -4345,6 +4348,7 @@
 { "parallel", HAS_ARG, QEMU_OPTION_parallel },
Quoted 8 lines

vl.c 2009-03-13 17:08:01.000000000 +0100 line 4354

Quoted 6 lines
vl.c 2009-03-13 17:08:01.000000000 +0100 renamed from vl.c 2009-03-13 17:07:47.000000000 +0100 +1 -0
 { "monitor", HAS_ARG, QEMU_OPTION_monitor },
 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
+ { "singlestep", 0, QEMU_OPTION_singlestep },
 { "S", 0, QEMU_OPTION_S },
 { "s", 0, QEMU_OPTION_s },
 { "p", HAS_ARG, QEMU_OPTION_p },

This option is never parsed, so the -singlestep option doesn't work.

True. The parser code got lost somewhere from my first to this incomplete patch
because of many, many merges in the meantime.

The new patch fixes this.

So I hope this will be the last iteration and the patch will finally find its
way to QEMU trunk.

Regards

Stefan

Add new command line option -singlestep for tcg single stepping.

This replaces a compile time option for some targets and adds this feature to targets which did not have a compile time option.

Add monitor command to enable or disable single step mode.

Modify monitor command "info status" to display single step mode.

bsd-user/main.c +5 -0
Index: trunk/bsd-user/main.c
===================================================================
@@ -33,6 +33,8 @@
 
 #define DEBUG_LOGFILE "/tmp/qemu.log"
 
+int singlestep;
+
 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 extern char **environ;
@@ -378,6 +380,7 @@
            "Debug options:\n"
            "-d options   activate log (logfile=%s)\n"
            "-p pagesize  set the host page size to 'pagesize'\n"
+           "-singlestep  always run in singlestep mode\n"
            "-strace      log system calls\n"
            "\n"
            "Environment variables:\n"
@@ -500,6 +503,8 @@
                 usage();
             }
             optind++;
+        } else if (!strcmp(r, "singlestep")) {
+            singlestep = 1;
         } else if (!strcmp(r, "strace")) {
             do_strace = 1;
         } else
darwin-user/main.c +5 -0
Index: trunk/darwin-user/main.c
===================================================================
@@ -41,6 +41,8 @@
 #include <mach/mach_init.h>
 #include <mach/vm_map.h>
 
+int singlestep;
+
 const char *interp_prefix = "";
 
 asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000");
@@ -751,6 +753,7 @@
            "-d options   activate log (logfile='%s')\n"
            "-g wait for gdb on port 1234\n"
            "-p pagesize  set the host page size to 'pagesize'\n",
+           "-singlestep  always run in singlestep mode\n"
            TARGET_ARCH,
            TARGET_ARCH,
            interp_prefix,
@@ -842,6 +845,8 @@
 #endif
                 exit(1);
             }
+        } else if (!strcmp(r, "singlestep")) {
+            singlestep = 1;
         } else
         {
             usage();
exec-all.h +2 -0
Index: trunk/exec-all.h
===================================================================
@@ -381,6 +381,8 @@
 
 #endif
 
+extern int singlestep;
+
 typedef void (CPUDebugExcpHandler)(CPUState *env);
 
 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
linux-user/main.c +5 -0
Index: trunk/linux-user/main.c
===================================================================
@@ -39,6 +39,8 @@
 
 char *exec_path;
 
+int singlestep;
+
 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 
@@ -2217,6 +2219,7 @@
            "Debug options:\n"
            "-d options   activate log (logfile=%s)\n"
            "-p pagesize  set the host page size to 'pagesize'\n"
+           "-singlestep  always run in singlestep mode\n"
            "-strace      log system calls\n"
            "\n"
            "Environment variables:\n"
@@ -2359,6 +2362,8 @@
             }
         } else if (!strcmp(r, "drop-ld-preload")) {
             (void) envlist_unsetenv(envlist, "LD_PRELOAD");
+        } else if (!strcmp(r, "singlestep")) {
+            singlestep = 1;
         } else if (!strcmp(r, "strace")) {
             do_strace = 1;
         } else
monitor.c +20 -3
Index: trunk/monitor.c
===================================================================
@@ -527,6 +527,17 @@
     cpu_set_log(mask);
 }
 
+static void do_singlestep(Monitor *mon, const char *option)
+{
+    if (!option || !strcmp(option, "on")) {
+        singlestep = 1;
+    } else if (!strcmp(option, "off")) {
+        singlestep = 0;
+    } else {
+        monitor_printf(mon, "unexpected option %s\n", option);
+    }
+}
+
 static void do_stop(Monitor *mon)
 {
     vm_stop(EXCP_INTERRUPT);
@@ -1510,9 +1521,13 @@
 
 static void do_info_status(Monitor *mon)
 {
-    if (vm_running)
-       monitor_printf(mon, "VM status: running\n");
-    else
+    if (vm_running) {
+        if (singlestep) {
+            monitor_printf(mon, "VM status: running (single step mode)\n");
+        } else {
+            monitor_printf(mon, "VM status: running\n");
+        }
+    } else
        monitor_printf(mon, "VM status: paused\n");
 }
 
@@ -1643,6 +1658,8 @@
       "tag|id", "restore a VM snapshot from its tag or id" },
     { "delvm", "s", do_delvm,
       "tag|id", "delete a VM snapshot from its tag or id" },
+    { "singlestep", "s?", do_singlestep,
+      "[on|off]", "run emulation in singlestep mode or switch to normal mode", },
     { "stop", "", do_stop,
       "", "stop emulation", },
     { "c|cont", "", do_cont,
qemu-doc.texi +10 -0
Index: trunk/qemu-doc.texi
===================================================================
@@ -490,6 +490,10 @@
 @item delvm @var{tag}|@var{id}
 Delete the snapshot identified by @var{tag} or @var{id}.
 
+@item singlestep [off]
+Run the emulation in single step mode.
+If called with option off, the emulation returns to normal mode.
+
 @item stop
 Stop emulation.
 
@@ -2370,6 +2374,8 @@
 Act as if the host page size was 'pagesize' bytes
 @item -g port
 Wait gdb connection to port
+@item -singlestep
+Run the emulation in single step mode.
 @end table
 
 Environment variables:
@@ -2488,6 +2494,8 @@
 Activate log (logfile=/tmp/qemu.log)
 @item -p pagesize
 Act as if the host page size was 'pagesize' bytes
+@item -singlestep
+Run the emulation in single step mode.
 @end table
 
 @node BSD User space emulator
@@ -2550,6 +2558,8 @@
 Activate log (logfile=/tmp/qemu.log)
 @item -p pagesize
 Act as if the host page size was 'pagesize' bytes
+@item -singlestep
+Run the emulation in single step mode.
 @end table
 
 @node compilation
qemu-options.hx +7 -0
Index: trunk/qemu-options.hx
===================================================================
@@ -1209,6 +1209,13 @@
 from a script.
 ETEXI
 
+DEF("singlestep", 0, QEMU_OPTION_singlestep, \
+    "-singlestep   always run in singlestep mode\n")
+STEXI
+@item -singlestep
+Run the emulation in single step mode.
+ETEXI
+
 DEF("S", 0, QEMU_OPTION_S, \
     "-S              freeze CPU at startup (use 'c' to start execution)\n")
 STEXI
target-alpha/translate.c +4 -4
Index: trunk/target-alpha/translate.c
===================================================================
@@ -2412,11 +2412,11 @@
         if (env->singlestep_enabled) {
             gen_excp(&ctx, EXCP_DEBUG, 0);
             break;
-	}
+        }
 
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+        if (singlestep) {
+            break;
+        }
     }
     if (ret != 1 && ret != 3) {
         tcg_gen_movi_i64(cpu_pc, ctx.pc);
target-arm/translate.c +1 -0
Index: trunk/target-arm/translate.c
===================================================================
@@ -8791,6 +8791,7 @@
         num_insns ++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
              !env->singlestep_enabled &&
+             !singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
 
target-cris/translate.c +1 -0
Index: trunk/target-cris/translate.c
===================================================================
@@ -3272,6 +3272,7 @@
 			break;
 	} while (!dc->is_jmp && !dc->cpustate_changed
 		 && gen_opc_ptr < gen_opc_end
+                 && !singlestep
 		 && (dc->pc < next_page_start)
                  && num_insns < max_insns);
 
target-i386/translate.c +5 -0
Index: trunk/target-i386/translate.c
===================================================================
@@ -7651,6 +7651,11 @@
             gen_eob(dc);
             break;
         }
+        if (singlestep) {
+            gen_jmp_im(pc_ptr - dc->cs_base);
+            gen_eob(dc);
+            break;
+        }
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-m68k/translate.c +1 -0
Index: trunk/target-m68k/translate.c
===================================================================
@@ -3031,6 +3031,7 @@
         num_insns++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
              !env->singlestep_enabled &&
+             !singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 
target-mips/translate.c +3 -4
Index: trunk/target-mips/translate.c
===================================================================
@@ -38,7 +38,6 @@
 
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS
-//#define MIPS_SINGLE_STEP
 
 /* MIPS major opcodes */
 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
@@ -8140,9 +8139,9 @@
 
         if (num_insns >= max_insns)
             break;
-#if defined (MIPS_SINGLE_STEP)
-        break;
-#endif
+
+        if (singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-ppc/translate.c +1 -4
Index: trunk/target-ppc/translate.c
===================================================================
@@ -39,7 +39,6 @@
 #define GDBSTUB_SINGLE_STEP 0x4
 
 /* Include definitions for instructions classes and implementations flags */
-//#define DO_SINGLE_STEP
 //#define PPC_DEBUG_DISAS
 //#define DO_PPC_STATISTICS
 
@@ -8288,15 +8287,13 @@
             gen_exception(ctxp, POWERPC_EXCP_TRACE);
         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
                             (env->singlestep_enabled) ||
+                            singlestep ||
                             num_insns >= max_insns)) {
             /* if we reach a page boundary or are single stepping, stop
              * generation
              */
             break;
         }
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-sh4/translate.c +2 -3
Index: trunk/target-sh4/translate.c
===================================================================
@@ -1929,9 +1929,8 @@
 	    break;
         if (num_insns >= max_insns)
             break;
-#ifdef SH4_SINGLE_STEP
-	break;
-#endif
+        if (singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
target-sparc/translate.c +1 -1
Index: trunk/target-sparc/translate.c
===================================================================
@@ -4838,7 +4838,7 @@
             break;
         /* if single step mode, we generate only one instruction and
            generate an exception */
-        if (env->singlestep_enabled) {
+        if (env->singlestep_enabled || singlestep) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
             tcg_gen_exit_tb(0);
             break;
vl.c +4 -0
Index: trunk/vl.c
===================================================================
@@ -212,6 +212,7 @@
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int vm_running;
+int singlestep;
 static int autostart;
 static int rtc_utc = 1;
 static int rtc_date_offset = -1; /* -1 means no change */
@@ -4669,6 +4670,9 @@
             case QEMU_OPTION_bios:
                 bios_name = optarg;
                 break;
+            case QEMU_OPTION_singlestep:
+                singlestep = 1;
+                break;
             case QEMU_OPTION_S:
                 autostart = 0;
                 break;
#15 lore raw
Quoted 6 lines · Stefan Weil
Quoted 3 lines · Aurelien Jarno

Given those explanations and the comments from other people, I am fine with this option. I still have some comments though (see below).

Please see my comments and an updated patch below.

Thanks, applied.

Quoted 475 lines
Quoted 18 lines

vl.c 2009-03-13 17:08:01.000000000 +0100 line 214

Quoted 12 lines

...
Index: trunk/vl.c
===================================================================

vl.c 2009-03-13 17:08:01.000000000 +0100 renamed from vl.c 2009-03-13 17:07:47.000000000 +0100 +1 -0
@@ -211,6 +211,7 @@
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int vm_running;
+int vm_singlestep;

You create a new variable. By the way, I think that calling it singlestep is better, and matches the naming of other options variable (like daemonize, graphic_rotate). You should define it to a default value of 0.

Calling those option variables option_singlestep, option_daemonize might even be a better solution...

I called it vm_singlestep because it is somehow similar to vm_running. It is a variable which indicates a certain state of QEMU's VM. Nevertheless I renamed it to singlestep in my new patch.

The default value is already 0 because all globals in C/C++ have this default value (BSS segment). An explicit value just increases the size of the executable (only by 4 (or 8) bytes in this case, I admit).

Today, there is no consistent usage of global default values. Some globals are explicitly set to zero, others not. I personally use explicit default values only when they are needed (!= 0).

Please feel free to add a "= 0" if you think this should be QEMU's standard.

Quoted 10 lines
Quoted 10 lines
vl.c 2009-03-13 17:08:01.000000000 +0100 renamed from vl.c 2009-03-13 17:07:47.000000000 +0100 +1 -0
@@ -4221,6 +4223,7 @@
 QEMU_OPTION_parallel,
 QEMU_OPTION_monitor,
 QEMU_OPTION_pidfile,
+ QEMU_OPTION_singlestep,
 QEMU_OPTION_S,
 QEMU_OPTION_s,
 QEMU_OPTION_p,
@@ -4345,6 +4348,7 @@
 { "parallel", HAS_ARG, QEMU_OPTION_parallel },
Quoted 8 lines

vl.c 2009-03-13 17:08:01.000000000 +0100 line 4354

Quoted 6 lines
vl.c 2009-03-13 17:08:01.000000000 +0100 renamed from vl.c 2009-03-13 17:07:47.000000000 +0100 +1 -0
 { "monitor", HAS_ARG, QEMU_OPTION_monitor },
 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
+ { "singlestep", 0, QEMU_OPTION_singlestep },
 { "S", 0, QEMU_OPTION_S },
 { "s", 0, QEMU_OPTION_s },
 { "p", HAS_ARG, QEMU_OPTION_p },

This option is never parsed, so the -singlestep option doesn't work.

True. The parser code got lost somewhere from my first to this incomplete patch
because of many, many merges in the meantime.

The new patch fixes this.

So I hope this will be the last iteration and the patch will finally find its
way to QEMU trunk.

Regards

Stefan

Add new command line option -singlestep for tcg single stepping.

This replaces a compile time option for some targets and adds this feature to targets which did not have a compile time option.

Add monitor command to enable or disable single step mode.

Modify monitor command "info status" to display single step mode.

Index: trunk/bsd-user/main.c
===================================================================

bsd-user/main.c +5 -0
@@ -33,6 +33,8 @@
 
 #define DEBUG_LOGFILE "/tmp/qemu.log"
 
+int singlestep;
+
 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 extern char **environ;
@@ -378,6 +380,7 @@
            "Debug options:\n"
            "-d options   activate log (logfile=%s)\n"
            "-p pagesize  set the host page size to 'pagesize'\n"
+           "-singlestep  always run in singlestep mode\n"
            "-strace      log system calls\n"
            "\n"
            "Environment variables:\n"
@@ -500,6 +503,8 @@
                 usage();
             }
             optind++;
+        } else if (!strcmp(r, "singlestep")) {
+            singlestep = 1;
         } else if (!strcmp(r, "strace")) {
             do_strace = 1;
         } else

Index: trunk/darwin-user/main.c
===================================================================

darwin-user/main.c +5 -0
@@ -41,6 +41,8 @@
 #include <mach/mach_init.h>
 #include <mach/vm_map.h>
 
+int singlestep;
+
 const char *interp_prefix = "";
 
 asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000");
@@ -751,6 +753,7 @@
            "-d options   activate log (logfile='%s')\n"
            "-g wait for gdb on port 1234\n"
            "-p pagesize  set the host page size to 'pagesize'\n",
+           "-singlestep  always run in singlestep mode\n"
            TARGET_ARCH,
            TARGET_ARCH,
            interp_prefix,
@@ -842,6 +845,8 @@
 #endif
                 exit(1);
             }
+        } else if (!strcmp(r, "singlestep")) {
+            singlestep = 1;
         } else
         {
             usage();

Index: trunk/exec-all.h
===================================================================

exec-all.h +2 -0
@@ -381,6 +381,8 @@
 
 #endif
 
+extern int singlestep;
+
 typedef void (CPUDebugExcpHandler)(CPUState *env);
 
 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);

Index: trunk/linux-user/main.c
===================================================================

linux-user/main.c +5 -0
@@ -39,6 +39,8 @@
 
 char *exec_path;
 
+int singlestep;
+
 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 
@@ -2217,6 +2219,7 @@
            "Debug options:\n"
            "-d options   activate log (logfile=%s)\n"
            "-p pagesize  set the host page size to 'pagesize'\n"
+           "-singlestep  always run in singlestep mode\n"
            "-strace      log system calls\n"
            "\n"
            "Environment variables:\n"
@@ -2359,6 +2362,8 @@
             }
         } else if (!strcmp(r, "drop-ld-preload")) {
             (void) envlist_unsetenv(envlist, "LD_PRELOAD");
+        } else if (!strcmp(r, "singlestep")) {
+            singlestep = 1;
         } else if (!strcmp(r, "strace")) {
             do_strace = 1;
         } else

Index: trunk/monitor.c
===================================================================

monitor.c +20 -3
@@ -527,6 +527,17 @@
     cpu_set_log(mask);
 }
 
+static void do_singlestep(Monitor *mon, const char *option)
+{
+    if (!option || !strcmp(option, "on")) {
+        singlestep = 1;
+    } else if (!strcmp(option, "off")) {
+        singlestep = 0;
+    } else {
+        monitor_printf(mon, "unexpected option %s\n", option);
+    }
+}
+
 static void do_stop(Monitor *mon)
 {
     vm_stop(EXCP_INTERRUPT);
@@ -1510,9 +1521,13 @@
 
 static void do_info_status(Monitor *mon)
 {
-    if (vm_running)
-       monitor_printf(mon, "VM status: running\n");
-    else
+    if (vm_running) {
+        if (singlestep) {
+            monitor_printf(mon, "VM status: running (single step mode)\n");
+        } else {
+            monitor_printf(mon, "VM status: running\n");
+        }
+    } else
        monitor_printf(mon, "VM status: paused\n");
 }
 
@@ -1643,6 +1658,8 @@
       "tag|id", "restore a VM snapshot from its tag or id" },
     { "delvm", "s", do_delvm,
       "tag|id", "delete a VM snapshot from its tag or id" },
+    { "singlestep", "s?", do_singlestep,
+      "[on|off]", "run emulation in singlestep mode or switch to normal mode", },
     { "stop", "", do_stop,
       "", "stop emulation", },
     { "c|cont", "", do_cont,

Index: trunk/qemu-doc.texi
===================================================================

qemu-doc.texi +10 -0
@@ -490,6 +490,10 @@
 @item delvm @var{tag}|@var{id}
 Delete the snapshot identified by @var{tag} or @var{id}.
 
+@item singlestep [off]
+Run the emulation in single step mode.
+If called with option off, the emulation returns to normal mode.
+
 @item stop
 Stop emulation.
 
@@ -2370,6 +2374,8 @@
 Act as if the host page size was 'pagesize' bytes
 @item -g port
 Wait gdb connection to port
+@item -singlestep
+Run the emulation in single step mode.
 @end table
 
 Environment variables:
@@ -2488,6 +2494,8 @@
 Activate log (logfile=/tmp/qemu.log)
 @item -p pagesize
 Act as if the host page size was 'pagesize' bytes
+@item -singlestep
+Run the emulation in single step mode.
 @end table
 
 @node BSD User space emulator
@@ -2550,6 +2558,8 @@
 Activate log (logfile=/tmp/qemu.log)
 @item -p pagesize
 Act as if the host page size was 'pagesize' bytes
+@item -singlestep
+Run the emulation in single step mode.
 @end table
 
 @node compilation

Index: trunk/qemu-options.hx
===================================================================

qemu-options.hx +7 -0
@@ -1209,6 +1209,13 @@
 from a script.
 ETEXI
 
+DEF("singlestep", 0, QEMU_OPTION_singlestep, \
+    "-singlestep   always run in singlestep mode\n")
+STEXI
+@item -singlestep
+Run the emulation in single step mode.
+ETEXI
+
 DEF("S", 0, QEMU_OPTION_S, \
     "-S              freeze CPU at startup (use 'c' to start execution)\n")
 STEXI

Index: trunk/target-alpha/translate.c
===================================================================

target-alpha/translate.c +4 -4
@@ -2412,11 +2412,11 @@
         if (env->singlestep_enabled) {
             gen_excp(&ctx, EXCP_DEBUG, 0);
             break;
-	}
+        }
 
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
+        if (singlestep) {
+            break;
+        }
     }
     if (ret != 1 && ret != 3) {
         tcg_gen_movi_i64(cpu_pc, ctx.pc);

Index: trunk/target-arm/translate.c
===================================================================

target-arm/translate.c +1 -0
@@ -8791,6 +8791,7 @@
         num_insns ++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
              !env->singlestep_enabled &&
+             !singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
 

Index: trunk/target-cris/translate.c
===================================================================

target-cris/translate.c +1 -0
@@ -3272,6 +3272,7 @@
 			break;
 	} while (!dc->is_jmp && !dc->cpustate_changed
 		 && gen_opc_ptr < gen_opc_end
+                 && !singlestep
 		 && (dc->pc < next_page_start)
                  && num_insns < max_insns);
 

Index: trunk/target-i386/translate.c
===================================================================

target-i386/translate.c +5 -0
@@ -7651,6 +7651,11 @@
             gen_eob(dc);
             break;
         }
+        if (singlestep) {
+            gen_jmp_im(pc_ptr - dc->cs_base);
+            gen_eob(dc);
+            break;
+        }
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/target-m68k/translate.c
===================================================================

target-m68k/translate.c +1 -0
@@ -3031,6 +3031,7 @@
         num_insns++;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
              !env->singlestep_enabled &&
+             !singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 

Index: trunk/target-mips/translate.c
===================================================================

target-mips/translate.c +3 -4
@@ -38,7 +38,6 @@
 
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS
-//#define MIPS_SINGLE_STEP
 
 /* MIPS major opcodes */
 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
@@ -8140,9 +8139,9 @@
 
         if (num_insns >= max_insns)
             break;
-#if defined (MIPS_SINGLE_STEP)
-        break;
-#endif
+
+        if (singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/target-ppc/translate.c
===================================================================

target-ppc/translate.c +1 -4
@@ -39,7 +39,6 @@
 #define GDBSTUB_SINGLE_STEP 0x4
 
 /* Include definitions for instructions classes and implementations flags */
-//#define DO_SINGLE_STEP
 //#define PPC_DEBUG_DISAS
 //#define DO_PPC_STATISTICS
 
@@ -8288,15 +8287,13 @@
             gen_exception(ctxp, POWERPC_EXCP_TRACE);
         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
                             (env->singlestep_enabled) ||
+                            singlestep ||
                             num_insns >= max_insns)) {
             /* if we reach a page boundary or are single stepping, stop
              * generation
              */
             break;
         }
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/target-sh4/translate.c
===================================================================

target-sh4/translate.c +2 -3
@@ -1929,9 +1929,8 @@
 	    break;
         if (num_insns >= max_insns)
             break;
-#ifdef SH4_SINGLE_STEP
-	break;
-#endif
+        if (singlestep)
+            break;
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();

Index: trunk/target-sparc/translate.c
===================================================================

target-sparc/translate.c +1 -1
@@ -4838,7 +4838,7 @@
             break;
         /* if single step mode, we generate only one instruction and
            generate an exception */
-        if (env->singlestep_enabled) {
+        if (env->singlestep_enabled || singlestep) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
             tcg_gen_exit_tb(0);
             break;

Index: trunk/vl.c
===================================================================

vl.c +4 -0
@@ -212,6 +212,7 @@
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int vm_running;
+int singlestep;
 static int autostart;
 static int rtc_utc = 1;
 static int rtc_date_offset = -1; /* -1 means no change */
@@ -4669,6 +4670,9 @@
             case QEMU_OPTION_bios:
                 bios_name = optarg;
                 break;
+            case QEMU_OPTION_singlestep:
+                singlestep = 1;
+                break;
             case QEMU_OPTION_S:
                 autostart = 0;
                 break;
Signature · 2 lines
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
[email protected]                 http://www.aurel32.net