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