Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(15)

Side by Side Diff: Modules/faulthandler.c

Issue 10639: reindent.py converts newlines to platform default
Patch Set: Created 8 years, 8 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Modules/_cursesmodule.c ('k') | Modules/_io/fileio.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #include "Python.h" 1 #include "Python.h"
2 #include "pythread.h" 2 #include "pythread.h"
3 #include <signal.h> 3 #include <signal.h>
4 #include <object.h> 4 #include <object.h>
5 #include <frameobject.h> 5 #include <frameobject.h>
6 #include <signal.h> 6 #include <signal.h>
7 #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
8 #include <pthread.h>
9 #endif
10 7
11 /* Allocate at maximum 100 MB of the stack to raise the stack overflow */ 8 /* Allocate at maximum 100 MB of the stack to raise the stack overflow */
12 #define STACK_OVERFLOW_MAX_SIZE (100*1024*1024) 9 #define STACK_OVERFLOW_MAX_SIZE (100*1024*1024)
13 10
14 #ifdef WITH_THREAD 11 #ifdef WITH_THREAD
15 # define FAULTHANDLER_LATER 12 # define FAULTHANDLER_LATER
16 #endif 13 #endif
17 14
18 #ifndef MS_WINDOWS 15 #ifndef MS_WINDOWS
19 /* register() is useless on Windows, because only SIGSEGV, SIGABRT and 16 /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 PyThread_type_lock running; 61 PyThread_type_lock running;
65 } thread; 62 } thread;
66 #endif 63 #endif
67 64
68 #ifdef FAULTHANDLER_USER 65 #ifdef FAULTHANDLER_USER
69 typedef struct { 66 typedef struct {
70 int enabled; 67 int enabled;
71 PyObject *file; 68 PyObject *file;
72 int fd; 69 int fd;
73 int all_threads; 70 int all_threads;
74 int chain;
75 _Py_sighandler_t previous; 71 _Py_sighandler_t previous;
76 PyInterpreterState *interp; 72 PyInterpreterState *interp;
77 } user_signal_t; 73 } user_signal_t;
78 74
79 static user_signal_t *user_signals; 75 static user_signal_t *user_signals;
80 76
81 /* the following macros come from Python: Modules/signalmodule.c */ 77 /* the following macros come from Python: Modules/signalmodule.c */
82 #if defined(PYOS_OS2) && !defined(PYCC_GCC) 78 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
83 #define NSIG 12 79 #define NSIG 12
84 #endif 80 #endif
85 #ifndef NSIG 81 #ifndef NSIG
86 # if defined(_NSIG) 82 # if defined(_NSIG)
87 # define NSIG _NSIG /* For BSD/SysV */ 83 # define NSIG _NSIG /* For BSD/SysV */
88 # elif defined(_SIGMAX) 84 # elif defined(_SIGMAX)
89 # define NSIG (_SIGMAX + 1) /* For QNX */ 85 # define NSIG (_SIGMAX + 1) /* For QNX */
90 # elif defined(SIGMAX) 86 # elif defined(SIGMAX)
91 # define NSIG (SIGMAX + 1) /* For djgpp */ 87 # define NSIG (SIGMAX + 1) /* For djgpp */
92 # else 88 # else
93 # define NSIG 64 /* Use a reasonable default value */ 89 # define NSIG 64 /* Use a reasonable default value */
94 # endif 90 # endif
95 #endif 91 #endif
96 92
97 static void faulthandler_user(int signum);
98 #endif /* FAULTHANDLER_USER */ 93 #endif /* FAULTHANDLER_USER */
99 94
100 95
101 static fault_handler_t faulthandler_handlers[] = { 96 static fault_handler_t faulthandler_handlers[] = {
102 #ifdef SIGBUS 97 #ifdef SIGBUS
103 {SIGBUS, 0, "Bus error", }, 98 {SIGBUS, 0, "Bus error", },
104 #endif 99 #endif
105 #ifdef SIGILL 100 #ifdef SIGILL
106 {SIGILL, 0, "Illegal instruction", }, 101 {SIGILL, 0, "Illegal instruction", },
107 #endif 102 #endif
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 if (handler->signum == signum) 248 if (handler->signum == signum)
254 break; 249 break;
255 } 250 }
256 if (handler == NULL) { 251 if (handler == NULL) {
257 /* faulthandler_nsignals == 0 (unlikely) */ 252 /* faulthandler_nsignals == 0 (unlikely) */
258 return; 253 return;
259 } 254 }
260 255
261 /* restore the previous handler */ 256 /* restore the previous handler */
262 #ifdef HAVE_SIGACTION 257 #ifdef HAVE_SIGACTION
263 (void)sigaction(signum, &handler->previous, NULL); 258 (void)sigaction(handler->signum, &handler->previous, NULL);
264 #else 259 #else
265 (void)signal(signum, handler->previous); 260 (void)signal(handler->signum, handler->previous);
266 #endif 261 #endif
267 handler->enabled = 0; 262 handler->enabled = 0;
268 263
269 PUTS(fd, "Fatal Python error: "); 264 PUTS(fd, "Fatal Python error: ");
270 PUTS(fd, handler->name); 265 PUTS(fd, handler->name);
271 PUTS(fd, "\n\n"); 266 PUTS(fd, "\n\n");
272 267
273 #ifdef WITH_THREAD 268 #ifdef WITH_THREAD
274 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and 269 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
275 are thus delivered to the thread that caused the fault. Get the Python 270 are thus delivered to the thread that caused the fault. Get the Python
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 576
582 static PyObject* 577 static PyObject*
583 faulthandler_cancel_dump_tracebacks_later_py(PyObject *self) 578 faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
584 { 579 {
585 cancel_dump_tracebacks_later(); 580 cancel_dump_tracebacks_later();
586 Py_RETURN_NONE; 581 Py_RETURN_NONE;
587 } 582 }
588 #endif /* FAULTHANDLER_LATER */ 583 #endif /* FAULTHANDLER_LATER */
589 584
590 #ifdef FAULTHANDLER_USER 585 #ifdef FAULTHANDLER_USER
591 static int
592 faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
593 {
594 #ifdef HAVE_SIGACTION
595 struct sigaction action;
596 action.sa_handler = faulthandler_user;
597 sigemptyset(&action.sa_mask);
598 /* if the signal is received while the kernel is executing a system
599 call, try to restart the system call instead of interrupting it and
600 return EINTR. */
601 action.sa_flags = SA_RESTART;
602 if (chain) {
603 /* do not prevent the signal from being received from within its
604 own signal handler */
605 action.sa_flags = SA_NODEFER;
606 }
607 #ifdef HAVE_SIGALTSTACK
608 if (stack.ss_sp != NULL) {
609 /* Call the signal handler on an alternate signal stack
610 provided by sigaltstack() */
611 action.sa_flags |= SA_ONSTACK;
612 }
613 #endif
614 return sigaction(signum, &action, p_previous);
615 #else
616 _Py_sighandler_t previous;
617 previous = signal(signum, faulthandler_user);
618 if (p_previous != NULL)
619 *p_previous = previous;
620 return (previous == SIG_ERR);
621 #endif
622 }
623
624 /* Handler of user signals (e.g. SIGUSR1). 586 /* Handler of user signals (e.g. SIGUSR1).
625 587
626 Dump the traceback of the current thread, or of all threads if 588 Dump the traceback of the current thread, or of all threads if
627 thread.all_threads is true. 589 thread.all_threads is true.
628 590
629 This function is signal safe and should only call signal safe functions. */ 591 This function is signal safe and should only call signal safe functions. */
630 592
631 static void 593 static void
632 faulthandler_user(int signum) 594 faulthandler_user(int signum)
633 { 595 {
(...skipping 14 matching lines...) Expand all
648 tstate = PyThreadState_Get(); 610 tstate = PyThreadState_Get();
649 #endif 611 #endif
650 612
651 if (user->all_threads) 613 if (user->all_threads)
652 _Py_DumpTracebackThreads(user->fd, user->interp, tstate); 614 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
653 else { 615 else {
654 if (tstate == NULL) 616 if (tstate == NULL)
655 return; 617 return;
656 _Py_DumpTraceback(user->fd, tstate); 618 _Py_DumpTraceback(user->fd, tstate);
657 } 619 }
658 #ifdef HAVE_SIGACTION
659 if (user->chain) {
660 (void)sigaction(signum, &user->previous, NULL);
661 /* call the previous signal handler */
662 raise(signum);
663 (void)faulthandler_register(signum, user->chain, NULL);
664 }
665 #else
666 if (user->chain) {
667 /* call the previous signal handler */
668 user->previous(signum);
669 }
670 #endif
671 errno = save_errno; 620 errno = save_errno;
672 } 621 }
673 622
674 static int 623 static int
675 check_signum(int signum) 624 check_signum(int signum)
676 { 625 {
677 unsigned int i; 626 unsigned int i;
678 627
679 for (i=0; i < faulthandler_nsignals; i++) { 628 for (i=0; i < faulthandler_nsignals; i++) {
680 if (faulthandler_handlers[i].signum == signum) { 629 if (faulthandler_handlers[i].signum == signum) {
681 PyErr_Format(PyExc_RuntimeError, 630 PyErr_Format(PyExc_RuntimeError,
682 "signal %i cannot be registered, " 631 "signal %i cannot be registered, "
683 "use enable() instead", 632 "use enable() instead",
684 signum); 633 signum);
685 return 0; 634 return 0;
686 } 635 }
687 } 636 }
688 if (signum < 1 || NSIG <= signum) { 637 if (signum < 1 || NSIG <= signum) {
689 PyErr_SetString(PyExc_ValueError, "signal number out of range"); 638 PyErr_SetString(PyExc_ValueError, "signal number out of range");
690 return 0; 639 return 0;
691 } 640 }
692 return 1; 641 return 1;
693 } 642 }
694 643
695 static PyObject* 644 static PyObject*
696 faulthandler_register_py(PyObject *self, 645 faulthandler_register(PyObject *self,
697 PyObject *args, PyObject *kwargs) 646 PyObject *args, PyObject *kwargs)
698 { 647 {
699 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL}; 648 static char *kwlist[] = {"signum", "file", "all_threads", NULL};
700 int signum; 649 int signum;
701 PyObject *file = NULL; 650 PyObject *file = NULL;
702 int all_threads = 1; 651 int all_threads = 1;
703 int chain = 0;
704 int fd; 652 int fd;
705 user_signal_t *user; 653 user_signal_t *user;
706 _Py_sighandler_t previous; 654 _Py_sighandler_t previous;
655 #ifdef HAVE_SIGACTION
656 struct sigaction action;
657 #endif
707 PyThreadState *tstate; 658 PyThreadState *tstate;
708 int err; 659 int err;
709 660
710 if (!PyArg_ParseTupleAndKeywords(args, kwargs, 661 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
711 "i|Oii:register", kwlist, 662 "i|Oi:register", kwlist,
712 &signum, &file, &all_threads, &chain)) 663 &signum, &file, &all_threads))
713 return NULL; 664 return NULL;
714 665
715 if (!check_signum(signum)) 666 if (!check_signum(signum))
716 return NULL; 667 return NULL;
717 668
718 tstate = get_thread_state(); 669 tstate = get_thread_state();
719 if (tstate == NULL) 670 if (tstate == NULL)
720 return NULL; 671 return NULL;
721 672
722 file = faulthandler_get_fileno(file, &fd); 673 file = faulthandler_get_fileno(file, &fd);
723 if (file == NULL) 674 if (file == NULL)
724 return NULL; 675 return NULL;
725 676
726 if (user_signals == NULL) { 677 if (user_signals == NULL) {
727 user_signals = calloc(NSIG, sizeof(user_signal_t)); 678 user_signals = calloc(NSIG, sizeof(user_signal_t));
728 if (user_signals == NULL) 679 if (user_signals == NULL)
729 return PyErr_NoMemory(); 680 return PyErr_NoMemory();
730 } 681 }
731 user = &user_signals[signum]; 682 user = &user_signals[signum];
732 683
733 if (!user->enabled) { 684 if (!user->enabled) {
734 err = faulthandler_register(signum, chain, &previous); 685 #ifdef HAVE_SIGACTION
686 action.sa_handler = faulthandler_user;
687 sigemptyset(&action.sa_mask);
688 /* if the signal is received while the kernel is executing a system
689 call, try to restart the system call instead of interrupting it and
690 return EINTR */
691 action.sa_flags = SA_RESTART;
692 #ifdef HAVE_SIGALTSTACK
693 if (stack.ss_sp != NULL) {
694 /* Call the signal handler on an alternate signal stack
695 provided by sigaltstack() */
696 action.sa_flags |= SA_ONSTACK;
697 }
698 #endif
699 err = sigaction(signum, &action, &previous);
700 #else
701 previous = signal(signum, faulthandler_user);
702 err = (previous == SIG_ERR);
703 #endif
735 if (err) { 704 if (err) {
736 PyErr_SetFromErrno(PyExc_OSError); 705 PyErr_SetFromErrno(PyExc_OSError);
737 return NULL; 706 return NULL;
738 } 707 }
739 } 708 }
740 709
741 Py_XDECREF(user->file); 710 Py_XDECREF(user->file);
742 Py_INCREF(file); 711 Py_INCREF(file);
743 user->file = file; 712 user->file = file;
744 user->fd = fd; 713 user->fd = fd;
745 user->all_threads = all_threads; 714 user->all_threads = all_threads;
746 user->chain = chain;
747 user->previous = previous; 715 user->previous = previous;
748 user->interp = tstate->interp; 716 user->interp = tstate->interp;
749 user->enabled = 1; 717 user->enabled = 1;
750 718
751 Py_RETURN_NONE; 719 Py_RETURN_NONE;
752 } 720 }
753 721
754 static int 722 static int
755 faulthandler_unregister(user_signal_t *user, int signum) 723 faulthandler_unregister(user_signal_t *user, int signum)
756 { 724 {
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 "or each timeout seconds if repeat is True. If exit is True, " 936 "or each timeout seconds if repeat is True. If exit is True, "
969 "call _exit(1) which is not safe.")}, 937 "call _exit(1) which is not safe.")},
970 {"cancel_dump_tracebacks_later", 938 {"cancel_dump_tracebacks_later",
971 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS, 939 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
972 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call " 940 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
973 "to dump_tracebacks_later().")}, 941 "to dump_tracebacks_later().")},
974 #endif 942 #endif
975 943
976 #ifdef FAULTHANDLER_USER 944 #ifdef FAULTHANDLER_USER
977 {"register", 945 {"register",
978 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS, 946 (PyCFunction)faulthandler_register, METH_VARARGS|METH_KEYWORDS,
979 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False) : " 947 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True): "
980 "register an handler for the signal 'signum': dump the " 948 "register an handler for the signal 'signum': dump the "
981 "traceback of the current thread, or of all threads if " 949 "traceback of the current thread, or of all threads if "
982 "all_threads is True, into file")}, 950 "all_threads is True, into file")},
983 {"unregister", 951 {"unregister",
984 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS, 952 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
985 PyDoc_STR("unregister(signum): unregister the handler of the signal " 953 PyDoc_STR("unregister(signum): unregister the handler of the signal "
986 "'signum' registered by register()")}, 954 "'signum' registered by register()")},
987 #endif 955 #endif
988 956
989 {"_read_null", faulthandler_read_null, METH_VARARGS, 957 {"_read_null", faulthandler_read_null, METH_VARARGS,
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 1101
1134 /* fatal */ 1102 /* fatal */
1135 faulthandler_disable(); 1103 faulthandler_disable();
1136 #ifdef HAVE_SIGALTSTACK 1104 #ifdef HAVE_SIGALTSTACK
1137 if (stack.ss_sp != NULL) { 1105 if (stack.ss_sp != NULL) {
1138 PyMem_Free(stack.ss_sp); 1106 PyMem_Free(stack.ss_sp);
1139 stack.ss_sp = NULL; 1107 stack.ss_sp = NULL;
1140 } 1108 }
1141 #endif 1109 #endif
1142 } 1110 }
OLDNEW
« no previous file with comments | « Modules/_cursesmodule.c ('k') | Modules/_io/fileio.c » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+