[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