Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 76162 invoked from network); 17 Apr 2007 16:11:19 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 17 Apr 2007 16:11:19 -0000 Received: (qmail 9537 invoked by uid 500); 17 Apr 2007 16:11:26 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 9440 invoked by uid 500); 17 Apr 2007 16:11:26 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 9431 invoked by uid 99); 17 Apr 2007 16:11:25 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Apr 2007 09:11:25 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Apr 2007 09:11:18 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id B566E1A983E; Tue, 17 Apr 2007 09:10:58 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r529662 - in /harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux: crash_handler.cpp crash_handler.h signals_em64t.cpp signals_ia32.cpp signals_ipf.cpp Date: Tue, 17 Apr 2007 16:10:58 -0000 To: commits@harmony.apache.org From: gshimansky@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070417161058.B566E1A983E@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: gshimansky Date: Tue Apr 17 09:10:57 2007 New Revision: 529662 URL: http://svn.apache.org/viewvc?view=rev&rev=529662 Log: Applied HARMONY-3669 [drlvm] Re-enabled GDB crash handler Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.cpp harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.h harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ipf.cpp Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.cpp URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.cpp?view=diff&rev=529662&r1=529661&r2=529662 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.cpp (original) +++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.cpp Tue Apr 17 09:10:57 2007 @@ -14,44 +14,66 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** +/** * @author Intel, Evgueni Brevnov * @version $Revision: 1.1.2.1.4.3 $ - */ + */ +#include #include #include -#include #include -#include + +#include "environment.h" #include "crash_handler.h" -static char executable[128];// prepare executable argument -static char pid[128]; // prepare pid argument as a string -static sem_t gdb_started; // prevent forking debugger more than once +static char g_executable[1024]; // Executable file name +static char g_strpid[128]; // Current pid as a string +static sem_t g_sem_started; // Prevent forking debugger more than once +static bool g_prepared = false; // Flag is set if gdb crash handler is prepared +static bool g_enabled = false; // vm.crash_handler value is stored here + #if defined (__INTEL_COMPILER) #pragma warning ( push ) #pragma warning (disable:869) #endif -static void crash_handler (int signum, siginfo_t* info, void* context) { - if (0 == sem_trywait(&gdb_started)) { - if (fork() == 0) { - fprintf(stderr, "----------------------------------------\n" - "gdb %s %s\n" - "----------------------------------------\n" - , executable, pid); fflush(stderr); - execl("/usr/bin/gdb", "gdb", executable, pid, NULL); - perror("Can't run debugger"); - } else { - // give gdb chance to start before the default handler kills the app - sleep(10); - } - } else { - // gdb was already started, - // reset the abort handler - signal(signum, 0); + + +bool is_gdb_crash_handler_enabled() +{ + if (!g_prepared) + return false; + + if (VM_Global_State::loader_env == NULL) + return g_enabled; + + return get_boolean_property("vm.crash_handler", FALSE, VM_PROPERTIES); +} + + +bool gdb_crash_handler() +{ + if (!g_prepared || + 0 != sem_trywait(&g_sem_started)) // gdb was already started + return false; + + if (fork() == 0) + { + fprintf(stderr, "----------------------------------------\n" + "gdb %s %s\n" + "----------------------------------------\n" + , g_executable, g_strpid); + fflush(stderr); + + execlp("gdb", "gdb", g_executable, g_strpid, NULL); + perror("Can't run gdb"); + } + else + { + // give gdb chance to start before the default handler kills the app + sleep(10); } } #if defined (__INTEL_COMPILER) @@ -68,21 +90,16 @@ return 0; } -static int get_pid(char pid[], int len) { - return snprintf(pid,len,"%d",getpid()); -} -void init_crash_handler() { - get_executable_name(executable, sizeof(executable)); - get_pid(pid, sizeof(pid)); - sem_init(&gdb_started, 0, 1); -} +int init_gdb_crash_handler() +{ + if (sem_init(&g_sem_started, 0, 1) != 0 || + get_executable_name(g_executable, sizeof(g_executable)) != 0) + return -1; -void install_crash_handler(int signum) { - struct sigaction sa; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = crash_handler; - sigaction(signum, &sa, NULL); -} + snprintf(g_strpid, sizeof(g_strpid), "%d", getpid()); + g_prepared = true; + assert(VM_Global_State::loader_env); + g_enabled = get_boolean_property("vm.crash_handler", FALSE, VM_PROPERTIES); +} Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.h URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.h?view=diff&rev=529662&r1=529661&r2=529662 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.h (original) +++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.h Tue Apr 17 09:10:57 2007 @@ -24,19 +24,28 @@ /** * \file - * Provides definition needed to install crash handler (from crash_handler.cpp) + * Provides definition needed to install gdb crash handler. */ /** - * Initializes the static state needed for crash handler. + * Checks if gdb crash handler is enabled and prepared. + * + * @return true if gdb crash handler is enabled and ready for use. + */ +bool is_gdb_crash_handler_enabled(); + +/** + * Initializes the static state needed for gdb crash handler. + * + * @return 0 on success or negative value on failure */ -void init_crash_handler(); +int init_gdb_crash_handler(); /** - * Installs specified signal handler to call gdb. + * Invokes gdb. * - * @param signum A signal number constant, e.g. SIGABRT or SIGSEGV + * @return true on success or false on failure */ -void install_crash_handler(int signum); +bool gdb_crash_handler(); #endif // _CRASH_HANDLER_H Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp?view=diff&rev=529662&r1=529661&r2=529662 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp (original) +++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp Tue Apr 17 09:10:57 2007 @@ -67,6 +67,7 @@ #include "exception_filter.h" #include "interpreter.h" +#include "crash_handler.h" #include "stack_dump.h" // Variables used to locate the context from the signal handler @@ -380,10 +381,16 @@ fprintf(stderr, "SIGSEGV in VM code.\n"); Registers regs; linux_ucontext_to_regs(®s, uc); + // setup default handler signal(signum, SIG_DFL); - // print stack trace - st_print_stack(®s); + + if (!is_gdb_crash_handler_enabled() || + !gdb_crash_handler()) + { + // print stack trace + st_print_stack(®s); + } } @@ -402,10 +409,16 @@ fprintf(stderr, "SIGFPE in VM code.\n"); Registers regs; linux_ucontext_to_regs(®s, uc); + // setup default handler signal(signum, SIG_DFL); - // print stack trace - st_print_stack(®s); + + if (!is_gdb_crash_handler_enabled() || + !gdb_crash_handler()) + { + // print stack trace + st_print_stack(®s); + } } /* @@ -532,10 +545,16 @@ ucontext_t *uc = (ucontext_t *)context; Registers regs; linux_ucontext_to_regs(®s, uc); + // setup default handler signal(signum, SIG_DFL); - // print stack trace - st_print_stack(®s); + + if (!is_gdb_crash_handler_enabled() || + !gdb_crash_handler()) + { + // print stack trace + st_print_stack(®s); + } } void initialize_signals() @@ -577,9 +596,8 @@ sigaction( SIGABRT, &sa, NULL); /* abort_handler installed */ - extern int get_executable_name(char*, int); - /* initialize the name of the executable (to be used by addr2line) */ - get_executable_name(executable, sizeof(executable)); + // Prepare gdb crash handler + init_gdb_crash_handler(); } //initialize_signals Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp?view=diff&rev=529662&r1=529661&r2=529662 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp (original) +++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp Tue Apr 17 09:10:57 2007 @@ -491,10 +491,16 @@ fprintf(stderr, "SIGSEGV in VM code.\n"); Registers regs; linux_ucontext_to_regs(®s, uc); + // setup default handler signal(signum, SIG_DFL); - // print stack trace - st_print_stack(®s); + + if (!is_gdb_crash_handler_enabled() || + !gdb_crash_handler()) + { + // print stack trace + st_print_stack(®s); + } } @@ -516,10 +522,16 @@ fprintf(stderr, "SIGFPE in VM code.\n"); Registers regs; linux_ucontext_to_regs(®s, uc); + // setup default handler signal(signum, SIG_DFL); - // print stack trace - st_print_stack(®s); + + if (!is_gdb_crash_handler_enabled() || + !gdb_crash_handler()) + { + // print stack trace + st_print_stack(®s); + } } void jvmti_jit_breakpoint_handler(int signum, siginfo_t* UNREF info, void* context) @@ -541,10 +553,16 @@ fprintf(stderr, "SIGTRAP in VM code.\n"); linux_ucontext_to_regs(®s, uc); + // setup default handler signal(signum, SIG_DFL); - // print stack trace - st_print_stack(®s); + + if (!is_gdb_crash_handler_enabled() || + !gdb_crash_handler()) + { + // print stack trace + st_print_stack(®s); + } } /* @@ -640,17 +658,15 @@ ucontext_t *uc = (ucontext_t *)context; linux_ucontext_to_regs(®s, uc); - // reset handler to avoid loop in case st_print_stack fails - struct sigaction sa; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - sigaction(SIGABRT, &sa, NULL); - // setup default handler signal(signum, SIG_DFL); - // print stack trace - st_print_stack(®s); + + if (!is_gdb_crash_handler_enabled() || + !gdb_crash_handler()) + { + // print stack trace + st_print_stack(®s); + } } /* @@ -779,15 +795,8 @@ sigaction( SIGABRT, &sa, NULL); /* abort_handler installed */ - extern int get_executable_name(char*, int); - /* initialize the name of the executable (to be used by addr2line) */ - get_executable_name(executable, sizeof(executable)); - - if (get_boolean_property("vm.crash_handler", FALSE, VM_PROPERTIES)) { - init_crash_handler(); - // can't install crash handler immediately, - // as we have already SIGABRT and SIGSEGV handlers - } + // Prepare gdb crash handler + init_gdb_crash_handler(); } //initialize_signals Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ipf.cpp URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ipf.cpp?view=diff&rev=529662&r1=529661&r2=529662 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ipf.cpp (original) +++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ipf.cpp Tue Apr 17 09:10:57 2007 @@ -75,10 +75,34 @@ #include -/** - * the saved copy of the executable name. - */ -static char executable[1024]; + + +void linux_ucontext_to_regs(Registers* regs, ucontext_t* uc) +{ + memcpy(regs->gr, uc->uc_mcontext.sc_gr, sizeof(regs->gr)); + memcpy(regs->fp, uc->uc_mcontext.sc_fr, sizeof(regs->fp)); + memcpy(regs->br, uc->uc_mcontext.sc_br, sizeof(regs->br)); + + regs->preds = uc->uc_mcontext.sc_pr; + regs->nats = uc->uc_mcontext.sc_ar_rnat; + regs->pfs = uc->uc_mcontext.sc_ar_pfs; + regs->bsp = (uint64*)uc->uc_mcontext.sc_ar_bsp; + regs->ip = uc->uc_mcontext.sc_ip; +} + +void linux_regs_to_ucontext(ucontext_t* uc, Registers* regs) +{ + memcpy(uc->uc_mcontext.sc_gr, regs->gr, sizeof(regs->gr)); + memcpy(uc->uc_mcontext.sc_fr, regs->fp, sizeof(regs->fp)); + memcpy(uc->uc_mcontext.sc_br, regs->br, sizeof(regs->br)); + + uc->uc_mcontext.sc_pr = regs->preds; + uc->uc_mcontext.sc_ar_rnat = regs->nats; + uc->uc_mcontext.sc_ar_pfs = regs->pfs; + uc->uc_mcontext.sc_ar_bsp = (uint64)regs->bsp; + uc->uc_mcontext.sc_ip = regs->ip; +} + void asm_jvmti_exception_catch_callback() { // FIXME: not implemented @@ -97,9 +121,20 @@ } void abort_handler (int signum, siginfo_t* info, void* context) { - fprintf(stderr, "FIXME: abort_handler\n"); + fprintf(stderr, "SIGABRT in VM code.\n"); + Registers regs; + ucontext_t *uc = (ucontext_t *)context; + linux_ucontext_to_regs(®s, uc); + + // setup default handler signal(signum, SIG_DFL); - kill(getpid(), signum); + + if (!is_gdb_crash_handler_enabled() || + !gdb_crash_handler()) + { + // print stack trace + st_print_stack(®s); + } } @@ -110,12 +145,6 @@ abort(); } -void linux_ucontext_to_regs(Registers* regs, ucontext_t* uc) -{ - //TODO: ADD Copying of IPF registers here like it was done on ia32!! - abort(); -} - void null_java_divide_by_zero_handler(int signum, siginfo_t* UNREF info, void* context) { ucontext_t *uc = (ucontext_t *)context; @@ -136,10 +165,16 @@ fprintf(stderr, "SIGFPE in VM code.\n"); Registers regs; linux_ucontext_to_regs(®s, uc); - st_print_stack(®s); - // crash with default handler - signal(signum, 0); + // setup default handler + signal(signum, SIG_DFL); + + if (!is_gdb_crash_handler_enabled() || + !gdb_crash_handler()) + { + // print stack trace + st_print_stack(®s); + } } @@ -373,9 +408,16 @@ fprintf(stderr, "SIGSEGV in VM code.\n"); Registers regs; linux_ucontext_to_regs(®s, uc); - st_print_stack(®s); - signal(signum, 0); + // setup default handler + signal(signum, SIG_DFL); + + if (!is_gdb_crash_handler_enabled() || + !gdb_crash_handler()) + { + // print stack trace + st_print_stack(®s); + } } void initialize_signals() { @@ -416,15 +458,9 @@ sigaction( SIGABRT, &sa, NULL); /* abort_handler installed */ - extern int get_executable_name(char*, int); - /* initialize the name of the executable (to be used by addr2line) */ - get_executable_name(executable, sizeof(executable)); - - if (get_boolean_property("vm.crash_handler", FALSE, VM_PROPERTIES)) { - init_crash_handler(); - // can't install crash handler immediately, - // as we have already SIGABRT and SIGSEGV handlers - } + // Prepare gdb crash handler + init_gdb_crash_handler(); + } //initialize_signals void shutdown_signals() { @@ -445,21 +481,6 @@ bool SuspendThread(unsigned xx){ return 0; } bool ResumeThread(unsigned xx){ return 1; } - -void linux_regs_to_ucontext(ucontext_t* uc, Registers* regs) -{ -//TODO: ADD Copying of IPF registers here like it was done on ia32!! -} - -static void linux_sigcontext_to_regs(Registers* regs, sigcontext* sc) -{ -//TODO: ADD Copying of IPF registers here like it was done on ia32!! -} - -static void linux_regs_to_sigcontext(sigcontext* sc, Registers* regs) -{ -//TODO: ADD Copying of IPF registers here like it was done on ia32!! -} static bool linux_throw_from_sigcontext(ucontext_t *uc, Class* exc_clss) {