dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] pnet ChangeLog configure.in engine/jitc.c engin...


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] pnet ChangeLog configure.in engine/jitc.c engin...
Date: Sun, 01 Jun 2008 08:25:04 +0000

CVSROOT:        /cvsroot/dotgnu-pnet
Module name:    pnet
Changes by:     Klaus Treichel <ktreichel>      08/06/01 08:25:04

Modified files:
        .              : ChangeLog configure.in 
        engine         : jitc.c jitc_diag.c 

Log message:
        Use the new libjit unwind api for backtraces.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pnet/ChangeLog?cvsroot=dotgnu-pnet&r1=1.3539&r2=1.3540
http://cvs.savannah.gnu.org/viewcvs/pnet/configure.in?cvsroot=dotgnu-pnet&r1=1.229&r2=1.230
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc.c?cvsroot=dotgnu-pnet&r1=1.81&r2=1.82
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_diag.c?cvsroot=dotgnu-pnet&r1=1.3&r2=1.4

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/ChangeLog,v
retrieving revision 1.3539
retrieving revision 1.3540
diff -u -b -r1.3539 -r1.3540
--- ChangeLog   21 Apr 2008 19:05:55 -0000      1.3539
+++ ChangeLog   1 Jun 2008 08:25:03 -0000       1.3540
@@ -1,3 +1,14 @@
+2008-06-01  Klaus Treichel  <address@hidden>
+
+       * configure.in: Add check for existence of the header execinfo.h and the
+       functions backtrace and backtrace_symbols.
+
+       * engine/jitc.c (ILJitBacktrace): Add helper function for printing
+       backtraces in gdb.
+
+       * engine/jitc_diag.c (_ILJitGetCallingMethod): Rewrite to use the new
+       libjit unwind api.
+
 2008-04-21  Aleksey Demakov  <address@hidden>
 
        * engine/jitc.c: add ILJitTraceIn and ILJitTraceOut functions.

Index: configure.in
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/configure.in,v
retrieving revision 1.229
retrieving revision 1.230
diff -u -b -r1.229 -r1.230
--- configure.in        9 Dec 2007 21:17:20 -0000       1.229
+++ configure.in        1 Jun 2008 08:25:04 -0000       1.230
@@ -422,6 +422,7 @@
 [[#ifdef HAVE_CURSES_H
 #include <curses.h>
 #endif]])
+AC_CHECK_HEADERS(execinfo.h)
 
 dnl Collect up the libraries that we need for termcap access.
 AC_SUBST(TERMCAPLIBS)
@@ -633,6 +634,7 @@
     AC_DEFINE(HAVE_GETTIMEOFDAY, 1, [Define whether gettimeofday is available 
on this system])
 ])
 AC_FUNC_ALLOCA
+AC_CHECK_FUNCS(backtrace backtrace_symbols)
 
 AC_MSG_CHECKING([whether to use enhanced profiler])
 AC_ARG_ENABLE(enhanced-profiling,

Index: engine/jitc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -b -r1.81 -r1.82
--- engine/jitc.c       21 Apr 2008 19:05:56 -0000      1.81
+++ engine/jitc.c       1 Jun 2008 08:25:04 -0000       1.82
@@ -36,6 +36,10 @@
 #include "lib_defs.h"
 #include "jitc_gen.h"
 #include "interlocked.h"
+/* Include header for backtrace support */
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -4697,6 +4701,158 @@
        }
 }
 
+/*
+ * This is a helper function for displaying backtraces in gdb.
+ * gdb is using debug information for determining the current
+ * frame address and return addresses.
+ * Since libjit is not emitting debug information gdb doesn't
+ * know what the frame looks like in jitted functions and shows
+ * rubbish as soon as the first frame of a jitted function is
+ * encounterd.
+ * This is the reason for $fp (the current frame pointer in gdb)
+ * being incorrect.
+ * On some archs functions in foreign shared libraries might be
+ * compiled so that their frame is different than the frame
+ * emitted by libjit do its safest to do the following:
+ * 1. show the gdb backtrace
+ * 2. Select the first frame without function information with fr n
+ *    where n is the number in front of that frame shown in gdb.
+ * 3. enter call ILJitBacktrace($rbp, $pc, n)
+ *    where n is the number of frames you want to see.
+ *    $rbp is the frame pointer register on X86_64. On x86 replace
+ *    $rbp with $ebp.
+ *
+ * This is for libjit in native mode. If you are using libjit in 
+ * interpreter mode simply enter call ILJitBacktrace(0, 0, n)
+ *
+ * Sample gdb macro for x86
+ *
+   define iljit_bt
+   call ILJitBacktrace($ebp, $pc, $arg0)
+   end
+ *
+ * Sample gdb macro for x86_64
+ *
+   define iljit_bt
+   call ILJitBacktrace($rbp, $pc, $arg0)
+   end
+ *
+ * Sample gdb macro for libjit in interpreter mode
+ *
+   define iljit_bt
+   call ILJitBacktrace(0, 0, $arg0)
+   end
+ */
+void ILJitBacktrace(void *frame, void *pc, int numFrames)
+{
+       ILExecThread *thread;
+       ILJITCoder *coder;
+       int currentFrame = 0;
+       jit_unwind_context_t unwindContext;
+       void **returnAddresses;
+#ifdef HAVE_BACKTRACE_SYMBOLS
+       char **symbols;
+#endif
+
+       if(numFrames <= 0)
+       {
+               return;
+       }
+       thread = ILExecThreadCurrent();
+       if(thread == 0)
+       {
+               return;
+       }
+       coder = (ILJITCoder *)(thread->process->coder);
+
+       returnAddresses = (void **)alloca(sizeof(void *) * numFrames);
+
+       /* Collect the return addresses */
+       if(pc)
+       {
+               returnAddresses[0] = pc;
+               ++currentFrame;
+       }
+       if(jit_unwind_init(&unwindContext, coder->context))
+       {
+               /* I hate to do this but a backtrace is not possible without */
+               /* setting the initial frame here */
+               if(frame)
+               {
+                       unwindContext.frame = frame;
+               }
+               while(currentFrame < numFrames)
+               {
+                       returnAddresses[currentFrame] = 
jit_unwind_get_pc(&unwindContext);
+                       ++currentFrame;
+                       if(!jit_unwind_next(&unwindContext))
+                       {
+                               break;
+                       }
+               }
+       }
+       numFrames = currentFrame;
+#ifdef HAVE_BACKTRACE_SYMBOLS
+       /* Get the native symbols */
+       symbols = backtrace_symbols(returnAddresses, numFrames);
+       if(!symbols)
+       {
+               return;
+       }
+       /* Now set the method names for the jitted functions */
+       for(currentFrame = 0; currentFrame < numFrames; ++currentFrame)
+       {
+               jit_function_t function;
+
+               function = jit_function_from_pc(coder->context,
+                                                                               
returnAddresses[currentFrame], 0);
+               if(function)
+               {
+                       symbols[currentFrame] = 
_ILJitFunctionGetMethodName(function);
+               }
+       }
+       /* Now print the information */
+       for(currentFrame = 0; currentFrame < numFrames; ++currentFrame)
+       {
+               if(symbols[currentFrame])
+               {
+                       printf("%i:\t%s\n", currentFrame, 
symbols[currentFrame]);
+               }
+               else
+               {
+                       printf("%i:\t[%p]\n", currentFrame, 
returnAddresses[currentFrame]);
+               }
+       }
+       ILFree(symbols);
+#else
+       /* Print the backtrace without having information about native 
functions */
+       /* Now print the information */
+       for(currentFrame = 0; currentFrame < numFrames; ++currentFrame)
+       {
+               jit_function_t function;
+
+               function = jit_function_from_pc(coder->context,
+                                                                               
returnAddresses[currentFrame], 0);
+               if(function)
+               {
+                       char *methodName = 
_ILJitFunctionGetMethodName(function);
+                       if(methodName)
+                       {
+                               printf("%i:\t%s\n", currentFrame, methodName);
+                       }
+                       else
+                       {
+                               printf("%i:\t%s\n", currentFrame, "unnamed 
jitted function");
+                       }
+               }
+               else
+               {
+                       printf("%i:\t[%p]\n", currentFrame, 
returnAddresses[currentFrame]);
+               }
+       }
+#endif
+}
+
 #endif /* _IL_JIT_ENABLE_DEBUG */
 
 #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS)

Index: engine/jitc_diag.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_diag.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- engine/jitc_diag.c  17 Dec 2006 10:31:32 -0000      1.3
+++ engine/jitc_diag.c  1 Jun 2008 08:25:04 -0000       1.4
@@ -27,9 +27,7 @@
        ILExecProcess *process = _ILExecThreadProcess(thread);
        ILJITCoder *jitCoder;
        ILJitFunction jitFunction = 0;
-       void *callFrame = jit_get_current_frame();
-       void *returnAddress = 0;
-       void *exceptionHandler = 0;
+       jit_unwind_context_t    unwindContext;
 
        if(!process)
        {
@@ -41,31 +39,32 @@
        }
        /* Find the first callframe that has a jitFunction assigned. */
        /* This callframe is usually the jitFunction for the internalcall. */
-       do {
-               returnAddress = jit_get_return_address(callFrame);
-               if(!(callFrame = jit_get_next_frame_address(callFrame)))
+       if(!jit_unwind_init(&unwindContext, jitCoder->context))
                {
-                       /* Could not get the next frame address. */
                        return 0;
                }
-               if((jitFunction = jit_function_from_pc(jitCoder->context,
-                                                                               
          returnAddress,
-                                                                               
          &exceptionHandler)))
+       do
+       {
+               if((jitFunction = jit_unwind_get_function(&unwindContext)))
                {
                        break;
                }
-
+               if(!jit_unwind_next(&unwindContext))
+               {
+                       return 0;
+               }
        } while(1);
 
-       /* callFrame is the first frame with a jitFunction assigned. */
-       /* Now we have to find the return address frames down the stack */
-       /* with a jitFunction assigned. */
+       /* The unwind context is now at the first frame with a jitFunction */
+       /* assigned. */
+       /* Now we have to find the next frame with a jitFunction assigned. */
        while(frames > 0)
        {
-               returnAddress = jit_get_return_address(callFrame);
-               if((jitFunction = jit_function_from_pc(jitCoder->context,
-                                                                               
          returnAddress,
-                                                                               
          &exceptionHandler)))
+               if(jit_unwind_next(&unwindContext) == 0)
+               {
+                       return 0;
+               }
+               if((jitFunction = jit_unwind_get_function(&unwindContext)))
                {
                        frames--;
                        if(frames == 0)
@@ -73,11 +72,6 @@
                                break;
                        }
                }
-               if(!(callFrame = jit_get_next_frame_address(callFrame)))
-               {
-                       /* Could not get the next frame address. */
-                       return 0;
-               }
        };
        /* And we return the ILMethod assigned to that jitFunction. */
        return (ILMethod *)jit_function_get_meta(jitFunction, 
IL_JIT_META_METHOD);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]