[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