Commit 99171a52 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

[PATCH] uml: Make syscall debugging code configurable

This patch makes some debug code in the system call path configurable.
Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 810f52c6
...@@ -40,4 +40,14 @@ config GCOV ...@@ -40,4 +40,14 @@ config GCOV
If you're involved in UML kernel development and want to use gcov, If you're involved in UML kernel development and want to use gcov,
say Y. If you're unsure, say N. say Y. If you're unsure, say N.
config SYSCALL_DEBUG
bool "Enable system call debugging"
default N
depends on DEBUG_INFO
help
This adds some system debugging to UML, including keeping a ring buffer
with recent system calls and some global and per-task statistics.
If unsure, say N
endmenu endmenu
...@@ -52,7 +52,6 @@ CONFIG_BSD_PROCESS_ACCT=y ...@@ -52,7 +52,6 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set # CONFIG_AUDIT is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set # CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y CONFIG_IKCONFIG=y
...@@ -61,9 +60,10 @@ CONFIG_IKCONFIG_PROC=y ...@@ -61,9 +60,10 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_KALLSYMS=y CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_ALL is not set
CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_BASE_FULL=y
CONFIG_BASE_SMALL=0
CONFIG_FUTEX=y CONFIG_FUTEX=y
CONFIG_EPOLL=y CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LABELS=0
...@@ -240,6 +240,11 @@ CONFIG_TUN=m ...@@ -240,6 +240,11 @@ CONFIG_TUN=m
# #
# CONFIG_NET_PCMCIA is not set # CONFIG_NET_PCMCIA is not set
#
# PCMCIA network device support
#
# CONFIG_NET_PCMCIA is not set
# #
# Wan interfaces # Wan interfaces
# #
...@@ -437,3 +442,4 @@ CONFIG_FRAME_POINTER=y ...@@ -437,3 +442,4 @@ CONFIG_FRAME_POINTER=y
CONFIG_PT_PROXY=y CONFIG_PT_PROXY=y
# CONFIG_GPROF is not set # CONFIG_GPROF is not set
# CONFIG_GCOV is not set # CONFIG_GCOV is not set
# CONFIG_SYSCALL_DEBUG is not set
...@@ -18,6 +18,7 @@ obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o ...@@ -18,6 +18,7 @@ obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
obj-$(CONFIG_GPROF) += gprof_syms.o obj-$(CONFIG_GPROF) += gprof_syms.o
obj-$(CONFIG_GCOV) += gmon_syms.o obj-$(CONFIG_GCOV) += gmon_syms.o
obj-$(CONFIG_TTY_LOG) += tty_log.o obj-$(CONFIG_TTY_LOG) += tty_log.o
obj-$(CONFIG_SYSCALL_DEBUG) += syscall_user.o
obj-$(CONFIG_MODE_TT) += tt/ obj-$(CONFIG_MODE_TT) += tt/
obj-$(CONFIG_MODE_SKAS) += skas/ obj-$(CONFIG_MODE_SKAS) += skas/
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#include "kern_util.h" #include "kern_util.h"
#include "uml-config.h"
#include "syscall_user.h" #include "syscall_user.h"
#include "sysdep/ptrace.h" #include "sysdep/ptrace.h"
#include "sysdep/sigcontext.h" #include "sysdep/sigcontext.h"
...@@ -14,6 +15,11 @@ ...@@ -14,6 +15,11 @@
void handle_syscall(union uml_pt_regs *regs) void handle_syscall(union uml_pt_regs *regs)
{ {
long result; long result;
#if UML_CONFIG_SYSCALL_DEBUG
int index;
index = record_syscall_start(UPT_SYSCALL_NR(regs));
#endif
syscall_trace(regs, 0); syscall_trace(regs, 0);
result = execute_syscall_skas(regs); result = execute_syscall_skas(regs);
...@@ -21,6 +27,9 @@ void handle_syscall(union uml_pt_regs *regs) ...@@ -21,6 +27,9 @@ void handle_syscall(union uml_pt_regs *regs)
REGS_SET_SYSCALL_RETURN(regs->skas.regs, result); REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
syscall_trace(regs, 1); syscall_trace(regs, 1);
#if UML_CONFIG_SYSCALL_DEBUG
record_syscall_end(index, result);
#endif
} }
/* /*
......
...@@ -154,6 +154,22 @@ long sys_olduname(struct oldold_utsname * name) ...@@ -154,6 +154,22 @@ long sys_olduname(struct oldold_utsname * name)
return error; return error;
} }
DEFINE_SPINLOCK(syscall_lock);
static int syscall_index = 0;
int next_syscall_index(int limit)
{
int ret;
spin_lock(&syscall_lock);
ret = syscall_index;
if(++syscall_index == limit)
syscall_index = 0;
spin_unlock(&syscall_lock);
return(ret);
}
/* /*
* Overrides for Emacs so that we follow Linus's tabbing style. * Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically * Emacs will notice this stuff at the end of the file and automatically
......
...@@ -36,6 +36,54 @@ void record_syscall_end(int index, long result) ...@@ -36,6 +36,54 @@ void record_syscall_end(int index, long result)
gettimeofday(&syscall_record[index].end, NULL); gettimeofday(&syscall_record[index].end, NULL);
} }
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include <stdlib.h>
#include <sys/time.h>
#include "kern_util.h"
#include "syscall_user.h"
struct {
int syscall;
int pid;
long result;
struct timeval start;
struct timeval end;
} syscall_record[1024];
int record_syscall_start(int syscall)
{
int max, index;
max = sizeof(syscall_record)/sizeof(syscall_record[0]);
index = next_syscall_index(max);
syscall_record[index].syscall = syscall;
syscall_record[index].pid = current_pid();
syscall_record[index].result = 0xdeadbeef;
gettimeofday(&syscall_record[index].start, NULL);
return(index);
}
void record_syscall_end(int index, long result)
{
syscall_record[index].result = result;
gettimeofday(&syscall_record[index].end, NULL);
}
/* /*
* Overrides for Emacs so that we follow Linus's tabbing style. * Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically * Emacs will notice this stuff at the end of the file and automatically
......
...@@ -22,8 +22,10 @@ long execute_syscall_tt(void *r) ...@@ -22,8 +22,10 @@ long execute_syscall_tt(void *r)
long res; long res;
int syscall; int syscall;
#ifdef CONFIG_SYSCALL_DEBUG
current->thread.nsyscalls++; current->thread.nsyscalls++;
nsyscalls++; nsyscalls++;
#endif
syscall = UPT_SYSCALL_NR(&regs->regs); syscall = UPT_SYSCALL_NR(&regs->regs);
if((syscall >= NR_syscalls) || (syscall < 0)) if((syscall >= NR_syscalls) || (syscall < 0))
......
...@@ -23,11 +23,17 @@ void syscall_handler_tt(int sig, union uml_pt_regs *regs) ...@@ -23,11 +23,17 @@ void syscall_handler_tt(int sig, union uml_pt_regs *regs)
void *sc; void *sc;
long result; long result;
int syscall; int syscall;
#ifdef UML_CONFIG_DEBUG_SYSCALL
int index;
#endif
syscall = UPT_SYSCALL_NR(regs); syscall = UPT_SYSCALL_NR(regs);
sc = UPT_SC(regs); sc = UPT_SC(regs);
SC_START_SYSCALL(sc); SC_START_SYSCALL(sc);
#ifdef UML_CONFIG_DEBUG_SYSCALL
index = record_syscall_start(syscall);
#endif
syscall_trace(regs, 0); syscall_trace(regs, 0);
result = execute_syscall_tt(regs); result = execute_syscall_tt(regs);
...@@ -39,6 +45,9 @@ void syscall_handler_tt(int sig, union uml_pt_regs *regs) ...@@ -39,6 +45,9 @@ void syscall_handler_tt(int sig, union uml_pt_regs *regs)
SC_SET_SYSCALL_RETURN(sc, result); SC_SET_SYSCALL_RETURN(sc, result);
syscall_trace(regs, 1); syscall_trace(regs, 1);
#ifdef UML_CONFIG_DEBUG_SYSCALL
record_syscall_end(index, result);
#endif
} }
void do_sigtrap(void *task) void do_sigtrap(void *task)
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <string.h> #include <string.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include <linux/ptrace.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/wait.h> #include <sys/wait.h>
#include "user.h" #include "user.h"
...@@ -187,7 +186,10 @@ int tracer(int (*init_proc)(void *), void *sp) ...@@ -187,7 +186,10 @@ int tracer(int (*init_proc)(void *), void *sp)
int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0; int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
int proc_id = 0, n, err, old_tracing = 0, strace = 0; int proc_id = 0, n, err, old_tracing = 0, strace = 0;
int local_using_sysemu = 0; int local_using_sysemu = 0;
#ifdef UML_CONFIG_SYSCALL_DEBUG
unsigned long eip = 0;
int last_index;
#endif
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
setup_tracer_winch(); setup_tracer_winch();
tracing_pid = os_getpid(); tracing_pid = os_getpid();
...@@ -278,6 +280,23 @@ int tracer(int (*init_proc)(void *), void *sp) ...@@ -278,6 +280,23 @@ int tracer(int (*init_proc)(void *), void *sp)
else if(WIFSTOPPED(status)){ else if(WIFSTOPPED(status)){
proc_id = pid_to_processor_id(pid); proc_id = pid_to_processor_id(pid);
sig = WSTOPSIG(status); sig = WSTOPSIG(status);
#ifdef UML_CONFIG_SYSCALL_DEBUG
if(signal_index[proc_id] == 1024){
signal_index[proc_id] = 0;
last_index = 1023;
}
else last_index = signal_index[proc_id] - 1;
if(((sig == SIGPROF) || (sig == SIGVTALRM) ||
(sig == SIGALRM)) &&
(signal_record[proc_id][last_index].signal == sig)&&
(signal_record[proc_id][last_index].pid == pid))
signal_index[proc_id] = last_index;
signal_record[proc_id][signal_index[proc_id]].pid = pid;
gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL);
eip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
signal_record[proc_id][signal_index[proc_id]].addr = eip;
signal_record[proc_id][signal_index[proc_id]++].signal = sig;
#endif
if(proc_id == -1){ if(proc_id == -1){
sleeping_process_signal(pid, sig); sleeping_process_signal(pid, sig);
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment