Author: Armin Rigo <[email protected]>
Branch: py3k-faulthandler
Changeset: r87411:bc08e4bce5dd
Date: 2016-09-27 10:35 +0200
http://bitbucket.org/pypy/pypy/changeset/bc08e4bce5dd/

Log:    Port pypy to the new interface

diff --git a/pypy/module/faulthandler/cintf.py 
b/pypy/module/faulthandler/cintf.py
--- a/pypy/module/faulthandler/cintf.py
+++ b/pypy/module/faulthandler/cintf.py
@@ -1,5 +1,5 @@
 import py
-from rpython.rtyper.lltypesystem import lltype, rffi, rstr
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr
 from rpython.translator import cdir
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 
@@ -15,7 +15,8 @@
     kwargs.setdefault('compilation_info', eci)
     return rffi.llexternal(*args, **kwargs)
 
-DUMP_CALLBACK = lltype.Ptr(lltype.FuncType([], lltype.Void))
+DUMP_CALLBACK = lltype.Ptr(lltype.FuncType(
+                     [rffi.INT, rffi.SIGNEDP, lltype.Signed], lltype.Void))
 
 pypy_faulthandler_setup = direct_llexternal(
     'pypy_faulthandler_setup', [DUMP_CALLBACK], rffi.CCHARP)
@@ -33,13 +34,14 @@
     'pypy_faulthandler_is_enabled', [], rffi.INT)
 
 pypy_faulthandler_write = direct_llexternal(
-    'pypy_faulthandler_write', [rffi.CCHARP], lltype.Void)
+    'pypy_faulthandler_write', [rffi.INT, rffi.CCHARP], lltype.Void)
 
 pypy_faulthandler_write_int = direct_llexternal(
-    'pypy_faulthandler_write_int', [lltype.Signed], lltype.Void)
+    'pypy_faulthandler_write_int', [rffi.INT, lltype.Signed], lltype.Void)
 
 pypy_faulthandler_dump_traceback = direct_llexternal(
-    'pypy_faulthandler_dump_traceback', [rffi.INT, rffi.INT], lltype.Void)
+    'pypy_faulthandler_dump_traceback',
+    [rffi.INT, rffi.INT, llmemory.Address], lltype.Void)
 
 # for tests...
 
diff --git a/pypy/module/faulthandler/dumper.py 
b/pypy/module/faulthandler/dumper.py
--- a/pypy/module/faulthandler/dumper.py
+++ b/pypy/module/faulthandler/dumper.py
@@ -1,24 +1,18 @@
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rlib import rgc
-from rpython.rlib.rvmprof import enum_all_code_objs
-from rpython.rlib.rvmprof import cintf as rvmprof_cintf
+from rpython.rlib.rvmprof import traceback
 
 from pypy.interpreter.pycode import PyCode
 from pypy.module.faulthandler.cintf import pypy_faulthandler_write
 from pypy.module.faulthandler.cintf import pypy_faulthandler_write_int
 
-#
-# xxx The dumper is tied to the internals of rvmprof. xxx
-#
 
-
-MAX_FRAME_DEPTH = 100
 MAX_STRING_LENGTH = 500
 
 global_buf = lltype.malloc(rffi.CCHARP.TO, MAX_STRING_LENGTH, flavor='raw',
                            immortal=True, zero=True)
 
-def _dump(s):
+def _dump(fd, s):
     assert isinstance(s, str)
     l = len(s)
     if l >= MAX_STRING_LENGTH:
@@ -28,43 +22,34 @@
         global_buf[i] = s[i]
         i += 1
     global_buf[l] = '\x00'
-    pypy_faulthandler_write(global_buf)
+    pypy_faulthandler_write(fd, global_buf)
 
-def _dump_int(i):
-    pypy_faulthandler_write_int(i)
+def _dump_int(fd, i):
+    pypy_faulthandler_write_int(fd, i)
 
 
-def dump_code(pycode, this_code_id, search_code_id):
-    if this_code_id != search_code_id:
-        return 0
-    _dump('"')
-    _dump(pycode.co_filename)
-    _dump('" in ')
-    _dump(pycode.co_name)
-    _dump(", from line ")
-    _dump_int(pycode.co_firstlineno)
-    _dump("\n")
-    return 1
+def dump_code(pycode, loc, fd):
+    if pycode is None:
+        _dump(fd, "  File ???")
+    else:
+        _dump(fd, '  File "')
+        _dump(fd, pycode.co_filename)
+        _dump(fd, '" in ')
+        _dump(fd, pycode.co_name)
+        _dump(fd, ", from line ")
+        _dump_int(fd, pycode.co_firstlineno)
+    if loc == traceback.LOC_JITTED:
+        _dump(fd, " [jitted]")
+    elif loc == traceback.LOC_JITTED_INLINED:
+        _dump(fd, " [jit inlined]")
+    _dump(fd, "\n")
 
 
 @rgc.no_collect
-def _dump_callback():
+def _dump_callback(fd, array_p, array_length):
     """We are as careful as we can reasonably be here (i.e. not 100%,
     but hopefully close enough).  In particular, this is written as
     RPython but shouldn't allocate anything.
     """
-    _dump("Current stack (most recent call first):\n")
-
-    s = rvmprof_cintf.get_rvmprof_stack()
-    depth = 0
-    while s:
-        if depth >= MAX_FRAME_DEPTH:
-            _dump("  ...\n")
-            break
-        if s.c_kind == rvmprof_cintf.VMPROF_CODE_TAG:
-            code_id = s.c_value
-            _dump("  File ")
-            if enum_all_code_objs(PyCode, dump_code, code_id) == 0:
-                _dump("???\n")
-        s = s.c_next
-        depth += 1
+    _dump(fd, "Current stack (most recent call first):\n")
+    traceback.walk_traceback(PyCode, dump_code, fd, array_p, array_length)
diff --git a/pypy/module/faulthandler/faulthandler.c 
b/pypy/module/faulthandler/faulthandler.c
--- a/pypy/module/faulthandler/faulthandler.c
+++ b/pypy/module/faulthandler/faulthandler.c
@@ -9,6 +9,11 @@
 #include <sys/resource.h>
 #include <math.h>
 
+#include "rvmprof.h"
+
+#define MAX_FRAME_DEPTH   100
+#define FRAME_DEPTH_N     RVMPROF_TRACEBACK_ESTIMATE_N(MAX_FRAME_DEPTH)
+
 
 typedef struct sigaction _Py_sighandler_t;
 
@@ -23,8 +28,7 @@
     int initialized;
     int enabled;
     volatile int fd, all_threads;
-    void (*volatile dump_traceback)(void);
-    int _current_fd;
+    volatile pypy_faulthandler_cb_t dump_traceback;
 } fatal_error;
 
 static stack_t stack;
@@ -46,45 +50,46 @@
 static const int faulthandler_nsignals =
     sizeof(faulthandler_handlers) / sizeof(fault_handler_t);
 
-static void
-fh_write(int fd, const char *str)
+RPY_EXTERN
+void pypy_faulthandler_write(int fd, const char *str)
 {
     (void)write(fd, str, strlen(str));
 }
 
 RPY_EXTERN
-void pypy_faulthandler_write(char *str)
+void pypy_faulthandler_write_int(int fd, long value)
 {
-    fh_write(fatal_error._current_fd, str);
+    char buf[32];
+    sprintf(buf, "%ld", value);
+    pypy_faulthandler_write(fd, buf);
 }
 
+
 RPY_EXTERN
-void pypy_faulthandler_write_int(long x)
+void pypy_faulthandler_dump_traceback(int fd, int all_threads,
+                                      void *ucontext)
 {
-    char buf[32];
-    sprintf(buf, "%ld", x);
-    fh_write(fatal_error._current_fd, buf);
+    pypy_faulthandler_cb_t fn;
+    intptr_t array_p[FRAME_DEPTH_N], array_length;
+
+    /* XXX 'all_threads' ignored */
+    fn = fatal_error.dump_traceback;
+    if (fn) {
+        array_length = vmprof_get_traceback(NULL, ucontext,
+                                            array_p, FRAME_DEPTH_N);
+        fn(fd, array_p, array_length);
+    }
 }
 
-
-RPY_EXTERN
-void pypy_faulthandler_dump_traceback(int fd, int all_threads)
-{
-    fatal_error._current_fd = fd;
-
-    /* XXX 'all_threads' ignored */
-    if (fatal_error.dump_traceback)
-        fatal_error.dump_traceback();
-}
-
-void faulthandler_dump_traceback(int fd, int all_threads)
+static void
+faulthandler_dump_traceback(int fd, int all_threads, void *ucontext)
 {
     static volatile int reentrant = 0;
 
     if (reentrant)
         return;
     reentrant = 1;
-    pypy_faulthandler_dump_traceback(fd, all_threads);
+    pypy_faulthandler_dump_traceback(fd, all_threads, ucontext);
     reentrant = 0;
 }
 
@@ -103,7 +108,7 @@
    This function is signal-safe and should only call signal-safe functions. */
 
 static void
-faulthandler_fatal_error(int signum)
+faulthandler_fatal_error(int signum, siginfo_t *info, void *ucontext)
 {
     int fd = fatal_error.fd;
     int i;
@@ -123,11 +128,11 @@
         handler->enabled = 0;
     }
 
-    fh_write(fd, "Fatal Python error: ");
-    fh_write(fd, handler->name);
-    fh_write(fd, "\n\n");
+    pypy_faulthandler_write(fd, "Fatal Python error: ");
+    pypy_faulthandler_write(fd, handler->name);
+    pypy_faulthandler_write(fd, "\n\n");
 
-    faulthandler_dump_traceback(fd, fatal_error.all_threads);
+    faulthandler_dump_traceback(fd, fatal_error.all_threads, ucontext);
 
     errno = save_errno;
 #ifdef MS_WINDOWS
@@ -144,7 +149,7 @@
 
 
 RPY_EXTERN
-char *pypy_faulthandler_setup(void dump_callback(void))
+char *pypy_faulthandler_setup(pypy_faulthandler_cb_t dump_callback)
 {
     if (fatal_error.initialized)
         return NULL;
@@ -201,11 +206,11 @@
             struct sigaction action;
             fault_handler_t *handler = &faulthandler_handlers[i];
 
-            action.sa_handler = faulthandler_fatal_error;
+            action.sa_sigaction = faulthandler_fatal_error;
             sigemptyset(&action.sa_mask);
             /* Do not prevent the signal from being received from within
                its own signal handler */
-            action.sa_flags = SA_NODEFER;
+            action.sa_flags = SA_NODEFER | SA_SIGINFO;
             if (stack.ss_sp != NULL) {
                 /* Call the signal handler on an alternate signal stack
                    provided by sigaltstack() */
diff --git a/pypy/module/faulthandler/faulthandler.h 
b/pypy/module/faulthandler/faulthandler.h
--- a/pypy/module/faulthandler/faulthandler.h
+++ b/pypy/module/faulthandler/faulthandler.h
@@ -2,19 +2,24 @@
 #define PYPY_FAULTHANDLER_H
 
 #include "src/precommondefs.h"
+#include <stdint.h>
 
 
-RPY_EXTERN char *pypy_faulthandler_setup(void dump_callback(void));
+typedef void (*pypy_faulthandler_cb_t)(int fd, intptr_t *array_p,
+                                       intptr_t length);
+
+RPY_EXTERN char *pypy_faulthandler_setup(pypy_faulthandler_cb_t dump_callback);
 RPY_EXTERN void pypy_faulthandler_teardown(void);
 
 RPY_EXTERN char *pypy_faulthandler_enable(int fd, int all_threads);
 RPY_EXTERN void pypy_faulthandler_disable(void);
 RPY_EXTERN int pypy_faulthandler_is_enabled(void);
 
-RPY_EXTERN void pypy_faulthandler_write(char *);
-RPY_EXTERN void pypy_faulthandler_write_int(long);
+RPY_EXTERN void pypy_faulthandler_write(int fd, const char *str);
+RPY_EXTERN void pypy_faulthandler_write_int(int fd, long value);
 
-RPY_EXTERN void pypy_faulthandler_dump_traceback(int fd, int all_threads);
+RPY_EXTERN void pypy_faulthandler_dump_traceback(int fd, int all_threads,
+                                                 void *ucontext);
 
 
 RPY_EXTERN int pypy_faulthandler_read_null(void);
diff --git a/pypy/module/faulthandler/handler.py 
b/pypy/module/faulthandler/handler.py
--- a/pypy/module/faulthandler/handler.py
+++ b/pypy/module/faulthandler/handler.py
@@ -1,5 +1,5 @@
 import os
-from rpython.rtyper.lltypesystem import rffi
+from rpython.rtyper.lltypesystem import llmemory, rffi
 from rpython.rlib.rposix import is_valid_fd
 from rpython.rlib.rarithmetic import widen
 from rpython.rlib.objectmodel import keepalive_until_here
@@ -71,7 +71,8 @@
         self.setup()
         cintf.pypy_faulthandler_dump_traceback(
             rffi.cast(rffi.INT, fileno),
-            rffi.cast(rffi.INT, all_threads))
+            rffi.cast(rffi.INT, all_threads),
+            llmemory.NULL)
         keepalive_until_here(w_file)
 
     def finish(self):
diff --git a/rpython/rlib/rvmprof/cintf.py b/rpython/rlib/rvmprof/cintf.py
--- a/rpython/rlib/rvmprof/cintf.py
+++ b/rpython/rlib/rvmprof/cintf.py
@@ -57,7 +57,7 @@
                                             compilation_info=eci,
                                             _nowrapper=True)
     vmprof_get_traceback = rffi.llexternal("vmprof_get_traceback",
-                                  [PVMPROFSTACK, lltype.Signed,
+                                  [PVMPROFSTACK, llmemory.Address,
                                    rffi.SIGNEDP, lltype.Signed],
                                   lltype.Signed, compilation_info=eci,
                                   _nowrapper=True)
diff --git a/rpython/rlib/rvmprof/src/rvmprof.h 
b/rpython/rlib/rvmprof/src/rvmprof.h
--- a/rpython/rlib/rvmprof/src/rvmprof.h
+++ b/rpython/rlib/rvmprof/src/rvmprof.h
@@ -1,3 +1,4 @@
+#include <stdint.h>
 
 RPY_EXTERN char *vmprof_init(int, double, char *);
 RPY_EXTERN void vmprof_ignore_signals(int);
@@ -8,6 +9,6 @@
 RPY_EXTERN int vmprof_stack_append(void*, long);
 RPY_EXTERN long vmprof_stack_pop(void*);
 RPY_EXTERN void vmprof_stack_free(void*);
-RPY_EXTERN intptr_t vmprof_get_traceback(void *, intptr_t, intptr_t*, 
intptr_t);
+RPY_EXTERN intptr_t vmprof_get_traceback(void *, void *, intptr_t*, intptr_t);
 
 #define RVMPROF_TRACEBACK_ESTIMATE_N(num_entries)  (2 * (num_entries) + 4)
diff --git a/rpython/rlib/rvmprof/src/vmprof_common.h 
b/rpython/rlib/rvmprof/src/vmprof_common.h
--- a/rpython/rlib/rvmprof/src/vmprof_common.h
+++ b/rpython/rlib/rvmprof/src/vmprof_common.h
@@ -130,10 +130,11 @@
 #endif
 
 RPY_EXTERN
-intptr_t vmprof_get_traceback(void *stack, intptr_t pc,
+intptr_t vmprof_get_traceback(void *stack, void *ucontext,
                               intptr_t *result_p, intptr_t result_length)
 {
     int n;
+    intptr_t pc = ucontext ? GetPC((ucontext_t *)ucontext) : 0;
     if (stack == NULL)
         stack = get_vmprof_stack();
     n = get_stack_trace(stack, result_p, result_length - 2, pc);
diff --git a/rpython/rlib/rvmprof/traceback.py 
b/rpython/rlib/rvmprof/traceback.py
--- a/rpython/rlib/rvmprof/traceback.py
+++ b/rpython/rlib/rvmprof/traceback.py
@@ -5,7 +5,7 @@
 
 from rpython.rlib.rvmprof import cintf, rvmprof
 from rpython.rlib.objectmodel import specialize
-from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 
 
 def traceback(estimate_number_of_entries):
@@ -17,7 +17,8 @@
     size = estimate_number_of_entries * 2 + 4
     stack = cintf.get_rvmprof_stack()
     array_p = lltype.malloc(rffi.SIGNEDP.TO, size, flavor='raw')
-    array_length = _cintf.vmprof_get_traceback(stack, 0, array_p, size)
+    NULL = llmemory.NULL
+    array_length = _cintf.vmprof_get_traceback(stack, NULL, array_p, size)
     return (array_p, array_length)
 
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to