faulthandler.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394
  1. #include "Python.h"
  2. #include "pycore_initconfig.h" // _PyStatus_ERR
  3. #include "pycore_pyerrors.h" // _Py_DumpExtensionModules
  4. #include "pycore_pystate.h" // _PyThreadState_GET()
  5. #include "pycore_signal.h" // Py_NSIG
  6. #include "pycore_traceback.h" // _Py_DumpTracebackThreads
  7. #include <object.h>
  8. #include <signal.h>
  9. #include <stdlib.h> // abort()
  10. #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H)
  11. # include <pthread.h>
  12. #endif
  13. #ifdef MS_WINDOWS
  14. # include <windows.h>
  15. #endif
  16. #ifdef HAVE_SYS_RESOURCE_H
  17. # include <sys/resource.h>
  18. #endif
  19. #if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) && defined(HAVE_SYS_AUXV_H)
  20. # include <linux/auxvec.h> // AT_MINSIGSTKSZ
  21. # include <sys/auxv.h> // getauxval()
  22. #endif
  23. /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */
  24. #define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024)
  25. #define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str))
  26. // clang uses __attribute__((no_sanitize("undefined")))
  27. // GCC 4.9+ uses __attribute__((no_sanitize_undefined))
  28. #if defined(__has_feature) // Clang
  29. # if __has_feature(undefined_behavior_sanitizer)
  30. # define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined")))
  31. # endif
  32. #endif
  33. #if defined(__GNUC__) \
  34. && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))
  35. # define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined))
  36. #endif
  37. #ifndef _Py_NO_SANITIZE_UNDEFINED
  38. # define _Py_NO_SANITIZE_UNDEFINED
  39. #endif
  40. typedef struct {
  41. int signum;
  42. int enabled;
  43. const char* name;
  44. _Py_sighandler_t previous;
  45. int all_threads;
  46. } fault_handler_t;
  47. #define fatal_error _PyRuntime.faulthandler.fatal_error
  48. #define thread _PyRuntime.faulthandler.thread
  49. #ifdef FAULTHANDLER_USER
  50. #define user_signals _PyRuntime.faulthandler.user_signals
  51. typedef struct faulthandler_user_signal user_signal_t;
  52. static void faulthandler_user(int signum);
  53. #endif /* FAULTHANDLER_USER */
  54. static fault_handler_t faulthandler_handlers[] = {
  55. #ifdef SIGBUS
  56. {SIGBUS, 0, "Bus error", },
  57. #endif
  58. #ifdef SIGILL
  59. {SIGILL, 0, "Illegal instruction", },
  60. #endif
  61. {SIGFPE, 0, "Floating point exception", },
  62. {SIGABRT, 0, "Aborted", },
  63. /* define SIGSEGV at the end to make it the default choice if searching the
  64. handler fails in faulthandler_fatal_error() */
  65. {SIGSEGV, 0, "Segmentation fault", }
  66. };
  67. static const size_t faulthandler_nsignals = \
  68. Py_ARRAY_LENGTH(faulthandler_handlers);
  69. #ifdef FAULTHANDLER_USE_ALT_STACK
  70. # define stack _PyRuntime.faulthandler.stack
  71. # define old_stack _PyRuntime.faulthandler.old_stack
  72. #endif
  73. /* Get the file descriptor of a file by calling its fileno() method and then
  74. call its flush() method.
  75. If file is NULL or Py_None, use sys.stderr as the new file.
  76. If file is an integer, it will be treated as file descriptor.
  77. On success, return the file descriptor and write the new file into *file_ptr.
  78. On error, return -1. */
  79. static int
  80. faulthandler_get_fileno(PyObject **file_ptr)
  81. {
  82. PyObject *result;
  83. long fd_long;
  84. int fd;
  85. PyObject *file = *file_ptr;
  86. if (file == NULL || file == Py_None) {
  87. PyThreadState *tstate = _PyThreadState_GET();
  88. file = _PySys_GetAttr(tstate, &_Py_ID(stderr));
  89. if (file == NULL) {
  90. PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
  91. return -1;
  92. }
  93. if (file == Py_None) {
  94. PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
  95. return -1;
  96. }
  97. }
  98. else if (PyLong_Check(file)) {
  99. fd = _PyLong_AsInt(file);
  100. if (fd == -1 && PyErr_Occurred())
  101. return -1;
  102. if (fd < 0) {
  103. PyErr_SetString(PyExc_ValueError,
  104. "file is not a valid file descriptor");
  105. return -1;
  106. }
  107. *file_ptr = NULL;
  108. return fd;
  109. }
  110. result = PyObject_CallMethodNoArgs(file, &_Py_ID(fileno));
  111. if (result == NULL)
  112. return -1;
  113. fd = -1;
  114. if (PyLong_Check(result)) {
  115. fd_long = PyLong_AsLong(result);
  116. if (0 <= fd_long && fd_long < INT_MAX)
  117. fd = (int)fd_long;
  118. }
  119. Py_DECREF(result);
  120. if (fd == -1) {
  121. PyErr_SetString(PyExc_RuntimeError,
  122. "file.fileno() is not a valid file descriptor");
  123. return -1;
  124. }
  125. result = PyObject_CallMethodNoArgs(file, &_Py_ID(flush));
  126. if (result != NULL)
  127. Py_DECREF(result);
  128. else {
  129. /* ignore flush() error */
  130. PyErr_Clear();
  131. }
  132. *file_ptr = file;
  133. return fd;
  134. }
  135. /* Get the state of the current thread: only call this function if the current
  136. thread holds the GIL. Raise an exception on error. */
  137. static PyThreadState*
  138. get_thread_state(void)
  139. {
  140. PyThreadState *tstate = _PyThreadState_GET();
  141. if (tstate == NULL) {
  142. /* just in case but very unlikely... */
  143. PyErr_SetString(PyExc_RuntimeError,
  144. "unable to get the current thread state");
  145. return NULL;
  146. }
  147. return tstate;
  148. }
  149. static void
  150. faulthandler_dump_traceback(int fd, int all_threads,
  151. PyInterpreterState *interp)
  152. {
  153. static volatile int reentrant = 0;
  154. if (reentrant)
  155. return;
  156. reentrant = 1;
  157. /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
  158. are thus delivered to the thread that caused the fault. Get the Python
  159. thread state of the current thread.
  160. PyThreadState_Get() doesn't give the state of the thread that caused the
  161. fault if the thread released the GIL, and so this function cannot be
  162. used. Read the thread specific storage (TSS) instead: call
  163. PyGILState_GetThisThreadState(). */
  164. PyThreadState *tstate = PyGILState_GetThisThreadState();
  165. if (all_threads) {
  166. (void)_Py_DumpTracebackThreads(fd, NULL, tstate);
  167. }
  168. else {
  169. if (tstate != NULL)
  170. _Py_DumpTraceback(fd, tstate);
  171. }
  172. reentrant = 0;
  173. }
  174. static PyObject*
  175. faulthandler_dump_traceback_py(PyObject *self,
  176. PyObject *args, PyObject *kwargs)
  177. {
  178. static char *kwlist[] = {"file", "all_threads", NULL};
  179. PyObject *file = NULL;
  180. int all_threads = 1;
  181. PyThreadState *tstate;
  182. const char *errmsg;
  183. int fd;
  184. if (!PyArg_ParseTupleAndKeywords(args, kwargs,
  185. "|Op:dump_traceback", kwlist,
  186. &file, &all_threads))
  187. return NULL;
  188. fd = faulthandler_get_fileno(&file);
  189. if (fd < 0)
  190. return NULL;
  191. tstate = get_thread_state();
  192. if (tstate == NULL)
  193. return NULL;
  194. if (all_threads) {
  195. errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
  196. if (errmsg != NULL) {
  197. PyErr_SetString(PyExc_RuntimeError, errmsg);
  198. return NULL;
  199. }
  200. }
  201. else {
  202. _Py_DumpTraceback(fd, tstate);
  203. }
  204. if (PyErr_CheckSignals())
  205. return NULL;
  206. Py_RETURN_NONE;
  207. }
  208. static void
  209. faulthandler_disable_fatal_handler(fault_handler_t *handler)
  210. {
  211. if (!handler->enabled)
  212. return;
  213. handler->enabled = 0;
  214. #ifdef HAVE_SIGACTION
  215. (void)sigaction(handler->signum, &handler->previous, NULL);
  216. #else
  217. (void)signal(handler->signum, handler->previous);
  218. #endif
  219. }
  220. /* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
  221. Display the current Python traceback, restore the previous handler and call
  222. the previous handler.
  223. On Windows, don't explicitly call the previous handler, because the Windows
  224. signal handler would not be called (for an unknown reason). The execution of
  225. the program continues at faulthandler_fatal_error() exit, but the same
  226. instruction will raise the same fault (signal), and so the previous handler
  227. will be called.
  228. This function is signal-safe and should only call signal-safe functions. */
  229. static void
  230. faulthandler_fatal_error(int signum)
  231. {
  232. const int fd = fatal_error.fd;
  233. size_t i;
  234. fault_handler_t *handler = NULL;
  235. int save_errno = errno;
  236. int found = 0;
  237. if (!fatal_error.enabled)
  238. return;
  239. for (i=0; i < faulthandler_nsignals; i++) {
  240. handler = &faulthandler_handlers[i];
  241. if (handler->signum == signum) {
  242. found = 1;
  243. break;
  244. }
  245. }
  246. if (handler == NULL) {
  247. /* faulthandler_nsignals == 0 (unlikely) */
  248. return;
  249. }
  250. /* restore the previous handler */
  251. faulthandler_disable_fatal_handler(handler);
  252. if (found) {
  253. PUTS(fd, "Fatal Python error: ");
  254. PUTS(fd, handler->name);
  255. PUTS(fd, "\n\n");
  256. }
  257. else {
  258. char unknown_signum[23] = {0,};
  259. snprintf(unknown_signum, 23, "%d", signum);
  260. PUTS(fd, "Fatal Python error from unexpected signum: ");
  261. PUTS(fd, unknown_signum);
  262. PUTS(fd, "\n\n");
  263. }
  264. faulthandler_dump_traceback(fd, fatal_error.all_threads,
  265. fatal_error.interp);
  266. _Py_DumpExtensionModules(fd, fatal_error.interp);
  267. errno = save_errno;
  268. #ifdef MS_WINDOWS
  269. if (signum == SIGSEGV) {
  270. /* don't explicitly call the previous handler for SIGSEGV in this signal
  271. handler, because the Windows signal handler would not be called */
  272. return;
  273. }
  274. #endif
  275. /* call the previous signal handler: it is called immediately if we use
  276. sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
  277. raise(signum);
  278. }
  279. #ifdef MS_WINDOWS
  280. static int
  281. faulthandler_ignore_exception(DWORD code)
  282. {
  283. /* bpo-30557: ignore exceptions which are not errors */
  284. if (!(code & 0x80000000)) {
  285. return 1;
  286. }
  287. /* bpo-31701: ignore MSC and COM exceptions
  288. E0000000 + code */
  289. if (code == 0xE06D7363 /* MSC exception ("Emsc") */
  290. || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) {
  291. return 1;
  292. }
  293. /* Interesting exception: log it with the Python traceback */
  294. return 0;
  295. }
  296. static LONG WINAPI
  297. faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
  298. {
  299. const int fd = fatal_error.fd;
  300. DWORD code = exc_info->ExceptionRecord->ExceptionCode;
  301. DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
  302. if (faulthandler_ignore_exception(code)) {
  303. /* ignore the exception: call the next exception handler */
  304. return EXCEPTION_CONTINUE_SEARCH;
  305. }
  306. PUTS(fd, "Windows fatal exception: ");
  307. switch (code)
  308. {
  309. /* only format most common errors */
  310. case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
  311. case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
  312. case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
  313. case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
  314. case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
  315. case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
  316. case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
  317. default:
  318. PUTS(fd, "code 0x");
  319. _Py_DumpHexadecimal(fd, code, 8);
  320. }
  321. PUTS(fd, "\n\n");
  322. if (code == EXCEPTION_ACCESS_VIOLATION) {
  323. /* disable signal handler for SIGSEGV */
  324. for (size_t i=0; i < faulthandler_nsignals; i++) {
  325. fault_handler_t *handler = &faulthandler_handlers[i];
  326. if (handler->signum == SIGSEGV) {
  327. faulthandler_disable_fatal_handler(handler);
  328. break;
  329. }
  330. }
  331. }
  332. faulthandler_dump_traceback(fd, fatal_error.all_threads,
  333. fatal_error.interp);
  334. /* call the next exception handler */
  335. return EXCEPTION_CONTINUE_SEARCH;
  336. }
  337. #endif
  338. #ifdef FAULTHANDLER_USE_ALT_STACK
  339. static int
  340. faulthandler_allocate_stack(void)
  341. {
  342. if (stack.ss_sp != NULL) {
  343. return 0;
  344. }
  345. /* Allocate an alternate stack for faulthandler() signal handler
  346. to be able to execute a signal handler on a stack overflow error */
  347. stack.ss_sp = PyMem_Malloc(stack.ss_size);
  348. if (stack.ss_sp == NULL) {
  349. PyErr_NoMemory();
  350. return -1;
  351. }
  352. int err = sigaltstack(&stack, &old_stack);
  353. if (err) {
  354. PyErr_SetFromErrno(PyExc_OSError);
  355. /* Release the stack to retry sigaltstack() next time */
  356. PyMem_Free(stack.ss_sp);
  357. stack.ss_sp = NULL;
  358. return -1;
  359. }
  360. return 0;
  361. }
  362. #endif
  363. /* Install the handler for fatal signals, faulthandler_fatal_error(). */
  364. static int
  365. faulthandler_enable(void)
  366. {
  367. if (fatal_error.enabled) {
  368. return 0;
  369. }
  370. fatal_error.enabled = 1;
  371. #ifdef FAULTHANDLER_USE_ALT_STACK
  372. if (faulthandler_allocate_stack() < 0) {
  373. return -1;
  374. }
  375. #endif
  376. for (size_t i=0; i < faulthandler_nsignals; i++) {
  377. fault_handler_t *handler;
  378. int err;
  379. handler = &faulthandler_handlers[i];
  380. assert(!handler->enabled);
  381. #ifdef HAVE_SIGACTION
  382. struct sigaction action;
  383. action.sa_handler = faulthandler_fatal_error;
  384. sigemptyset(&action.sa_mask);
  385. /* Do not prevent the signal from being received from within
  386. its own signal handler */
  387. action.sa_flags = SA_NODEFER;
  388. #ifdef FAULTHANDLER_USE_ALT_STACK
  389. assert(stack.ss_sp != NULL);
  390. /* Call the signal handler on an alternate signal stack
  391. provided by sigaltstack() */
  392. action.sa_flags |= SA_ONSTACK;
  393. #endif
  394. err = sigaction(handler->signum, &action, &handler->previous);
  395. #else
  396. handler->previous = signal(handler->signum,
  397. faulthandler_fatal_error);
  398. err = (handler->previous == SIG_ERR);
  399. #endif
  400. if (err) {
  401. PyErr_SetFromErrno(PyExc_RuntimeError);
  402. return -1;
  403. }
  404. handler->enabled = 1;
  405. }
  406. #ifdef MS_WINDOWS
  407. assert(fatal_error.exc_handler == NULL);
  408. fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler);
  409. #endif
  410. return 0;
  411. }
  412. static PyObject*
  413. faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
  414. {
  415. static char *kwlist[] = {"file", "all_threads", NULL};
  416. PyObject *file = NULL;
  417. int all_threads = 1;
  418. int fd;
  419. PyThreadState *tstate;
  420. if (!PyArg_ParseTupleAndKeywords(args, kwargs,
  421. "|Op:enable", kwlist, &file, &all_threads))
  422. return NULL;
  423. fd = faulthandler_get_fileno(&file);
  424. if (fd < 0)
  425. return NULL;
  426. tstate = get_thread_state();
  427. if (tstate == NULL)
  428. return NULL;
  429. Py_XINCREF(file);
  430. Py_XSETREF(fatal_error.file, file);
  431. fatal_error.fd = fd;
  432. fatal_error.all_threads = all_threads;
  433. fatal_error.interp = PyThreadState_GetInterpreter(tstate);
  434. if (faulthandler_enable() < 0) {
  435. return NULL;
  436. }
  437. Py_RETURN_NONE;
  438. }
  439. static void
  440. faulthandler_disable(void)
  441. {
  442. if (fatal_error.enabled) {
  443. fatal_error.enabled = 0;
  444. for (size_t i=0; i < faulthandler_nsignals; i++) {
  445. fault_handler_t *handler;
  446. handler = &faulthandler_handlers[i];
  447. faulthandler_disable_fatal_handler(handler);
  448. }
  449. }
  450. #ifdef MS_WINDOWS
  451. if (fatal_error.exc_handler != NULL) {
  452. RemoveVectoredExceptionHandler(fatal_error.exc_handler);
  453. fatal_error.exc_handler = NULL;
  454. }
  455. #endif
  456. Py_CLEAR(fatal_error.file);
  457. }
  458. static PyObject*
  459. faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored))
  460. {
  461. if (!fatal_error.enabled) {
  462. Py_RETURN_FALSE;
  463. }
  464. faulthandler_disable();
  465. Py_RETURN_TRUE;
  466. }
  467. static PyObject*
  468. faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
  469. {
  470. return PyBool_FromLong(fatal_error.enabled);
  471. }
  472. static void
  473. faulthandler_thread(void *unused)
  474. {
  475. PyLockStatus st;
  476. const char* errmsg;
  477. int ok;
  478. #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
  479. sigset_t set;
  480. /* we don't want to receive any signal */
  481. sigfillset(&set);
  482. pthread_sigmask(SIG_SETMASK, &set, NULL);
  483. #endif
  484. do {
  485. st = PyThread_acquire_lock_timed(thread.cancel_event,
  486. thread.timeout_us, 0);
  487. if (st == PY_LOCK_ACQUIRED) {
  488. PyThread_release_lock(thread.cancel_event);
  489. break;
  490. }
  491. /* Timeout => dump traceback */
  492. assert(st == PY_LOCK_FAILURE);
  493. _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
  494. errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL);
  495. ok = (errmsg == NULL);
  496. if (thread.exit)
  497. _exit(1);
  498. } while (ok && thread.repeat);
  499. /* The only way out */
  500. PyThread_release_lock(thread.running);
  501. }
  502. static void
  503. cancel_dump_traceback_later(void)
  504. {
  505. /* If not scheduled, nothing to cancel */
  506. if (!thread.cancel_event) {
  507. return;
  508. }
  509. /* Notify cancellation */
  510. PyThread_release_lock(thread.cancel_event);
  511. /* Wait for thread to join */
  512. PyThread_acquire_lock(thread.running, 1);
  513. PyThread_release_lock(thread.running);
  514. /* The main thread should always hold the cancel_event lock */
  515. PyThread_acquire_lock(thread.cancel_event, 1);
  516. Py_CLEAR(thread.file);
  517. if (thread.header) {
  518. PyMem_Free(thread.header);
  519. thread.header = NULL;
  520. }
  521. }
  522. #define SEC_TO_US (1000 * 1000)
  523. static char*
  524. format_timeout(_PyTime_t us)
  525. {
  526. unsigned long sec, min, hour;
  527. char buffer[100];
  528. /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */
  529. sec = (unsigned long)(us / SEC_TO_US);
  530. us %= SEC_TO_US;
  531. min = sec / 60;
  532. sec %= 60;
  533. hour = min / 60;
  534. min %= 60;
  535. if (us != 0) {
  536. PyOS_snprintf(buffer, sizeof(buffer),
  537. "Timeout (%lu:%02lu:%02lu.%06u)!\n",
  538. hour, min, sec, (unsigned int)us);
  539. }
  540. else {
  541. PyOS_snprintf(buffer, sizeof(buffer),
  542. "Timeout (%lu:%02lu:%02lu)!\n",
  543. hour, min, sec);
  544. }
  545. return _PyMem_Strdup(buffer);
  546. }
  547. static PyObject*
  548. faulthandler_dump_traceback_later(PyObject *self,
  549. PyObject *args, PyObject *kwargs)
  550. {
  551. static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
  552. PyObject *timeout_obj;
  553. _PyTime_t timeout, timeout_us;
  554. int repeat = 0;
  555. PyObject *file = NULL;
  556. int fd;
  557. int exit = 0;
  558. PyThreadState *tstate;
  559. char *header;
  560. size_t header_len;
  561. if (!PyArg_ParseTupleAndKeywords(args, kwargs,
  562. "O|iOi:dump_traceback_later", kwlist,
  563. &timeout_obj, &repeat, &file, &exit))
  564. return NULL;
  565. if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
  566. _PyTime_ROUND_TIMEOUT) < 0) {
  567. return NULL;
  568. }
  569. timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT);
  570. if (timeout_us <= 0) {
  571. PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
  572. return NULL;
  573. }
  574. /* Limit to LONG_MAX seconds for format_timeout() */
  575. if (timeout_us > PY_TIMEOUT_MAX || timeout_us / SEC_TO_US > LONG_MAX) {
  576. PyErr_SetString(PyExc_OverflowError,
  577. "timeout value is too large");
  578. return NULL;
  579. }
  580. tstate = get_thread_state();
  581. if (tstate == NULL) {
  582. return NULL;
  583. }
  584. fd = faulthandler_get_fileno(&file);
  585. if (fd < 0) {
  586. return NULL;
  587. }
  588. if (!thread.running) {
  589. thread.running = PyThread_allocate_lock();
  590. if (!thread.running) {
  591. return PyErr_NoMemory();
  592. }
  593. }
  594. if (!thread.cancel_event) {
  595. thread.cancel_event = PyThread_allocate_lock();
  596. if (!thread.cancel_event || !thread.running) {
  597. return PyErr_NoMemory();
  598. }
  599. /* cancel_event starts to be acquired: it's only released to cancel
  600. the thread. */
  601. PyThread_acquire_lock(thread.cancel_event, 1);
  602. }
  603. /* format the timeout */
  604. header = format_timeout(timeout_us);
  605. if (header == NULL) {
  606. return PyErr_NoMemory();
  607. }
  608. header_len = strlen(header);
  609. /* Cancel previous thread, if running */
  610. cancel_dump_traceback_later();
  611. Py_XINCREF(file);
  612. Py_XSETREF(thread.file, file);
  613. thread.fd = fd;
  614. /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */
  615. thread.timeout_us = (PY_TIMEOUT_T)timeout_us;
  616. thread.repeat = repeat;
  617. thread.interp = PyThreadState_GetInterpreter(tstate);
  618. thread.exit = exit;
  619. thread.header = header;
  620. thread.header_len = header_len;
  621. /* Arm these locks to serve as events when released */
  622. PyThread_acquire_lock(thread.running, 1);
  623. if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
  624. PyThread_release_lock(thread.running);
  625. Py_CLEAR(thread.file);
  626. PyMem_Free(header);
  627. thread.header = NULL;
  628. PyErr_SetString(PyExc_RuntimeError,
  629. "unable to start watchdog thread");
  630. return NULL;
  631. }
  632. Py_RETURN_NONE;
  633. }
  634. static PyObject*
  635. faulthandler_cancel_dump_traceback_later_py(PyObject *self,
  636. PyObject *Py_UNUSED(ignored))
  637. {
  638. cancel_dump_traceback_later();
  639. Py_RETURN_NONE;
  640. }
  641. #ifdef FAULTHANDLER_USER
  642. static int
  643. faulthandler_register(int signum, int chain, _Py_sighandler_t *previous_p)
  644. {
  645. #ifdef HAVE_SIGACTION
  646. struct sigaction action;
  647. action.sa_handler = faulthandler_user;
  648. sigemptyset(&action.sa_mask);
  649. /* if the signal is received while the kernel is executing a system
  650. call, try to restart the system call instead of interrupting it and
  651. return EINTR. */
  652. action.sa_flags = SA_RESTART;
  653. if (chain) {
  654. /* do not prevent the signal from being received from within its
  655. own signal handler */
  656. action.sa_flags = SA_NODEFER;
  657. }
  658. #ifdef FAULTHANDLER_USE_ALT_STACK
  659. assert(stack.ss_sp != NULL);
  660. /* Call the signal handler on an alternate signal stack
  661. provided by sigaltstack() */
  662. action.sa_flags |= SA_ONSTACK;
  663. #endif
  664. return sigaction(signum, &action, previous_p);
  665. #else
  666. _Py_sighandler_t previous;
  667. previous = signal(signum, faulthandler_user);
  668. if (previous_p != NULL) {
  669. *previous_p = previous;
  670. }
  671. return (previous == SIG_ERR);
  672. #endif
  673. }
  674. /* Handler of user signals (e.g. SIGUSR1).
  675. Dump the traceback of the current thread, or of all threads if
  676. thread.all_threads is true.
  677. This function is signal safe and should only call signal safe functions. */
  678. static void
  679. faulthandler_user(int signum)
  680. {
  681. user_signal_t *user;
  682. int save_errno = errno;
  683. user = &user_signals[signum];
  684. if (!user->enabled)
  685. return;
  686. faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
  687. #ifdef HAVE_SIGACTION
  688. if (user->chain) {
  689. (void)sigaction(signum, &user->previous, NULL);
  690. errno = save_errno;
  691. /* call the previous signal handler */
  692. raise(signum);
  693. save_errno = errno;
  694. (void)faulthandler_register(signum, user->chain, NULL);
  695. errno = save_errno;
  696. }
  697. #else
  698. if (user->chain && user->previous != NULL) {
  699. errno = save_errno;
  700. /* call the previous signal handler */
  701. user->previous(signum);
  702. }
  703. #endif
  704. }
  705. static int
  706. check_signum(int signum)
  707. {
  708. for (size_t i=0; i < faulthandler_nsignals; i++) {
  709. if (faulthandler_handlers[i].signum == signum) {
  710. PyErr_Format(PyExc_RuntimeError,
  711. "signal %i cannot be registered, "
  712. "use enable() instead",
  713. signum);
  714. return 0;
  715. }
  716. }
  717. if (signum < 1 || Py_NSIG <= signum) {
  718. PyErr_SetString(PyExc_ValueError, "signal number out of range");
  719. return 0;
  720. }
  721. return 1;
  722. }
  723. static PyObject*
  724. faulthandler_register_py(PyObject *self,
  725. PyObject *args, PyObject *kwargs)
  726. {
  727. static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
  728. int signum;
  729. PyObject *file = NULL;
  730. int all_threads = 1;
  731. int chain = 0;
  732. int fd;
  733. user_signal_t *user;
  734. _Py_sighandler_t previous;
  735. PyThreadState *tstate;
  736. int err;
  737. if (!PyArg_ParseTupleAndKeywords(args, kwargs,
  738. "i|Opp:register", kwlist,
  739. &signum, &file, &all_threads, &chain))
  740. return NULL;
  741. if (!check_signum(signum))
  742. return NULL;
  743. tstate = get_thread_state();
  744. if (tstate == NULL)
  745. return NULL;
  746. fd = faulthandler_get_fileno(&file);
  747. if (fd < 0)
  748. return NULL;
  749. if (user_signals == NULL) {
  750. user_signals = PyMem_Calloc(Py_NSIG, sizeof(user_signal_t));
  751. if (user_signals == NULL)
  752. return PyErr_NoMemory();
  753. }
  754. user = &user_signals[signum];
  755. if (!user->enabled) {
  756. #ifdef FAULTHANDLER_USE_ALT_STACK
  757. if (faulthandler_allocate_stack() < 0) {
  758. return NULL;
  759. }
  760. #endif
  761. err = faulthandler_register(signum, chain, &previous);
  762. if (err) {
  763. PyErr_SetFromErrno(PyExc_OSError);
  764. return NULL;
  765. }
  766. user->previous = previous;
  767. }
  768. Py_XINCREF(file);
  769. Py_XSETREF(user->file, file);
  770. user->fd = fd;
  771. user->all_threads = all_threads;
  772. user->chain = chain;
  773. user->interp = PyThreadState_GetInterpreter(tstate);
  774. user->enabled = 1;
  775. Py_RETURN_NONE;
  776. }
  777. static int
  778. faulthandler_unregister(user_signal_t *user, int signum)
  779. {
  780. if (!user->enabled)
  781. return 0;
  782. user->enabled = 0;
  783. #ifdef HAVE_SIGACTION
  784. (void)sigaction(signum, &user->previous, NULL);
  785. #else
  786. (void)signal(signum, user->previous);
  787. #endif
  788. Py_CLEAR(user->file);
  789. user->fd = -1;
  790. return 1;
  791. }
  792. static PyObject*
  793. faulthandler_unregister_py(PyObject *self, PyObject *args)
  794. {
  795. int signum;
  796. user_signal_t *user;
  797. int change;
  798. if (!PyArg_ParseTuple(args, "i:unregister", &signum))
  799. return NULL;
  800. if (!check_signum(signum))
  801. return NULL;
  802. if (user_signals == NULL)
  803. Py_RETURN_FALSE;
  804. user = &user_signals[signum];
  805. change = faulthandler_unregister(user, signum);
  806. return PyBool_FromLong(change);
  807. }
  808. #endif /* FAULTHANDLER_USER */
  809. static void
  810. faulthandler_suppress_crash_report(void)
  811. {
  812. #ifdef MS_WINDOWS_DESKTOP
  813. UINT mode;
  814. /* Configure Windows to not display the Windows Error Reporting dialog */
  815. mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
  816. SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
  817. #endif
  818. #ifdef HAVE_SYS_RESOURCE_H
  819. struct rlimit rl;
  820. /* Disable creation of core dump */
  821. if (getrlimit(RLIMIT_CORE, &rl) == 0) {
  822. rl.rlim_cur = 0;
  823. setrlimit(RLIMIT_CORE, &rl);
  824. }
  825. #endif
  826. #ifdef _MSC_VER
  827. /* Visual Studio: configure abort() to not display an error message nor
  828. open a popup asking to report the fault. */
  829. _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
  830. #endif
  831. }
  832. static PyObject* _Py_NO_SANITIZE_UNDEFINED
  833. faulthandler_read_null(PyObject *self, PyObject *args)
  834. {
  835. volatile int *x;
  836. volatile int y;
  837. faulthandler_suppress_crash_report();
  838. x = NULL;
  839. y = *x;
  840. return PyLong_FromLong(y);
  841. }
  842. static void
  843. faulthandler_raise_sigsegv(void)
  844. {
  845. faulthandler_suppress_crash_report();
  846. #if defined(MS_WINDOWS)
  847. /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
  848. handler and then gives back the execution flow to the program (without
  849. explicitly calling the previous error handler). In a normal case, the
  850. SIGSEGV was raised by the kernel because of a fault, and so if the
  851. program retries to execute the same instruction, the fault will be
  852. raised again.
  853. Here the fault is simulated by a fake SIGSEGV signal raised by the
  854. application. We have to raise SIGSEGV at lease twice: once for
  855. faulthandler_fatal_error(), and one more time for the previous signal
  856. handler. */
  857. while(1)
  858. raise(SIGSEGV);
  859. #else
  860. raise(SIGSEGV);
  861. #endif
  862. }
  863. static PyObject *
  864. faulthandler_sigsegv(PyObject *self, PyObject *args)
  865. {
  866. int release_gil = 0;
  867. if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
  868. return NULL;
  869. if (release_gil) {
  870. Py_BEGIN_ALLOW_THREADS
  871. faulthandler_raise_sigsegv();
  872. Py_END_ALLOW_THREADS
  873. } else {
  874. faulthandler_raise_sigsegv();
  875. }
  876. Py_RETURN_NONE;
  877. }
  878. static void _Py_NO_RETURN
  879. faulthandler_fatal_error_thread(void *plock)
  880. {
  881. Py_FatalError("in new thread");
  882. }
  883. static PyObject *
  884. faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
  885. {
  886. long tid;
  887. PyThread_type_lock lock;
  888. faulthandler_suppress_crash_report();
  889. lock = PyThread_allocate_lock();
  890. if (lock == NULL)
  891. return PyErr_NoMemory();
  892. PyThread_acquire_lock(lock, WAIT_LOCK);
  893. tid = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
  894. if (tid == -1) {
  895. PyThread_free_lock(lock);
  896. PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
  897. return NULL;
  898. }
  899. /* wait until the thread completes: it will never occur, since Py_FatalError()
  900. exits the process immediately. */
  901. PyThread_acquire_lock(lock, WAIT_LOCK);
  902. PyThread_release_lock(lock);
  903. PyThread_free_lock(lock);
  904. Py_RETURN_NONE;
  905. }
  906. static PyObject* _Py_NO_SANITIZE_UNDEFINED
  907. faulthandler_sigfpe(PyObject *self, PyObject *args)
  908. {
  909. faulthandler_suppress_crash_report();
  910. /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
  911. PowerPC. Use volatile to disable compile-time optimizations. */
  912. volatile int x = 1, y = 0, z;
  913. z = x / y;
  914. /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
  915. raise it manually. */
  916. raise(SIGFPE);
  917. /* This line is never reached, but we pretend to make something with z
  918. to silence a compiler warning. */
  919. return PyLong_FromLong(z);
  920. }
  921. static PyObject *
  922. faulthandler_sigabrt(PyObject *self, PyObject *args)
  923. {
  924. faulthandler_suppress_crash_report();
  925. abort();
  926. Py_RETURN_NONE;
  927. }
  928. #if defined(FAULTHANDLER_USE_ALT_STACK)
  929. #define FAULTHANDLER_STACK_OVERFLOW
  930. static uintptr_t
  931. stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
  932. {
  933. /* Allocate (at least) 4096 bytes on the stack at each call.
  934. bpo-23654, bpo-38965: use volatile keyword to prevent tail call
  935. optimization. */
  936. volatile unsigned char buffer[4096];
  937. uintptr_t sp = (uintptr_t)&buffer;
  938. *depth += 1;
  939. if (sp < min_sp || max_sp < sp)
  940. return sp;
  941. buffer[0] = 1;
  942. buffer[4095] = 0;
  943. return stack_overflow(min_sp, max_sp, depth);
  944. }
  945. static PyObject *
  946. faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
  947. {
  948. size_t depth, size;
  949. uintptr_t sp = (uintptr_t)&depth;
  950. uintptr_t stop, lower_limit, upper_limit;
  951. faulthandler_suppress_crash_report();
  952. depth = 0;
  953. if (STACK_OVERFLOW_MAX_SIZE <= sp) {
  954. lower_limit = sp - STACK_OVERFLOW_MAX_SIZE;
  955. }
  956. else {
  957. lower_limit = 0;
  958. }
  959. if (UINTPTR_MAX - STACK_OVERFLOW_MAX_SIZE >= sp) {
  960. upper_limit = sp + STACK_OVERFLOW_MAX_SIZE;
  961. }
  962. else {
  963. upper_limit = UINTPTR_MAX;
  964. }
  965. stop = stack_overflow(lower_limit, upper_limit, &depth);
  966. if (sp < stop)
  967. size = stop - sp;
  968. else
  969. size = sp - stop;
  970. PyErr_Format(PyExc_RuntimeError,
  971. "unable to raise a stack overflow (allocated %zu bytes "
  972. "on the stack, %zu recursive calls)",
  973. size, depth);
  974. return NULL;
  975. }
  976. #endif /* defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_SIGACTION) */
  977. static int
  978. faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
  979. {
  980. Py_VISIT(thread.file);
  981. #ifdef FAULTHANDLER_USER
  982. if (user_signals != NULL) {
  983. for (size_t signum=0; signum < Py_NSIG; signum++)
  984. Py_VISIT(user_signals[signum].file);
  985. }
  986. #endif
  987. Py_VISIT(fatal_error.file);
  988. return 0;
  989. }
  990. #ifdef MS_WINDOWS
  991. static PyObject *
  992. faulthandler_raise_exception(PyObject *self, PyObject *args)
  993. {
  994. unsigned int code, flags = 0;
  995. if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
  996. return NULL;
  997. faulthandler_suppress_crash_report();
  998. RaiseException(code, flags, 0, NULL);
  999. Py_RETURN_NONE;
  1000. }
  1001. #endif
  1002. PyDoc_STRVAR(module_doc,
  1003. "faulthandler module.");
  1004. static PyMethodDef module_methods[] = {
  1005. {"enable",
  1006. _PyCFunction_CAST(faulthandler_py_enable), METH_VARARGS|METH_KEYWORDS,
  1007. PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
  1008. "enable the fault handler")},
  1009. {"disable", faulthandler_disable_py, METH_NOARGS,
  1010. PyDoc_STR("disable(): disable the fault handler")},
  1011. {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
  1012. PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
  1013. {"dump_traceback",
  1014. _PyCFunction_CAST(faulthandler_dump_traceback_py), METH_VARARGS|METH_KEYWORDS,
  1015. PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
  1016. "dump the traceback of the current thread, or of all threads "
  1017. "if all_threads is True, into file")},
  1018. {"dump_traceback_later",
  1019. _PyCFunction_CAST(faulthandler_dump_traceback_later), METH_VARARGS|METH_KEYWORDS,
  1020. PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False):\n"
  1021. "dump the traceback of all threads in timeout seconds,\n"
  1022. "or each timeout seconds if repeat is True. If exit is True, "
  1023. "call _exit(1) which is not safe.")},
  1024. {"cancel_dump_traceback_later",
  1025. faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
  1026. PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
  1027. "to dump_traceback_later().")},
  1028. #ifdef FAULTHANDLER_USER
  1029. {"register",
  1030. _PyCFunction_CAST(faulthandler_register_py), METH_VARARGS|METH_KEYWORDS,
  1031. PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
  1032. "register a handler for the signal 'signum': dump the "
  1033. "traceback of the current thread, or of all threads if "
  1034. "all_threads is True, into file")},
  1035. {"unregister",
  1036. _PyCFunction_CAST(faulthandler_unregister_py), METH_VARARGS|METH_KEYWORDS,
  1037. PyDoc_STR("unregister(signum): unregister the handler of the signal "
  1038. "'signum' registered by register()")},
  1039. #endif
  1040. {"_read_null", faulthandler_read_null, METH_NOARGS,
  1041. PyDoc_STR("_read_null(): read from NULL, raise "
  1042. "a SIGSEGV or SIGBUS signal depending on the platform")},
  1043. {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
  1044. PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
  1045. {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
  1046. PyDoc_STR("fatal_error_c_thread(): "
  1047. "call Py_FatalError() in a new C thread.")},
  1048. {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
  1049. PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
  1050. {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
  1051. PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
  1052. #ifdef FAULTHANDLER_STACK_OVERFLOW
  1053. {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
  1054. PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
  1055. #endif
  1056. #ifdef MS_WINDOWS
  1057. {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
  1058. PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
  1059. #endif
  1060. {NULL, NULL} /* sentinel */
  1061. };
  1062. static int
  1063. PyExec_faulthandler(PyObject *module) {
  1064. /* Add constants for unit tests */
  1065. #ifdef MS_WINDOWS
  1066. /* RaiseException() codes (prefixed by an underscore) */
  1067. if (PyModule_AddIntConstant(module, "_EXCEPTION_ACCESS_VIOLATION",
  1068. EXCEPTION_ACCESS_VIOLATION)) {
  1069. return -1;
  1070. }
  1071. if (PyModule_AddIntConstant(module, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
  1072. EXCEPTION_INT_DIVIDE_BY_ZERO)) {
  1073. return -1;
  1074. }
  1075. if (PyModule_AddIntConstant(module, "_EXCEPTION_STACK_OVERFLOW",
  1076. EXCEPTION_STACK_OVERFLOW)) {
  1077. return -1;
  1078. }
  1079. /* RaiseException() flags (prefixed by an underscore) */
  1080. if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE",
  1081. EXCEPTION_NONCONTINUABLE)) {
  1082. return -1;
  1083. }
  1084. if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
  1085. EXCEPTION_NONCONTINUABLE_EXCEPTION)) {
  1086. return -1;
  1087. }
  1088. #endif
  1089. return 0;
  1090. }
  1091. static PyModuleDef_Slot faulthandler_slots[] = {
  1092. {Py_mod_exec, PyExec_faulthandler},
  1093. // XXX gh-103092: fix isolation.
  1094. //{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
  1095. {0, NULL}
  1096. };
  1097. static struct PyModuleDef module_def = {
  1098. PyModuleDef_HEAD_INIT,
  1099. .m_name = "faulthandler",
  1100. .m_doc = module_doc,
  1101. .m_methods = module_methods,
  1102. .m_traverse = faulthandler_traverse,
  1103. .m_slots = faulthandler_slots
  1104. };
  1105. PyMODINIT_FUNC
  1106. PyInit_faulthandler(void)
  1107. {
  1108. return PyModuleDef_Init(&module_def);
  1109. }
  1110. static int
  1111. faulthandler_init_enable(void)
  1112. {
  1113. PyObject *enable = _PyImport_GetModuleAttrString("faulthandler", "enable");
  1114. if (enable == NULL) {
  1115. return -1;
  1116. }
  1117. PyObject *res = PyObject_CallNoArgs(enable);
  1118. Py_DECREF(enable);
  1119. if (res == NULL) {
  1120. return -1;
  1121. }
  1122. Py_DECREF(res);
  1123. return 0;
  1124. }
  1125. PyStatus
  1126. _PyFaulthandler_Init(int enable)
  1127. {
  1128. #ifdef FAULTHANDLER_USE_ALT_STACK
  1129. memset(&stack, 0, sizeof(stack));
  1130. stack.ss_flags = 0;
  1131. /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just
  1132. SIGSTKSZ bytes. Calling the previous signal handler in faulthandler
  1133. signal handler uses more than SIGSTKSZ bytes of stack memory on some
  1134. platforms. */
  1135. stack.ss_size = SIGSTKSZ * 2;
  1136. #ifdef AT_MINSIGSTKSZ
  1137. /* bpo-46968: Query Linux for minimal stack size to ensure signal delivery
  1138. for the hardware running CPython. This OS feature is available in
  1139. Linux kernel version >= 5.14 */
  1140. unsigned long at_minstack_size = getauxval(AT_MINSIGSTKSZ);
  1141. if (at_minstack_size != 0) {
  1142. stack.ss_size = SIGSTKSZ + at_minstack_size;
  1143. }
  1144. #endif
  1145. #endif
  1146. memset(&thread, 0, sizeof(thread));
  1147. if (enable) {
  1148. if (faulthandler_init_enable() < 0) {
  1149. return _PyStatus_ERR("failed to enable faulthandler");
  1150. }
  1151. }
  1152. return _PyStatus_OK();
  1153. }
  1154. void _PyFaulthandler_Fini(void)
  1155. {
  1156. /* later */
  1157. if (thread.cancel_event) {
  1158. cancel_dump_traceback_later();
  1159. PyThread_release_lock(thread.cancel_event);
  1160. PyThread_free_lock(thread.cancel_event);
  1161. thread.cancel_event = NULL;
  1162. }
  1163. if (thread.running) {
  1164. PyThread_free_lock(thread.running);
  1165. thread.running = NULL;
  1166. }
  1167. #ifdef FAULTHANDLER_USER
  1168. /* user */
  1169. if (user_signals != NULL) {
  1170. for (size_t signum=0; signum < Py_NSIG; signum++) {
  1171. faulthandler_unregister(&user_signals[signum], signum);
  1172. }
  1173. PyMem_Free(user_signals);
  1174. user_signals = NULL;
  1175. }
  1176. #endif
  1177. /* fatal */
  1178. faulthandler_disable();
  1179. #ifdef FAULTHANDLER_USE_ALT_STACK
  1180. if (stack.ss_sp != NULL) {
  1181. /* Fetch the current alt stack */
  1182. stack_t current_stack;
  1183. memset(&current_stack, 0, sizeof(current_stack));
  1184. if (sigaltstack(NULL, &current_stack) == 0) {
  1185. if (current_stack.ss_sp == stack.ss_sp) {
  1186. /* The current alt stack is the one that we installed.
  1187. It is safe to restore the old stack that we found when
  1188. we installed ours */
  1189. sigaltstack(&old_stack, NULL);
  1190. } else {
  1191. /* Someone switched to a different alt stack and didn't
  1192. restore ours when they were done (if they're done).
  1193. There's not much we can do in this unlikely case */
  1194. }
  1195. }
  1196. PyMem_Free(stack.ss_sp);
  1197. stack.ss_sp = NULL;
  1198. }
  1199. #endif
  1200. }