aboutsummaryrefslogtreecommitdiff
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2022-10-24 22:18:09 +0200
committerLaurent Vivier <laurent@vivier.eu>2022-10-25 09:20:40 +0200
commitbd5ccd61080abf976a6a6cc2d09d31299bea0cee (patch)
tree3fce456ccb09b725ad1b32d7bfd7ab99a3529f0a /linux-user/syscall.c
parent35a2c85f7d691db7aa2c47181902ac87478eef7a (diff)
linux-user: Add guest memory layout to exception dump
When the emulation stops with a hard exception it's very useful for debugging purposes to dump the current guest memory layout (for an example see /proc/self/maps) beside the CPU registers. The open_self_maps() function provides such a memory dump, but since it's located in the syscall.c file, various changes (add #includes, make this function externally visible, ...) are needed to be able to call it from the existing EXCP_DUMP() macro. This patch takes another approach by re-defining EXCP_DUMP() to call target_exception_dump(), which is in syscall.c, consolidates the log print functions and allows to add the call to dump the memory layout. Beside a reduced code footprint, this approach keeps the changes across the various callers minimal, and keeps EXCP_DUMP() highlighted as important macro/function. Signed-off-by: Helge Deller <deller@gmx.de> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <Y1bzAWbw07WBKPxw@p100> [lv: remove pc declaration and setting] Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e985ad167f..8402c1399d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -183,6 +183,7 @@ struct file_clone_range {
#include "qapi/error.h"
#include "fd-trans.h"
#include "tcg/tcg.h"
+#include "cpu_loop-common.h"
#ifndef CLONE_IO
#define CLONE_IO 0x80000000 /* Clone io context */
@@ -8169,6 +8170,33 @@ static int is_proc_myself(const char *filename, const char *entry)
return 0;
}
+static void excp_dump_file(FILE *logfile, CPUArchState *env,
+ const char *fmt, int code)
+{
+ if (logfile) {
+ CPUState *cs = env_cpu(env);
+
+ fprintf(logfile, fmt, code);
+ fprintf(logfile, "Failing executable: %s\n", exec_path);
+ cpu_dump_state(cs, logfile, 0);
+ open_self_maps(env, fileno(logfile));
+ }
+}
+
+void target_exception_dump(CPUArchState *env, const char *fmt, int code)
+{
+ /* dump to console */
+ excp_dump_file(stderr, env, fmt, code);
+
+ /* dump to log file */
+ if (qemu_log_separate()) {
+ FILE *logfile = qemu_log_trylock();
+
+ excp_dump_file(logfile, env, fmt, code);
+ qemu_log_unlock(logfile);
+ }
+}
+
#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN || \
defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA)
static int is_proc(const char *filename, const char *entry)