When jato receives SIGUSR2 all threads print their register
content and backtrace:

pkill -SIGUSR2 jato

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 arch/x86/backtrace.c   |   23 +++++++++++++++-----
 include/vm/backtrace.h |    1 +
 vm/signal.c            |   52 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/arch/x86/backtrace.c b/arch/x86/backtrace.c
index f6d77e4..6e48eff 100644
--- a/arch/x86/backtrace.c
+++ b/arch/x86/backtrace.c
@@ -222,7 +222,7 @@ static void show_registers(gregset_t gregs)
 }
 #endif
 
-void print_backtrace_and_die(int sig, siginfo_t *info, void *secret)
+void print_backtrace_from_signal(int sig, siginfo_t *info, void *secret)
 {
        ucontext_t *uc = secret;
        unsigned long eip, ebp, addr;
@@ -231,6 +231,21 @@ void print_backtrace_and_die(int sig, siginfo_t *info, 
void *secret)
        ebp     = uc->uc_mcontext.gregs[BP_REG];
        addr    = (unsigned long) info->si_addr;
 
+       show_registers(uc->uc_mcontext.gregs);
+
+       print_trace_from(eip, (void *) ebp);
+
+       trace_flush();
+}
+
+void print_backtrace_and_die(int sig, siginfo_t *info, void *secret)
+{
+       ucontext_t *uc = secret;
+       unsigned long eip, addr;
+
+       eip     = uc->uc_mcontext.gregs[IP_REG];
+       addr    = (unsigned long) info->si_addr;
+
        switch (sig) {
        case SIGSEGV:
                trace_printf("SIGSEGV at %s %08lx while accessing memory 
address %08lx.\n",
@@ -240,11 +255,7 @@ void print_backtrace_and_die(int sig, siginfo_t *info, 
void *secret)
                trace_printf("Signal %d at %s %08lx\n", sig, IP_REG_NAME, eip);
                break;
        };
-       show_registers(uc->uc_mcontext.gregs);
-
-       print_trace_from(eip, (void *) ebp);
-
-       trace_flush();
 
+       print_backtrace_from_signal(sig, info, secret);
        exit(1);
 }
diff --git a/include/vm/backtrace.h b/include/vm/backtrace.h
index 6cb2406..449d82b 100644
--- a/include/vm/backtrace.h
+++ b/include/vm/backtrace.h
@@ -6,6 +6,7 @@
 
 struct string;
 
+extern void print_backtrace_from_signal(int, siginfo_t *, void *);
 extern void print_backtrace_and_die(int, siginfo_t *, void *);
 extern void print_trace(void);
 extern void print_trace_from(unsigned long, void*);
diff --git a/vm/signal.c b/vm/signal.c
index 63fe0d9..dfab59a 100644
--- a/vm/signal.c
+++ b/vm/signal.c
@@ -35,6 +35,7 @@
 #include "vm/preload.h"
 #include "vm/signal.h"
 #include "vm/stack-trace.h"
+#include "vm/trace.h"
 
 #include "arch/signal.h"
 
@@ -44,6 +45,9 @@
 #include <stdio.h>
 
 static __thread struct register_state thread_register_state;
+static pthread_mutex_t sigusr2_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t sigusr2_cond = PTHREAD_COND_INITIALIZER;
+static bool sigusr2_sent;
 
 static unsigned long throw_arithmetic_exception(unsigned long src_addr)
 {
@@ -171,6 +175,51 @@ static void signal_handler(int sig, siginfo_t *si, void 
*ctx)
        print_backtrace_and_die(sig, si, ctx);
 }
 
+static void print_state(int sig, siginfo_t *si, void *ctx)
+{
+       struct vm_thread *self;
+       char * name;
+
+       self = vm_thread_self();
+       name = vm_thread_get_name(self);
+       trace_printf("\n[%s] :\n\n", name ? name : "(null)");
+
+       print_backtrace_from_signal(sig, si, ctx);
+       free(name);
+}
+
+static void sigusr2_handler(int sig, siginfo_t *si, void *ctx)
+{
+       pthread_mutex_lock(&sigusr2_mutex);
+
+       if (sigusr2_sent) {
+               print_state(sig, si, ctx);
+               pthread_mutex_unlock(&sigusr2_mutex);
+               pthread_cond_broadcast(&sigusr2_cond);
+               return;
+       }
+
+       sigusr2_sent = true;
+
+       struct vm_thread *thread;
+
+       vm_thread_for_each(thread) {
+               if (thread->posix_id == pthread_self()) {
+                       print_state(sig, si, ctx);
+                       continue;
+               }
+
+               if (pthread_kill(thread->posix_id, SIGUSR2) != 0)
+                       die("pthread_kill");
+
+               pthread_cond_wait(&sigusr2_cond, &sigusr2_mutex);
+       }
+
+       sigusr2_sent = false;
+
+       pthread_mutex_unlock(&sigusr2_mutex);
+}
+
 void setup_signal_handlers(void)
 {
        struct sigaction sa;
@@ -186,4 +235,7 @@ void setup_signal_handlers(void)
 
        sa.sa_sigaction = signal_handler;
        sigaction(SIGUSR1, &sa, NULL);
+
+       sa.sa_sigaction = sigusr2_handler;
+       sigaction(SIGUSR2, &sa, NULL);
 }
-- 
1.6.0.4


------------------------------------------------------------------------------
Return on Information:
Google Enterprise Search pays you back
Get the facts.
http://p.sf.net/sfu/google-dev2dev
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to