aboutsummaryrefslogtreecommitdiff
path: root/contrib/plugins/lockstep.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/plugins/lockstep.c')
-rw-r--r--contrib/plugins/lockstep.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/contrib/plugins/lockstep.c b/contrib/plugins/lockstep.c
index 237543b..62981d4 100644
--- a/contrib/plugins/lockstep.c
+++ b/contrib/plugins/lockstep.c
@@ -14,7 +14,8 @@
* particular run may execute the exact same sequence of blocks. An
* asynchronous event (for example X11 graphics update) may cause a
* block to end early and a new partial block to start. This means
- * serial only test cases are a better bet. -d nochain may also help.
+ * serial only test cases are a better bet. -d nochain may also help
+ * as well as -accel tcg,one-insn-per-tb=on
*
* This code is not thread safe!
*
@@ -57,7 +58,7 @@ typedef struct {
/* The execution state we compare */
typedef struct {
uint64_t pc;
- unsigned long insn_count;
+ uint64_t insn_count;
} ExecState;
typedef struct {
@@ -100,6 +101,31 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
plugin_cleanup(id);
}
+/*
+ * g_memdup has been deprecated in Glib since 2.68 and
+ * will complain about it if you try to use it. However until
+ * glib_req_ver for QEMU is bumped we make a copy of the glib-compat
+ * handler.
+ */
+static inline gpointer g_memdup2_qemu(gconstpointer mem, gsize byte_size)
+{
+#if GLIB_CHECK_VERSION(2, 68, 0)
+ return g_memdup2(mem, byte_size);
+#else
+ gpointer new_mem;
+
+ if (mem && byte_size != 0) {
+ new_mem = g_malloc(byte_size);
+ memcpy(new_mem, mem, byte_size);
+ } else {
+ new_mem = NULL;
+ }
+
+ return new_mem;
+#endif
+}
+#define g_memdup2(m, s) g_memdup2_qemu(m, s)
+
static void report_divergance(ExecState *us, ExecState *them)
{
DivergeState divrec = { log, 0 };
@@ -134,10 +160,13 @@ static void report_divergance(ExecState *us, ExecState *them)
/* Output short log entry of going out of sync... */
if (verbose || divrec.distance == 1 || diverged) {
- g_string_printf(out,
- "@ 0x%016" PRIx64 " vs 0x%016" PRIx64
+ g_string_printf(out, "@ "
+ "0x%016" PRIx64 " (%" PRId64 ") vs "
+ "0x%016" PRIx64 " (%" PRId64 ")"
" (%d/%d since last)\n",
- us->pc, them->pc, g_slist_length(divergence_log),
+ us->pc, us->insn_count,
+ them->pc, them->insn_count,
+ g_slist_length(divergence_log),
divrec.distance);
qemu_plugin_outs(out->str);
}
@@ -146,10 +175,7 @@ static void report_divergance(ExecState *us, ExecState *them)
int i;
GSList *entry;
- g_string_printf(out,
- "Δ insn_count @ 0x%016" PRIx64
- " (%ld) vs 0x%016" PRIx64 " (%ld)\n",
- us->pc, us->insn_count, them->pc, them->insn_count);
+ g_string_printf(out, "Δ too high, we have diverged, previous insns\n");
for (entry = log, i = 0;
g_slist_next(entry) && i < 5;
@@ -162,7 +188,7 @@ static void report_divergance(ExecState *us, ExecState *them)
prev->insn_count);
}
qemu_plugin_outs(out->str);
- qemu_plugin_outs("too much divergence... giving up.");
+ qemu_plugin_outs("giving up\n");
qemu_plugin_uninstall(our_id, plugin_cleanup);
}
}
@@ -347,7 +373,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
return -1;
}
} else if (g_strcmp0(tokens[0], "sockpath") == 0) {
- sock_path = tokens[1];
+ sock_path = g_strdup(tokens[1]);
} else {
fprintf(stderr, "option parsing failed: %s\n", p);
return -1;