Author: Armin Rigo <[email protected]>
Branch: py3k-faulthandler
Changeset: r87435:4753b6674b9f
Date: 2016-09-28 23:39 +0200
http://bitbucket.org/pypy/pypy/changeset/4753b6674b9f/

Log:    tweaks, in-progress

diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -40,13 +40,14 @@
     "binascii", "_multiprocessing", '_warnings', "_collections",
     "_multibytecodec", "_continuation", "_cffi_backend",
     "_csv", "_pypyjson", "_posixsubprocess", # "cppyy", "micronumpy"
-    "faulthandler", "_jitlog",
+    "_jitlog",
 ])
 
 from rpython.jit.backend import detect_cpu
 try:
     if detect_cpu.autodetect().startswith('x86'):
         working_modules.add('_vmprof')
+        working_modules.add('faulthandler')
 except detect_cpu.ProcessorAutodetectError:
     pass
 
@@ -118,7 +119,8 @@
     "_hashlib"  : ["pypy.module._ssl.interp_ssl"],
     "_minimal_curses": ["pypy.module._minimal_curses.fficurses"],
     "_continuation": ["rpython.rlib.rstacklet"],
-    "_vmprof" : ["pypy.module._vmprof.interp_vmprof"],
+    "_vmprof"      : ["pypy.module._vmprof.interp_vmprof"],
+    "faulthandler" : ["pypy.module._vmprof.interp_vmprof"],
     "_lzma"     : ["pypy.module._lzma.interp_lzma"],
     }
 
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
@@ -51,5 +51,4 @@
     but hopefully close enough).  In particular, this is written as
     RPython but shouldn't allocate anything.
     """
-    _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,7 +9,12 @@
 #include <sys/resource.h>
 #include <math.h>
 
-#include "rvmprof.h"
+#ifdef RPYTHON_LL2CTYPES
+#  include "../../../rpython/rlib/rvmprof/src/rvmprof.h"
+#else
+#  include "rvmprof.h"
+#endif
+#include "src/threadlocal.h"
 
 #define MAX_FRAME_DEPTH   100
 #define FRAME_DEPTH_N     RVMPROF_TRACEBACK_ESTIMATE_N(MAX_FRAME_DEPTH)
@@ -59,7 +64,7 @@
 RPY_EXTERN
 void pypy_faulthandler_write_int(int fd, long value)
 {
-    char buf[32];
+    char buf[48];
     sprintf(buf, "%ld", value);
     pypy_faulthandler_write(fd, buf);
 }
@@ -72,13 +77,51 @@
     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) {
+    if (!fn)
+        return;
+
+#ifndef RPYTHON_LL2CTYPES
+    if (all_threads && _RPython_ThreadLocals_AcquireTimeout(10000) == 0) {
+        /* This is known not to be perfectly safe against segfaults if we
+           don't hold the GIL ourselves.  Too bad.  I suspect that CPython
+           has issues there too.
+        */
+        struct pypy_threadlocal_s *my, *p;
+        int blankline = 0;
+        char buf[40];
+
+        my = (struct pypy_threadlocal_s *)_RPy_ThreadLocals_Get();
+        p = _RPython_ThreadLocals_Head();
+        p = _RPython_ThreadLocals_Enum(p);
+        while (p != NULL) {
+            if (blankline)
+                pypy_faulthandler_write(fd, "\n");
+            blankline = 1;
+
+            pypy_faulthandler_write(fd, my == p ? "Current thread" : "Thread");
+            sprintf(buf, " 0x%lx", (unsigned long)p->thread_ident);
+            pypy_faulthandler_write(fd, buf);
+            pypy_faulthandler_write(fd, " (most recent call first):\n");
+
+            array_length = vmprof_get_traceback(p->vmprof_tl_stack,
+                                                my == p ? ucontext : NULL,
+                                                array_p, FRAME_DEPTH_N);
+            fn(fd, array_p, array_length);
+
+            p = _RPython_ThreadLocals_Enum(p);
+        }
+        _RPython_ThreadLocals_Release();
+    }
+    else {
+        pypy_faulthandler_write(fd, "Stack (most recent call first):\n");
         array_length = vmprof_get_traceback(NULL, ucontext,
                                             array_p, FRAME_DEPTH_N);
         fn(fd, array_p, array_length);
     }
+#else
+    pypy_faulthandler_write(fd, "(no traceback when untranslated)\n");
+#endif
 }
 
 static void
diff --git a/pypy/module/faulthandler/test/test_faulthander.py 
b/pypy/module/faulthandler/test/test_faulthander.py
--- a/pypy/module/faulthandler/test/test_faulthander.py
+++ b/pypy/module/faulthandler/test/test_faulthander.py
@@ -1,8 +1,3 @@
-from pypy.module.faulthandler import interp_faulthandler
-
-class TestFaultHandler:
-    def test_fatal_error(self, space):
-        raises(RuntimeError, interp_faulthandler.fatal_error, space, "Message")
 
 class AppTestFaultHandler:
     spaceconfig = {
diff --git a/rpython/translator/c/src/threadlocal.c 
b/rpython/translator/c/src/threadlocal.c
--- a/rpython/translator/c/src/threadlocal.c
+++ b/rpython/translator/c/src/threadlocal.c
@@ -14,11 +14,19 @@
 
 static int check_valid(void);
 
-void _RPython_ThreadLocals_Acquire(void) {
-    while (!pypy_lock_test_and_set(&pypy_threadlocal_lock, 1)) {
+int _RPython_ThreadLocals_AcquireTimeout(int max_wait_iterations) {
+    while (1) {
+        long old_value = pypy_lock_test_and_set(&pypy_threadlocal_lock, 1);
+        if (old_value == 0)
+            break;
         /* busy loop */
+        if (max_wait_iterations == 0)
+            return -1;
+        if (max_wait_iterations > 0)
+            --max_wait_iterations;
     }
     assert(check_valid());
+    return 0;
 }
 void _RPython_ThreadLocals_Release(void) {
     assert(check_valid());
@@ -59,11 +67,7 @@
 {
     /* assume that at most one pypy_threadlocal_s survived, the current one */
     struct pypy_threadlocal_s *cur;
-#ifdef USE___THREAD
-    cur = &pypy_threadlocal;
-#else
     cur = (struct pypy_threadlocal_s *)_RPy_ThreadLocals_Get();
-#endif
     if (cur && cur->ready == 42) {
         cur->next = cur->prev = &linkedlist_head;
         linkedlist_head.next = linkedlist_head.prev = cur;
diff --git a/rpython/translator/c/src/threadlocal.h 
b/rpython/translator/c/src/threadlocal.h
--- a/rpython/translator/c/src/threadlocal.h
+++ b/rpython/translator/c/src/threadlocal.h
@@ -19,8 +19,10 @@
    current thread, and if not, calls the following helper. */
 RPY_EXTERN char *_RPython_ThreadLocals_Build(void);
 
-RPY_EXTERN void _RPython_ThreadLocals_Acquire(void);
+RPY_EXTERN int _RPython_ThreadLocals_AcquireTimeout(int max_wait_iterations);
 RPY_EXTERN void _RPython_ThreadLocals_Release(void);
+#define _RPython_ThreadLocals_Acquire()  \
+    (void)_RPython_ThreadLocals_AcquireTimeout(-1)
 
 /* Must acquire/release the thread-local lock around a series of calls
    to the following function */
@@ -66,6 +68,8 @@
 
 #define RPY_THREADLOCALREF_GET(FIELD)   pypy_threadlocal.FIELD
 
+#define _RPy_ThreadLocals_Get()  (&pypy_threadlocal)
+
 
 /* ------------------------------------------------------------ */
 #else
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to