On 7/10/26 11:44, Philippe Mathieu-Daudé wrote:
Add log_raise_exception(), a common helper cpu_loop_*() can
call to log a raised exception when '-d int' is used, and
qemu_excp_name() to resolve QEMU-internal exceptions to names.
Use it in cpu_loop_exit_atomic() to log the EXCP_ATOMIC reason.
Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
---
accel/tcg/cpu-exec-common.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c
index 68077c8fd9d..2ac8380d0bb 100644
--- a/accel/tcg/cpu-exec-common.c
+++ b/accel/tcg/cpu-exec-common.c
@@ -89,6 +89,37 @@ void tcg_update_all_cflags(void)
}
}
+#define EXCP_QEMU_INTERNAL 0x10000
+
+static const char *qemu_excp_name(int excp)
+{
+ static const char *excp_name[] = {
+ [EXCP_INTERRUPT - EXCP_QEMU_INTERNAL] = "async interruption",
+ [EXCP_HLT - EXCP_QEMU_INTERNAL] = "hlt instruction",
+ [EXCP_DEBUG - EXCP_QEMU_INTERNAL] = "debug",
+ [EXCP_HALTED - EXCP_QEMU_INTERNAL] = "halted",
+ [EXCP_YIELD - EXCP_QEMU_INTERNAL] = "yield",
+ [EXCP_ATOMIC - EXCP_QEMU_INTERNAL] = "emulate atomic",
+ };
+ assert(excp >= EXCP_QEMU_INTERNAL);
+ excp -= EXCP_QEMU_INTERNAL;
+ if ((excp < ARRAY_SIZE(excp_name)) && excp_name[excp]) {
+ return excp_name[excp];
+ }
+ return "undocumented";
+}
+
+static void log_raise_exception(const CPUState *cpu, int excp)
+{
+ if (!qemu_loglevel_mask(CPU_LOG_INT)) {
+ return;
+ }
+ if (excp >= EXCP_QEMU_INTERNAL) {
+ qemu_log_mask(CPU_LOG_INT, "raise exception: 0x%x (internal: %s)\n",
+ excp, qemu_excp_name(excp));
Daniel suggested on IRC we can use target_name() here to distinguish
between different kinds of vCPUs. Alternatively we can add a
CPUClass::log_friendly_format_name() defaulting to current "%p index:%d"
but overwritable i.e. as "accel:%s target:%s cluster:%d index:%u", so
each time we log something on a vCPU context we have an unified prefix
format to parse.
+ }
+}
+
/* exit the current TB, but without causing any exception to be raised */
void cpu_loop_exit_noexc(CPUState *cpu)
{
@@ -118,5 +149,6 @@ void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc)
/* Prevent looping if already executing in a serial context. */
g_assert(!cpu_in_serial_context(cpu));
cpu->exception_index = EXCP_ATOMIC;
+ log_raise_exception(cpu, EXCP_ATOMIC);
cpu_loop_exit_restore(cpu, pc);
}