[Python-modules-commits] [faulthandler] 01/04: Import faulthandler_2.4.orig.tar.gz

Ondřej Nový onovy-guest at moszumanska.debian.org
Wed Jun 15 10:49:00 UTC 2016


This is an automated email from the git hooks/post-receive script.

onovy-guest pushed a commit to branch master
in repository faulthandler.

commit 14b3bfb994958edb27768c58d88904207dea567a
Author: Ondřej Nový <novy at ondrej.org>
Date:   Wed Jun 15 12:44:33 2016 +0200

    Import faulthandler_2.4.orig.tar.gz
---
 AUTHORS                                    |  12 +
 MANIFEST.in                                |   3 +-
 PKG-INFO                                   | 265 +-----------
 README                                     | 257 +----------
 TODO                                       |   3 +
 faulthandler.c                             | 293 ++++++++-----
 faulthandler.egg-info/PKG-INFO             |  50 +++
 faulthandler.egg-info/SOURCES.txt          |  13 +
 faulthandler.egg-info/dependency_links.txt |   1 +
 faulthandler.egg-info/top_level.txt        |   1 +
 setup.cfg                                  |   5 +
 setup.py                                   |  23 +-
 tests.py                                   | 655 +++++++++++++++++++----------
 traceback.c                                |  49 +--
 14 files changed, 758 insertions(+), 872 deletions(-)

diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..d881ae5
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,12 @@
+Authors
+=======
+
+Victor Stinner <victor.stinner at gmail.com>
+
+Contributors
+============
+
+Dan Sully <daniel at electricrain.com> - minor fixes
+Guido van Rossum <guido at dropbox.com> - enhance traceback output
+Martin (gzlist) <gzlist at googlemail.com> - improved Windows support
+
diff --git a/MANIFEST.in b/MANIFEST.in
index eb0090c..5051cf9 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,5 @@
+include AUTHORS
 include COPYING
 include MANIFEST.in
 include tests.py
-include faulthandler/faulthandler.h
+include TODO
diff --git a/PKG-INFO b/PKG-INFO
index 9c00c6c..73d6796 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,10 +1,10 @@
-Metadata-Version: 1.0
+Metadata-Version: 1.1
 Name: faulthandler
-Version: 2.0
+Version: 2.4
 Summary: Display the Python traceback on a crash
-Home-page: https://github.com/haypo/faulthandler/wiki/
+Home-page: http://faulthandler.readthedocs.org/
 Author: Victor Stinner
-Author-email: victor.stinner at haypocalc.com
+Author-email: victor.stinner at gmail.com
 License: BSD (2-clause)
 Description: +++++++++++++
         Fault handler
@@ -33,265 +33,10 @@ Description: +++++++++++++
         traceback on a crash or when Python is blocked (eg. deadlock).
         
         Website:
-        https://github.com/haypo/faulthandler/wiki/
+        http://faulthandler.readthedocs.org/
         
         faulthandler is part of Python since Python 3.3:
         http://docs.python.org/dev/library/faulthandler.html
-        
-        
-        Example
-        =======
-        
-        Example of a segmentation fault on Linux: ::
-        
-            $ python
-            >>> import faulthandler
-            >>> faulthandler.enable()
-            >>> faulthandler._sigsegv()
-            Fatal Python error: Segmentation fault
-        
-            Traceback (most recent call first):
-              File "<stdin>", line 1 in <module>
-            Segmentation fault
-        
-        
-        Installation
-        ============
-        
-        To install faulthandler module, type the following command: ::
-        
-            python setup.py install
-        
-        Then you can test your setup using the following command: ::
-        
-            python tests.py
-        
-        You need a C compiler (eg. gcc) and Python headers to build the faulthandler
-        module. Eg. on Fedora, you have to install python-devel package (sudo yum
-        install python-devel).
-        
-        
-        faulthandler module API
-        =======================
-        
-        There are 4 different ways to display the Python traceback:
-        
-         * enable(): on a crash
-         * dump_tracebacks_later(): after a timeout (useful if your program hangs)
-         * register(): by sending a signal (eg. SIGUSR1). It doesn't work on Windows.
-         * dump_traceback(): explicitly
-        
-        Fault handler state (disabled by default):
-        
-         * enable(file=sys.stderr, all_threads=False): enable the fault handler
-         * disable(): disable the fault handler
-         * is_enabled(): get the status of the fault handler
-        
-        Dump the current traceback:
-        
-         * dump_traceback(file=sys.stderr, all_threads=False): dump traceback of the
-           current thread, or of all threads if all_threads is True, into file
-         * dump_tracebacks_later(timeout, repeat=False, file=sys.stderr,
-           exit=False): dump the traceback of all threads in timeout seconds, or each
-           timeout seconds if repeat is True. If the function is called twice, the new
-           call replaces previous parameters. Exit immediatly if exit is True.
-         * cancel_dump_tracebacks_later(): cancel the previous call to
-           dump_tracebacks_later()
-        
-        dump_tracebacks_later() is implemented using the SIGALRM signal and the alarm()
-        function: if the signal handler is called during a system call, the system call
-        is interrupted (return EINTR). It it not available on Windows.
-        
-        enable() and dump_tracebacks_later() keep an internal reference to the output
-        file. Use disable() and cancel_dump_tracebacks_later() to clear this reference.
-        
-        Dump the traceback on an user signal:
-        
-         * register(signum, file=sys.stderr, all_threads=False): register an handler
-           for the signal 'signum': dump the traceback of the current thread, or of all
-           threads if all_threads is True, into file". Not available on Windows.
-         * unregister(signum): unregister the handler of the signal 'signum' registered
-           by register(). Not available on Windows.
-        
-        Functions to test the fault handler:
-        
-         * _fatal_error(message): Exit Python with a fatal error, call Py_FatalError()
-           with message.
-         * _read_null(): read from the NULL pointer (raise SIGSEGV or SIGBUS depending
-           on the platform)
-         * _sigabrt(): raise a SIGABRT signal (Aborted)
-         * _sigbus(): raise a SIGBUS signal (Bus error)
-         * _sigfpe(): raise a SIGFPE signal (Floating point exception), do a division by
-           zero
-         * _sigill(): raise a SIGILL signal (Illegal instruction)
-         * _sigsegv(): raise a SIGSEGV signal (Segmentation fault), read memory from
-           NULL (address 0)
-         * _stack_overflow(): raise a stack overflow error. Not available on all
-           platforms.
-        
-        register(), unregister(), sigbus() and sigill() are not available on all
-        operation systems.
-        
-        faulthandler.version_info is the module version as a tuple: (major, minor),
-        faulthandler.__version__ is the module version a string (e.g. "2.0").
-        
-        
-        Changelog
-        =========
-        
-        Version 2.0 (2011-05-10)
-        ------------------------
-        
-        Major changes:
-        
-         * faulthandler is now part of Python 3.3
-         * enable() handles also the SIGABRT signal
-         * Add exit option to dump_tracebacks_later(): if True, exit the program
-           on timeout after dumping the traceback
-        
-        Other changes:
-        
-         * Change default value of the all_threads argument: dump all threads by
-           default because under some rare conditions, it is not possible to get
-           the current thread
-         * Save/restore errno in signal handlers
-         * dump_tracebacks_later() always dump all threads: remove all_threads option
-         * Add faulthandler.__version__ attribute (module version as a string)
-         * faulthandler.version is now a tuple
-         * Rename:
-        
-           * dump_traceback_later() to dump_tracebacks_later()
-           * cancel_dump_traceback_later() to cancel_dump_tracebacks_later()
-           * sigsegv() to _sigsegv()
-           * sigfpe() to _sigfpe()
-           * sigbus() to _sigbus()
-           * sigill() to _sigill()
-        
-         * register() and unregister() are no more available on Windows. They were
-           useless: only SIGSEGV, SIGABRT and SIGILL can be handled by the application,
-           and these signals can only be handled by enable().
-         * Add _fatal_error(), _read_null(), _sigabrt() and _stack_overflow() test
-           functions
-         * register() uses sigaction() SA_RESTART flag to try to not interrupt the
-           current system call
-         * The fault handler calls the previous signal handler, using sigaction()
-           SA_NODEFER flag to call it immediatly
-         * enable() raises an OSError if it was not possible to register a signal
-           handler
-         * Set module size to 0, instead of -1, to be able to unload the module with
-           Python 3
-         * Fix a reference leak in dump_tracebacks_later()
-         * Fix register() if it called twice with the same signal
-         * Implement m_traverse for Python 3 to help the garbage collector
-         * Move code from faulthandler/*.c to faulthandler.c and traceback.c: the code
-           is simpler and it was easier to integrate faulthandler into Python 3.3 using
-           one file (traceback.c already existed in Python)
-         * register() uses a static list for all signals instead of reallocating memory
-           each time a new signal is registered, because the list is shared with the
-           signal handler which may be called anytime.
-        
-        Version 1.5 (2011-03-24)
-        ------------------------
-        
-         * Conform to the PEP 8:
-        
-           * Rename isenabled() to is_enabled()
-           * Rename dumpbacktrace() to dump_traceback()
-           * Rename dumpbacktrace_later() to dump_traceback_later()
-           * Rename cancel_dumpbacktrace_later() to cancel_dump_traceback_later()
-        
-         * Limit strings to 100 characters
-         * dump_traceback_later() signal handler doesn't clear its reference to the
-           file, because Py_CLEAR() is not signal safe: you have to call explicitly
-           cancel_dump_traceback_later()
-        
-        Version 1.4 (2011-02-14)
-        ------------------------
-        
-         * Add register() and unregister() functions
-         * Add optional all_threads argument to enable()
-         * Limit the backtrace to 100 threads
-         * Allocate an alternative stack for the fatal signal handler to be able to
-           display a backtrace on a stack overflow (define HAVE_SIGALTSTACK). Not
-           available on Windows.
-        
-        Version 1.3 (2011-01-31)
-        ------------------------
-        
-         * Don't compile dumpbacktrace_later() and cancel_dumpbacktrace_later() on
-           Windows because alarm() is missing
-        
-        Version 1.2 (2011-01-31)
-        ------------------------
-        
-         * Add dumpbacktrace_later() and cancel_dumpbacktrace_later() function
-         * enable() and dumpbacktrace() get an optional file argument
-         * Replace dumpbacktrace_threads() function by a new dumpbacktrace() argument:
-           dumpbacktrace(all_threads=True)
-         * enable() gets the file descriptor of sys.stderr instead of using the file
-           descriptor 2
-        
-        Version 1.1 (2011-01-03)
-        ------------------------
-        
-         * Disable the handler by default, because pkgutil may load the module and so
-           enable the handler which is unexpected
-         * Add dumpbacktrace() and dumpbacktrace_threads() functions
-         * sigill() is available on Windows thanks to Martin's patch
-         * Fix dump_ascii() for signed char type (eg. on FreeBSD)
-         * Fix tests.py for Python 2.5
-        
-        Version 1.0 (2010-12-24)
-        ------------------------
-        
-         * First public release
-        
-        
-        Status
-        ======
-        
-         * 2011-01-31: Version 1.2 tested with Python 2.5, 2.6, 2.7, 3.1 and 3.2 on
-           Debian Sid
-         * 2010-12-24: Tested with Python 2.6, 3.1 and 3.2 on Debian Sid
-         * 2010-12-24: Tested with Python 2.6 and 3.1 on Windows XP
-        
-        
-        Similar projects
-        ================
-        
-        Python debuggers:
-        
-         * tipper: write the traceback of the current thread into a file on SIGUSR1
-           signal: http://pypi.python.org/pypi/tipper/
-         * crier: write the traceback of the current thread into a file
-           (eg. /tmp/dump-<pid>) if a "request" file is created (eg. /tmp/crier-<pid>).
-           Implemented using a thread. https://gist.github.com/737056
-         * Python WAD (Wrapped Application Debugger), not update since 2001:
-           http://www.dabeaz.com/papers/Python2001/python.html
-        
-        Application fault handlers:
-        
-         * The GNU libc has a fault handler in debug/segfault.c
-         * XEmacs has a fault handler displaying the Lisp traceback
-         * RPy has a fault handler
-        
-        System-wide fault handlers:
-        
-         * Ubuntu uses Apport: https://wiki.ubuntu.com/Apport
-         * The Linux kernel logs also segfaults into /var/log/kern.log (and
-           /var/log/syslog). /proc/sys/kernel/core_pattern contols how coredumps are
-           created.
-         * Windows opens a popup on a fatal error asking if the error should be
-           reported to Microsoft
-        
-        
-        See also
-        ========
-        
-         * http://bugs.python.org/issue8863 (may 2010):
-           Display Python backtrace on SIGSEGV, SIGFPE and fatal error
-         * http://bugs.python.org/issue3999 (sept. 2008):
-           Real segmentation fault handler
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Intended Audience :: Developers
diff --git a/README b/README
index 26c4e7d..15bb80e 100644
--- a/README
+++ b/README
@@ -25,263 +25,8 @@ faulthandler is implemented in C using signal handlers to be able to dump a
 traceback on a crash or when Python is blocked (eg. deadlock).
 
 Website:
-https://github.com/haypo/faulthandler/wiki/
+http://faulthandler.readthedocs.org/
 
 faulthandler is part of Python since Python 3.3:
 http://docs.python.org/dev/library/faulthandler.html
 
-
-Example
-=======
-
-Example of a segmentation fault on Linux: ::
-
-    $ python
-    >>> import faulthandler
-    >>> faulthandler.enable()
-    >>> faulthandler._sigsegv()
-    Fatal Python error: Segmentation fault
-
-    Traceback (most recent call first):
-      File "<stdin>", line 1 in <module>
-    Segmentation fault
-
-
-Installation
-============
-
-To install faulthandler module, type the following command: ::
-
-    python setup.py install
-
-Then you can test your setup using the following command: ::
-
-    python tests.py
-
-You need a C compiler (eg. gcc) and Python headers to build the faulthandler
-module. Eg. on Fedora, you have to install python-devel package (sudo yum
-install python-devel).
-
-
-faulthandler module API
-=======================
-
-There are 4 different ways to display the Python traceback:
-
- * enable(): on a crash
- * dump_tracebacks_later(): after a timeout (useful if your program hangs)
- * register(): by sending a signal (eg. SIGUSR1). It doesn't work on Windows.
- * dump_traceback(): explicitly
-
-Fault handler state (disabled by default):
-
- * enable(file=sys.stderr, all_threads=False): enable the fault handler
- * disable(): disable the fault handler
- * is_enabled(): get the status of the fault handler
-
-Dump the current traceback:
-
- * dump_traceback(file=sys.stderr, all_threads=False): dump traceback of the
-   current thread, or of all threads if all_threads is True, into file
- * dump_tracebacks_later(timeout, repeat=False, file=sys.stderr,
-   exit=False): dump the traceback of all threads in timeout seconds, or each
-   timeout seconds if repeat is True. If the function is called twice, the new
-   call replaces previous parameters. Exit immediatly if exit is True.
- * cancel_dump_tracebacks_later(): cancel the previous call to
-   dump_tracebacks_later()
-
-dump_tracebacks_later() is implemented using the SIGALRM signal and the alarm()
-function: if the signal handler is called during a system call, the system call
-is interrupted (return EINTR). It it not available on Windows.
-
-enable() and dump_tracebacks_later() keep an internal reference to the output
-file. Use disable() and cancel_dump_tracebacks_later() to clear this reference.
-
-Dump the traceback on an user signal:
-
- * register(signum, file=sys.stderr, all_threads=False): register an handler
-   for the signal 'signum': dump the traceback of the current thread, or of all
-   threads if all_threads is True, into file". Not available on Windows.
- * unregister(signum): unregister the handler of the signal 'signum' registered
-   by register(). Not available on Windows.
-
-Functions to test the fault handler:
-
- * _fatal_error(message): Exit Python with a fatal error, call Py_FatalError()
-   with message.
- * _read_null(): read from the NULL pointer (raise SIGSEGV or SIGBUS depending
-   on the platform)
- * _sigabrt(): raise a SIGABRT signal (Aborted)
- * _sigbus(): raise a SIGBUS signal (Bus error)
- * _sigfpe(): raise a SIGFPE signal (Floating point exception), do a division by
-   zero
- * _sigill(): raise a SIGILL signal (Illegal instruction)
- * _sigsegv(): raise a SIGSEGV signal (Segmentation fault), read memory from
-   NULL (address 0)
- * _stack_overflow(): raise a stack overflow error. Not available on all
-   platforms.
-
-register(), unregister(), sigbus() and sigill() are not available on all
-operation systems.
-
-faulthandler.version_info is the module version as a tuple: (major, minor),
-faulthandler.__version__ is the module version a string (e.g. "2.0").
-
-
-Changelog
-=========
-
-Version 2.0 (2011-05-10)
-------------------------
-
-Major changes:
-
- * faulthandler is now part of Python 3.3
- * enable() handles also the SIGABRT signal
- * Add exit option to dump_tracebacks_later(): if True, exit the program
-   on timeout after dumping the traceback
-
-Other changes:
-
- * Change default value of the all_threads argument: dump all threads by
-   default because under some rare conditions, it is not possible to get
-   the current thread
- * Save/restore errno in signal handlers
- * dump_tracebacks_later() always dump all threads: remove all_threads option
- * Add faulthandler.__version__ attribute (module version as a string)
- * faulthandler.version is now a tuple
- * Rename:
-
-   * dump_traceback_later() to dump_tracebacks_later()
-   * cancel_dump_traceback_later() to cancel_dump_tracebacks_later()
-   * sigsegv() to _sigsegv()
-   * sigfpe() to _sigfpe()
-   * sigbus() to _sigbus()
-   * sigill() to _sigill()
-
- * register() and unregister() are no more available on Windows. They were
-   useless: only SIGSEGV, SIGABRT and SIGILL can be handled by the application,
-   and these signals can only be handled by enable().
- * Add _fatal_error(), _read_null(), _sigabrt() and _stack_overflow() test
-   functions
- * register() uses sigaction() SA_RESTART flag to try to not interrupt the
-   current system call
- * The fault handler calls the previous signal handler, using sigaction()
-   SA_NODEFER flag to call it immediatly
- * enable() raises an OSError if it was not possible to register a signal
-   handler
- * Set module size to 0, instead of -1, to be able to unload the module with
-   Python 3
- * Fix a reference leak in dump_tracebacks_later()
- * Fix register() if it called twice with the same signal
- * Implement m_traverse for Python 3 to help the garbage collector
- * Move code from faulthandler/*.c to faulthandler.c and traceback.c: the code
-   is simpler and it was easier to integrate faulthandler into Python 3.3 using
-   one file (traceback.c already existed in Python)
- * register() uses a static list for all signals instead of reallocating memory
-   each time a new signal is registered, because the list is shared with the
-   signal handler which may be called anytime.
-
-Version 1.5 (2011-03-24)
-------------------------
-
- * Conform to the PEP 8:
-
-   * Rename isenabled() to is_enabled()
-   * Rename dumpbacktrace() to dump_traceback()
-   * Rename dumpbacktrace_later() to dump_traceback_later()
-   * Rename cancel_dumpbacktrace_later() to cancel_dump_traceback_later()
-
- * Limit strings to 100 characters
- * dump_traceback_later() signal handler doesn't clear its reference to the
-   file, because Py_CLEAR() is not signal safe: you have to call explicitly
-   cancel_dump_traceback_later()
-
-Version 1.4 (2011-02-14)
-------------------------
-
- * Add register() and unregister() functions
- * Add optional all_threads argument to enable()
- * Limit the backtrace to 100 threads
- * Allocate an alternative stack for the fatal signal handler to be able to
-   display a backtrace on a stack overflow (define HAVE_SIGALTSTACK). Not
-   available on Windows.
-
-Version 1.3 (2011-01-31)
-------------------------
-
- * Don't compile dumpbacktrace_later() and cancel_dumpbacktrace_later() on
-   Windows because alarm() is missing
-
-Version 1.2 (2011-01-31)
-------------------------
-
- * Add dumpbacktrace_later() and cancel_dumpbacktrace_later() function
- * enable() and dumpbacktrace() get an optional file argument
- * Replace dumpbacktrace_threads() function by a new dumpbacktrace() argument:
-   dumpbacktrace(all_threads=True)
- * enable() gets the file descriptor of sys.stderr instead of using the file
-   descriptor 2
-
-Version 1.1 (2011-01-03)
-------------------------
-
- * Disable the handler by default, because pkgutil may load the module and so
-   enable the handler which is unexpected
- * Add dumpbacktrace() and dumpbacktrace_threads() functions
- * sigill() is available on Windows thanks to Martin's patch
- * Fix dump_ascii() for signed char type (eg. on FreeBSD)
- * Fix tests.py for Python 2.5
-
-Version 1.0 (2010-12-24)
-------------------------
-
- * First public release
-
-
-Status
-======
-
- * 2011-01-31: Version 1.2 tested with Python 2.5, 2.6, 2.7, 3.1 and 3.2 on
-   Debian Sid
- * 2010-12-24: Tested with Python 2.6, 3.1 and 3.2 on Debian Sid
- * 2010-12-24: Tested with Python 2.6 and 3.1 on Windows XP
-
-
-Similar projects
-================
-
-Python debuggers:
-
- * tipper: write the traceback of the current thread into a file on SIGUSR1
-   signal: http://pypi.python.org/pypi/tipper/
- * crier: write the traceback of the current thread into a file
-   (eg. /tmp/dump-<pid>) if a "request" file is created (eg. /tmp/crier-<pid>).
-   Implemented using a thread. https://gist.github.com/737056
- * Python WAD (Wrapped Application Debugger), not update since 2001:
-   http://www.dabeaz.com/papers/Python2001/python.html
-
-Application fault handlers:
-
- * The GNU libc has a fault handler in debug/segfault.c
- * XEmacs has a fault handler displaying the Lisp traceback
- * RPy has a fault handler
-
-System-wide fault handlers:
-
- * Ubuntu uses Apport: https://wiki.ubuntu.com/Apport
- * The Linux kernel logs also segfaults into /var/log/kern.log (and
-   /var/log/syslog). /proc/sys/kernel/core_pattern contols how coredumps are
-   created.
- * Windows opens a popup on a fatal error asking if the error should be
-   reported to Microsoft
-
-
-See also
-========
-
- * http://bugs.python.org/issue8863 (may 2010):
-   Display Python backtrace on SIGSEGV, SIGFPE and fatal error
- * http://bugs.python.org/issue3999 (sept. 2008):
-   Real segmentation fault handler
-
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..13cf232
--- /dev/null
+++ b/TODO
@@ -0,0 +1,3 @@
+ * sync doc
+ * write a tool to "preload" faulthandler and enable it
+
diff --git a/faulthandler.c b/faulthandler.c
index 542b7bd..447946d 100644
--- a/faulthandler.c
+++ b/faulthandler.c
@@ -7,8 +7,14 @@
 #include "Python.h"
 #include "pythread.h"
 #include <signal.h>
+#ifdef MS_WINDOWS
+#  include <windows.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#  include <sys/resource.h>
+#endif
 
-#define VERSION 0x200
+#define VERSION 0x204
 
 /* Allocate at maximum 100 MB of the stack to raise the stack overflow */
 #define STACK_OVERFLOW_MAX_SIZE (100*1024*1024)
@@ -35,8 +41,9 @@
 #  define PYINT_ASLONG PyInt_AsLong
 #endif
 
-#define PUTS(fd, str) write(fd, str, strlen(str))
-
+/* cast size_t to int because write() takes an int on Windows
+   (anyway, the length is smaller than 30 characters) */
+#define PUTS(fd, str) write(fd, str, (int)strlen(str))
 
 #ifdef HAVE_SIGACTION
 typedef struct sigaction _Py_sighandler_t;
@@ -76,10 +83,10 @@ static struct {
 #ifdef FAULTHANDLER_USER
 typedef struct {
     int enabled;
-    int signum;
     PyObject *file;
     int fd;
     int all_threads;
+    int chain;
     _Py_sighandler_t previous;
     PyInterpreterState *interp;
 } user_signal_t;
@@ -102,6 +109,7 @@ static user_signal_t *user_signals;
 # endif
 #endif
 
+static void faulthandler_user(int signum);
 #endif /* FAULTHANDLER_USER */
 
 
@@ -156,6 +164,10 @@ faulthandler_get_fileno(PyObject *file, int *p_fd)
             PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
             return NULL;
         }
+        if (file == Py_None) {
+            PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
+            return NULL;
+        }
     }
 
     result = PyObject_CallMethod(file, "fileno", "");
@@ -239,18 +251,18 @@ faulthandler_dump_traceback_py(PyObject *self,
 }
 
 
-/* Handler of SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
+/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
 
    Display the current Python traceback, restore the previous handler and call
    the previous handler.
 
-   On Windows, don't call explictly the previous handler, because Windows
+   On Windows, don't explicitly call the previous handler, because the Windows
    signal handler would not be called (for an unknown reason). The execution of
    the program continues at faulthandler_fatal_error() exit, but the same
    instruction will raise the same fault (signal), and so the previous handler
    will be called.
 
-   This function is signal safe and should only call signal safe functions. */
+   This function is signal-safe and should only call signal-safe functions. */
 
 static void
 faulthandler_fatal_error(int signum)
@@ -276,9 +288,9 @@ faulthandler_fatal_error(int signum)
 
     /* restore the previous handler */
 #ifdef HAVE_SIGACTION
-    (void)sigaction(handler->signum, &handler->previous, NULL);
+    (void)sigaction(signum, &handler->previous, NULL);
 #else
-    (void)signal(handler->signum, handler->previous);
+    (void)signal(signum, handler->previous);
 #endif
     handler->enabled = 0;
 
@@ -288,7 +300,7 @@ faulthandler_fatal_error(int signum)
 
 #ifdef WITH_THREAD
     /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
-       so are delivered to the thread that caused the fault. Get the Python
+       are thus delivered to the thread that caused the fault. Get the Python
        thread state of the current thread.
 
        PyThreadState_Get() doesn't give the state of the thread that caused the
@@ -310,12 +322,12 @@ faulthandler_fatal_error(int signum)
     errno = save_errno;
 #ifdef MS_WINDOWS
     if (signum == SIGSEGV) {
-        /* don't call explictly the previous handler for SIGSEGV in this signal
+        /* don't explicitly call the previous handler for SIGSEGV in this signal
            handler, because the Windows signal handler would not be called */
         return;
     }
 #endif
-    /* call the previous signal handler: it is called immediatly if we use
+    /* call the previous signal handler: it is called immediately if we use
        sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
     raise(signum);
 }
@@ -497,7 +509,7 @@ format_timeout(double timeout)
 }
 
 static PyObject*
-faulthandler_dump_tracebacks_later(PyObject *self,
+faulthandler_dump_traceback_later(PyObject *self,
                                   PyObject *args, PyObject *kwargs)
 {
     static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
@@ -506,12 +518,13 @@ faulthandler_dump_tracebacks_later(PyObject *self,
     int repeat = 0;
     PyObject *file = NULL;
     int exit = 0;
+    PyThreadState *tstate;
     int fd;
     char *header;
     size_t header_len;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-        "i|iOi:dump_tracebacks_later", kwlist,
+        "i|iOi:dump_traceback_later", kwlist,
         &timeout, &repeat, &file, &exit))
         return NULL;
     if (timeout <= 0) {
@@ -519,6 +532,10 @@ faulthandler_dump_tracebacks_later(PyObject *self,
         return NULL;
     }
 
+    tstate = get_thread_state();
+    if (tstate == NULL)
+        return NULL;
+
     file = faulthandler_get_fileno(file, &fd);
     if (file == NULL)
         return NULL;
@@ -542,8 +559,8 @@ faulthandler_dump_tracebacks_later(PyObject *self,
     fault_alarm.fd = fd;
     fault_alarm.timeout = timeout;
     fault_alarm.repeat = repeat;
+    fault_alarm.interp = tstate->interp;
     fault_alarm.exit = exit;
-    fault_alarm.interp = PyThreadState_Get()->interp;
     fault_alarm.header = header;
     fault_alarm.header_len = header_len;
 
@@ -553,7 +570,7 @@ faulthandler_dump_tracebacks_later(PyObject *self,
 }
 
 static PyObject*
-faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
+faulthandler_cancel_dump_traceback_later_py(PyObject *self)
 {
     alarm(0);
     Py_CLEAR(fault_alarm.file);
@@ -564,6 +581,39 @@ faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
 #endif /* FAULTHANDLER_LATER */
 
 #ifdef FAULTHANDLER_USER
+static int
+faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
+{
+#ifdef HAVE_SIGACTION
+    struct sigaction action;
+    action.sa_handler = faulthandler_user;
+    sigemptyset(&action.sa_mask);
+    /* if the signal is received while the kernel is executing a system
+       call, try to restart the system call instead of interrupting it and
+       return EINTR. */
+    action.sa_flags = SA_RESTART;
+    if (chain) {
+        /* do not prevent the signal from being received from within its
+           own signal handler */
+        action.sa_flags = SA_NODEFER;
+    }
+#ifdef HAVE_SIGALTSTACK
+    if (stack.ss_sp != NULL) {
+        /* Call the signal handler on an alternate signal stack
+           provided by sigaltstack() */
+        action.sa_flags |= SA_ONSTACK;
+    }
+#endif
+    return sigaction(signum, &action, p_previous);
+#else
+    _Py_sighandler_t previous;
+    previous = signal(signum, faulthandler_user);
+    if (p_previous != NULL)
+        *p_previous = previous;
+    return (previous == SIG_ERR);
+#endif
+}
+
 /* Handler of user signals (e.g. SIGUSR1).
 
    Dump the traceback of the current thread, or of all threads if
@@ -594,11 +644,28 @@ faulthandler_user(int signum)
     if (user->all_threads)
         _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
     else {
-        if (tstate == NULL)
-            return;
-        _Py_DumpTraceback(user->fd, tstate);
+        if (tstate != NULL)
+            _Py_DumpTraceback(user->fd, tstate);
     }
-    errno = save_errno;
+#ifdef HAVE_SIGACTION
+    if (user->chain) {
+        (void)sigaction(signum, &user->previous, NULL);
+        errno = save_errno;
+
+        /* call the previous signal handler */
+        raise(signum);
+
+        save_errno = errno;
+        (void)faulthandler_register(signum, user->chain, NULL);
+        errno = save_errno;
+    }
+#else
+    if (user->chain) {
+        errno = save_errno;
+        /* call the previous signal handler */
+        user->previous(signum);
+    }
+#endif
 }
 
 static int
@@ -623,25 +690,23 @@ check_signum(int signum)
 }
 
 static PyObject*
-faulthandler_register(PyObject *self,
-                      PyObject *args, PyObject *kwargs)
+faulthandler_register_py(PyObject *self,
+                         PyObject *args, PyObject *kwargs)
 {
-    static char *kwlist[] = {"signum", "file", "all_threads", NULL};
+    static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
     int signum;
     PyObject *file = NULL;
     int all_threads = 1;
+    int chain = 0;
     int fd;
     user_signal_t *user;
     _Py_sighandler_t previous;
-#ifdef HAVE_SIGACTION
-    struct sigaction action;
-#endif
     PyThreadState *tstate;
     int err;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-        "i|Oi:register", kwlist,
-        &signum, &file, &all_threads))
+        "i|Oii:register", kwlist,
+        &signum, &file, &all_threads, &chain))
         return NULL;
 
     if (!check_signum(signum))
@@ -663,29 +728,13 @@ faulthandler_register(PyObject *self,
     user = &user_signals[signum];
 
     if (!user->enabled) {
-#ifdef HAVE_SIGACTION
-        action.sa_handler = faulthandler_user;
-        sigemptyset(&action.sa_mask);
-        /* if the signal is received while the kernel is executing a system
-           call, try to restart the system call instead of interrupting it and
-           return EINTR */
-        action.sa_flags = SA_RESTART;
-#ifdef HAVE_SIGALTSTACK
-        if (stack.ss_sp != NULL) {
-            /* Call the signal handler on an alternate signal stack
-               provided by sigaltstack() */
-            action.sa_flags |= SA_ONSTACK;
-        }
-#endif
-        err = sigaction(signum, &action, &previous);
-#else
-        previous = signal(signum, faulthandler_user);
-        err = (previous == SIG_ERR);
-#endif
+        err = faulthandler_register(signum, chain, &previous);
         if (err) {
             PyErr_SetFromErrno(PyExc_OSError);
             return NULL;
         }
+
+        user->previous = previous;
     }
 
     Py_XDECREF(user->file);
@@ -693,7 +742,7 @@ faulthandler_register(PyObject *self,
     user->file = file;
     user->fd = fd;
     user->all_threads = all_threads;
-    user->previous = previous;
+    user->chain = chain;
     user->interp = tstate->interp;
     user->enabled = 1;
 
@@ -739,30 +788,55 @@ faulthandler_unregister_py(PyObject *self, PyObject *args)
 #endif   /* FAULTHANDLER_USER */
 
 
+static void
+faulthandler_suppress_crash_report(void)
+{
+#ifdef MS_WINDOWS
+    UINT mode;
+
+    /* Configure Windows to not display the Windows Error Reporting dialog */
+    mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
+    SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+    struct rlimit rl;
+
+    /* Disable creation of core dump */
+    if (getrlimit(RLIMIT_CORE, &rl) != 0) {
+        rl.rlim_cur = 0;
+        setrlimit(RLIMIT_CORE, &rl);
+    }
+#endif
+
+#ifdef _MSC_VER
+    /* Visual Studio: configure abort() to not display an error message nor
+       open a popup asking to report the fault. */
+    _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
+#endif
+}
+
 static PyObject *
 faulthandler_read_null(PyObject *self, PyObject *args)
 {
-    int *x = NULL, y;
-    int release_gil = 0;
-    if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
-        return NULL;
-    if (release_gil) {
-        Py_BEGIN_ALLOW_THREADS
-        y = *x;
-        Py_END_ALLOW_THREADS
-    } else
-        y = *x;
+    volatile int *x;
+    volatile int y;
+
+    faulthandler_suppress_crash_report();
+    x = NULL;
+    y = *x;
     return PyLong_FromLong(y);
 
 }
 
-static PyObject *
-faulthandler_sigsegv(PyObject *self, PyObject *args)
+static void
+faulthandler_raise_sigsegv(void)
 {
+    faulthandler_suppress_crash_report();
 #if defined(MS_WINDOWS)
     /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
... 1368 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/faulthandler.git



More information about the Python-modules-commits mailing list