summaryrefslogtreecommitdiff
path: root/linux-user/strace.c
diff options
context:
space:
mode:
authorLaurent Vivier <laurent@vivier.eu>2011-04-07 00:25:32 +0200
committerRiku Voipio <riku.voipio@iki.fi>2011-04-26 10:15:40 +0300
commit608e55921770bbae1609135aa0c351238f57fc5f (patch)
tree1f5ee00f8c499c6df275b2de0f1342a9f3dfc0fe /linux-user/strace.c
parent05098a9315819621405eb662baddeec624127d7a (diff)
downloadqemu-608e55921770bbae1609135aa0c351238f57fc5f.tar.gz
linux-user: improve traces
Add trace details for getpid(), kill(), _llseek(), rt_sigaction(), rt_sigprocmask(), clone(). Signed-off-by: Laurent Vivier <laurent@vivier.eu> Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
Diffstat (limited to 'linux-user/strace.c')
-rw-r--r--linux-user/strace.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 8dd398b9f2..5d9bb085c7 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -9,6 +9,7 @@
#include <sys/mount.h>
#include <sys/mman.h>
#include <unistd.h>
+#include <sched.h>
#include "qemu.h"
int do_strace=0;
@@ -63,6 +64,7 @@ UNUSED static void print_string(abi_long, int);
UNUSED static void print_raw_param(const char *, abi_long, int);
UNUSED static void print_timeval(abi_ulong, int);
UNUSED static void print_number(abi_long, int);
+UNUSED static void print_signal(abi_ulong, int);
/*
* Utility functions
@@ -117,6 +119,37 @@ if( cmd == val ) { \
gemu_log("%d",cmd);
}
+static void
+print_signal(abi_ulong arg, int last)
+{
+ const char *signal_name = NULL;
+ switch(arg) {
+ case TARGET_SIGHUP: signal_name = "SIGHUP"; break;
+ case TARGET_SIGINT: signal_name = "SIGINT"; break;
+ case TARGET_SIGQUIT: signal_name = "SIGQUIT"; break;
+ case TARGET_SIGILL: signal_name = "SIGILL"; break;
+ case TARGET_SIGABRT: signal_name = "SIGABRT"; break;
+ case TARGET_SIGFPE: signal_name = "SIGFPE"; break;
+ case TARGET_SIGKILL: signal_name = "SIGKILL"; break;
+ case TARGET_SIGSEGV: signal_name = "SIGSEGV"; break;
+ case TARGET_SIGPIPE: signal_name = "SIGPIPE"; break;
+ case TARGET_SIGALRM: signal_name = "SIGALRM"; break;
+ case TARGET_SIGTERM: signal_name = "SIGTERM"; break;
+ case TARGET_SIGUSR1: signal_name = "SIGUSR1"; break;
+ case TARGET_SIGUSR2: signal_name = "SIGUSR2"; break;
+ case TARGET_SIGCHLD: signal_name = "SIGCHLD"; break;
+ case TARGET_SIGCONT: signal_name = "SIGCONT"; break;
+ case TARGET_SIGSTOP: signal_name = "SIGSTOP"; break;
+ case TARGET_SIGTTIN: signal_name = "SIGTTIN"; break;
+ case TARGET_SIGTTOU: signal_name = "SIGTTOU"; break;
+ }
+ if (signal_name == NULL) {
+ print_raw_param("%ld", arg, 1);
+ return;
+ }
+ gemu_log("%s%s", signal_name, get_comma(last));
+}
+
#ifdef TARGET_NR__newselect
static void
print_fdset(int n, abi_ulong target_fds_addr)
@@ -427,6 +460,32 @@ UNUSED static struct flags fcntl_flags[] = {
FLAG_END,
};
+UNUSED static struct flags clone_flags[] = {
+ FLAG_GENERIC(CLONE_VM),
+ FLAG_GENERIC(CLONE_FS),
+ FLAG_GENERIC(CLONE_FILES),
+ FLAG_GENERIC(CLONE_SIGHAND),
+ FLAG_GENERIC(CLONE_PTRACE),
+ FLAG_GENERIC(CLONE_VFORK),
+ FLAG_GENERIC(CLONE_PARENT),
+ FLAG_GENERIC(CLONE_THREAD),
+ FLAG_GENERIC(CLONE_NEWNS),
+ FLAG_GENERIC(CLONE_SYSVSEM),
+ FLAG_GENERIC(CLONE_SETTLS),
+ FLAG_GENERIC(CLONE_PARENT_SETTID),
+ FLAG_GENERIC(CLONE_CHILD_CLEARTID),
+ FLAG_GENERIC(CLONE_DETACHED),
+ FLAG_GENERIC(CLONE_UNTRACED),
+ FLAG_GENERIC(CLONE_CHILD_SETTID),
+ FLAG_GENERIC(CLONE_NEWUTS),
+ FLAG_GENERIC(CLONE_NEWIPC),
+ FLAG_GENERIC(CLONE_NEWUSER),
+ FLAG_GENERIC(CLONE_NEWPID),
+ FLAG_GENERIC(CLONE_NEWNET),
+ FLAG_GENERIC(CLONE_IO),
+ FLAG_END,
+};
+
/*
* print_xxx utility functions. These are used to print syscall
* parameters in certain format. All of these have parameter
@@ -669,6 +728,39 @@ print_chmod(const struct syscallname *name,
}
#endif
+#ifdef TARGET_NR_clone
+static void
+print_clone(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+#if defined(TARGET_M68K)
+ print_flags(clone_flags, arg0, 0);
+ print_raw_param("newsp=0x" TARGET_ABI_FMT_lx, arg1, 1);
+#elif defined(TARGET_SH4) || defined(TARGET_ALPHA)
+ print_flags(clone_flags, arg0, 0);
+ print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
+ print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+ print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg3, 0);
+ print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg4, 1);
+#elif defined(TARGET_CRIS)
+ print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg0, 0);
+ print_flags(clone_flags, arg1, 0);
+ print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+ print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
+ print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
+#else
+ print_flags(clone_flags, arg0, 0);
+ print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
+ print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+ print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
+ print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
+#endif
+ print_syscall_epilogue(name);
+}
+#endif
+
#ifdef TARGET_NR_creat
static void
print_creat(const struct syscallname *name,
@@ -805,6 +897,28 @@ print_linkat(const struct syscallname *name,
}
#endif
+#ifdef TARGET_NR__llseek
+static void
+print__llseek(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ const char *whence = "UNKNOWN";
+ print_syscall_prologue(name);
+ print_raw_param("%d", arg0, 0);
+ print_raw_param("%ld", arg1, 0);
+ print_raw_param("%ld", arg2, 0);
+ print_pointer(arg3, 0);
+ switch(arg4) {
+ case SEEK_SET: whence = "SEEK_SET"; break;
+ case SEEK_CUR: whence = "SEEK_CUR"; break;
+ case SEEK_END: whence = "SEEK_END"; break;
+ }
+ gemu_log("%s",whence);
+ print_syscall_epilogue(name);
+}
+#endif
+
#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) || \
defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64)
static void
@@ -875,6 +989,40 @@ print_rmdir(const struct syscallname *name,
}
#endif
+#ifdef TARGET_NR_rt_sigaction
+static void
+print_rt_sigaction(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_signal(arg0, 0);
+ print_pointer(arg1, 0);
+ print_pointer(arg2, 1);
+ print_syscall_epilogue(name);
+}
+#endif
+
+#ifdef TARGET_NR_rt_sigprocmask
+static void
+print_rt_sigprocmask(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ const char *how = "UNKNOWN";
+ print_syscall_prologue(name);
+ switch(arg0) {
+ case TARGET_SIG_BLOCK: how = "SIG_BLOCK"; break;
+ case TARGET_SIG_UNBLOCK: how = "SIG_UNBLOCK"; break;
+ case TARGET_SIG_SETMASK: how = "SIG_SETMASK"; break;
+ }
+ gemu_log("%s,",how);
+ print_pointer(arg1, 0);
+ print_pointer(arg2, 1);
+ print_syscall_epilogue(name);
+}
+#endif
+
#ifdef TARGET_NR_mknod
static void
print_mknod(const struct syscallname *name,
@@ -1298,6 +1446,19 @@ print_futex(const struct syscallname *name,
}
#endif
+#ifdef TARGET_NR_kill
+static void
+print_kill(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_raw_param("%d", arg0, 0);
+ print_signal(arg1, 1);
+ print_syscall_epilogue(name);
+}
+#endif
+
/*
* An array of all of the syscalls we know about
*/