[pypy-commit] pypy default: try a bit harder to load vmprof at run time

fijal noreply at buildbot.pypy.org
Sat May 23 16:54:12 CEST 2015


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: 
Changeset: r77508:4a153cd19d96
Date: 2015-05-23 16:54 +0200
http://bitbucket.org/pypy/pypy/changeset/4a153cd19d96/

Log:	try a bit harder to load vmprof at run time

diff --git a/pypy/module/_vmprof/interp_vmprof.py b/pypy/module/_vmprof/interp_vmprof.py
--- a/pypy/module/_vmprof/interp_vmprof.py
+++ b/pypy/module/_vmprof/interp_vmprof.py
@@ -27,7 +27,7 @@
     include_dirs = [SRC],
     includes = ['vmprof.h', 'trampoline.h'],
     separate_module_files = [SRC.join('trampoline.asmgcc.s')],
-    libraries = ['unwind'],
+    libraries = ['dl'],
     
     post_include_bits=["""
         void pypy_vmprof_init(void);
@@ -73,6 +73,9 @@
 vmprof_disable = rffi.llexternal("vmprof_disable", [], rffi.INT,
                                  compilation_info=eci,
                                 save_err=rffi.RFFI_SAVE_ERRNO)
+vmprof_get_error = rffi.llexternal("vmprof_get_error", [], rffi.CCHARP,
+                                   compilation_info=eci,
+                                   save_err=rffi.RFFI_SAVE_ERRNO)
 
 vmprof_register_virtual_function = rffi.llexternal(
     "vmprof_register_virtual_function",
diff --git a/pypy/module/_vmprof/src/vmprof.c b/pypy/module/_vmprof/src/vmprof.c
--- a/pypy/module/_vmprof/src/vmprof.c
+++ b/pypy/module/_vmprof/src/vmprof.c
@@ -27,9 +27,10 @@
 #include <sys/types.h>
 #include <errno.h>
 #include <pthread.h>
+#include <dlfcn.h>
 
-#define UNW_LOCAL_ONLY
-#include <libunwind.h>
+//#define UNW_LOCAL_ONLY
+//#include <libunwind.h>
 
 #include "vmprof.h"
 
@@ -44,6 +45,7 @@
 static char profile_write_buffer[BUFFER_SIZE];
 static int profile_buffer_position = 0;
 void* vmprof_mainloop_func;
+char* vmprof_error = NULL;
 static ptrdiff_t mainloop_sp_offset;
 static vmprof_get_virtual_ip_t mainloop_get_virtual_ip;
 static long last_period_usec = 0;
@@ -59,6 +61,11 @@
 #define MARKER_VIRTUAL_IP '\x02'
 #define MARKER_TRAILER '\x03'
 
+int (*unw_get_reg)(unw_cursor_t*, int, unw_word_t*) = NULL;
+int (*unw_step)(unw_cursor_t*) = NULL;
+int (*unw_init_local)(unw_cursor_t *, unw_context_t *) = NULL;
+int (*unw_get_proc_info)(unw_cursor_t *, unw_proc_info_t *) = NULL;
+
 static void prof_word(long x) {
 	((long*)(profile_write_buffer + profile_buffer_position))[0] = x;
 	profile_buffer_position += sizeof(long);
@@ -342,11 +349,48 @@
  * *************************************************************
  */
 
-void vmprof_set_mainloop(void* func, ptrdiff_t sp_offset, 
+int vmprof_set_mainloop(void* func, ptrdiff_t sp_offset, 
                          vmprof_get_virtual_ip_t get_virtual_ip) {
+    void *libhandle;
+
     mainloop_sp_offset = sp_offset;
     mainloop_get_virtual_ip = get_virtual_ip;
     vmprof_mainloop_func = func;
+    if (!unw_get_reg) {
+        if (!(libhandle = dlopen("libunwind.so", RTLD_LAZY | RTLD_LOCAL))) {
+            vmprof_error = dlerror();
+            return -1;
+        }
+        if (!(unw_get_reg = dlsym(libhandle, "_ULx86_64_get_reg"))) {
+            vmprof_error = dlerror();
+            return -1;
+        }
+        if (!(unw_get_proc_info = dlsym(libhandle, "_ULx86_64_get_proc_info"))){
+            vmprof_error = dlerror();
+            return -1;
+        }
+        if (!(unw_init_local = dlsym(libhandle, "_ULx86_64_init_local"))) {
+            vmprof_error = dlerror();
+            return -1;
+        }
+        if (!(unw_step = dlsym(libhandle, "_ULx86_64_step"))) {
+            vmprof_error = dlerror();
+            return -1;
+        }
+        if (dlclose(libhandle)) {
+            vmprof_error = dlerror();
+            return -1;
+        }
+    }
+    return 0;
+}
+
+char* vmprof_get_error()
+{
+    char* res;
+    res = vmprof_error;
+    vmprof_error = NULL;
+    return res;
 }
 
 int vmprof_enable(int fd, long period_usec, int write_header, char *s,
diff --git a/pypy/module/_vmprof/src/vmprof.h b/pypy/module/_vmprof/src/vmprof.h
--- a/pypy/module/_vmprof/src/vmprof.h
+++ b/pypy/module/_vmprof/src/vmprof.h
@@ -2,11 +2,110 @@
 #define VMPROF_VMPROF_H_
 
 #include <stddef.h>
+#include <stdint.h>
+#include <ucontext.h>
+
+// copied from libunwind.h
+
+typedef enum
+  {
+    UNW_X86_64_RAX,
+    UNW_X86_64_RDX,
+    UNW_X86_64_RCX,
+    UNW_X86_64_RBX,
+    UNW_X86_64_RSI,
+    UNW_X86_64_RDI,
+    UNW_X86_64_RBP,
+    UNW_X86_64_RSP,
+    UNW_X86_64_R8,
+    UNW_X86_64_R9,
+    UNW_X86_64_R10,
+    UNW_X86_64_R11,
+    UNW_X86_64_R12,
+    UNW_X86_64_R13,
+    UNW_X86_64_R14,
+    UNW_X86_64_R15,
+    UNW_X86_64_RIP,
+#ifdef CONFIG_MSABI_SUPPORT
+    UNW_X86_64_XMM0,
+    UNW_X86_64_XMM1,
+    UNW_X86_64_XMM2,
+    UNW_X86_64_XMM3,
+    UNW_X86_64_XMM4,
+    UNW_X86_64_XMM5,
+    UNW_X86_64_XMM6,
+    UNW_X86_64_XMM7,
+    UNW_X86_64_XMM8,
+    UNW_X86_64_XMM9,
+    UNW_X86_64_XMM10,
+    UNW_X86_64_XMM11,
+    UNW_X86_64_XMM12,
+    UNW_X86_64_XMM13,
+    UNW_X86_64_XMM14,
+    UNW_X86_64_XMM15,
+    UNW_TDEP_LAST_REG = UNW_X86_64_XMM15,
+#else
+    UNW_TDEP_LAST_REG = UNW_X86_64_RIP,
+#endif
+
+    /* XXX Add other regs here */
+
+    /* frame info (read-only) */
+    UNW_X86_64_CFA,
+
+    UNW_TDEP_IP = UNW_X86_64_RIP,
+    UNW_TDEP_SP = UNW_X86_64_RSP,
+    UNW_TDEP_BP = UNW_X86_64_RBP,
+    UNW_TDEP_EH = UNW_X86_64_RAX
+  }
+x86_64_regnum_t;
+
+typedef uint64_t unw_word_t;
+
+#define UNW_TDEP_CURSOR_LEN 127
+
+typedef struct unw_cursor
+  {
+    unw_word_t opaque[UNW_TDEP_CURSOR_LEN];
+  }
+unw_cursor_t;
+
+#define UNW_REG_IP UNW_X86_64_RIP
+#define UNW_REG_SP UNW_X86_64_RSP
+
+typedef ucontext_t unw_context_t;
+
+typedef struct unw_proc_info
+  {
+    unw_word_t start_ip;	/* first IP covered by this procedure */
+    unw_word_t end_ip;		/* first IP NOT covered by this procedure */
+    unw_word_t lsda;		/* address of lang.-spec. data area (if any) */
+    unw_word_t handler;		/* optional personality routine */
+    unw_word_t gp;		/* global-pointer value for this procedure */
+    unw_word_t flags;		/* misc. flags */
+
+    int format;			/* unwind-info format (arch-specific) */
+    int unwind_info_size;	/* size of the information (if applicable) */
+    void *unwind_info;		/* unwind-info (arch-specific) */
+  }
+unw_proc_info_t;
+
+// functions copied from libunwind using dlopen
+
+extern int (*unw_get_reg)(unw_cursor_t*, int, unw_word_t*);
+extern int (*unw_step)(unw_cursor_t*);
+extern int (*unw_init_local)(unw_cursor_t *, unw_context_t *);
+extern int (*unw_get_proc_info)(unw_cursor_t *, unw_proc_info_t *);
+
+// end of copy
+
+extern char* vmprof_error;
 
 typedef void* (*vmprof_get_virtual_ip_t)(void*);
+char* vmprof_get_error();
 
 extern void* vmprof_mainloop_func;
-void vmprof_set_mainloop(void* func, ptrdiff_t sp_offset, 
+int vmprof_set_mainloop(void* func, ptrdiff_t sp_offset, 
                          vmprof_get_virtual_ip_t get_virtual_ip);
 
 void vmprof_register_virtual_function(const char* name, void* start, void* end);


More information about the pypy-commit mailing list