1 2 /* Traceback implementation */ 3 4 #include "Python.h" 5 6 #include "code.h" 7 #include "frameobject.h" 8 #include "structmember.h" 9 #include "osdefs.h" 10 #ifdef HAVE_FCNTL_H 11 #include <fcntl.h> 12 #endif 13 14 #define OFF(x) offsetof(PyTracebackObject, x) 15 16 #define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) 17 #define MAX_STRING_LENGTH 500 18 #define MAX_FRAME_DEPTH 100 19 #define MAX_NTHREADS 100 20 21 /* Function from Parser/tokenizer.c */ 22 extern char * PyTokenizer_FindEncodingFilename(int, PyObject *); 23 24 _Py_IDENTIFIER(TextIOWrapper); 25 _Py_IDENTIFIER(close); 26 _Py_IDENTIFIER(open); 27 _Py_IDENTIFIER(path); 28 29 static PyObject * 30 tb_dir(PyTracebackObject *self) 31 { 32 return Py_BuildValue("[ssss]", "tb_frame", "tb_next", 33 "tb_lasti", "tb_lineno"); 34 } 35 36 static PyMethodDef tb_methods[] = { 37 {"__dir__", (PyCFunction)tb_dir, METH_NOARGS}, 38 {NULL, NULL, 0, NULL}, 39 }; 40 41 static PyMemberDef tb_memberlist[] = { 42 {"tb_next", T_OBJECT, OFF(tb_next), READONLY}, 43 {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY}, 44 {"tb_lasti", T_INT, OFF(tb_lasti), READONLY}, 45 {"tb_lineno", T_INT, OFF(tb_lineno), READONLY}, 46 {NULL} /* Sentinel */ 47 }; 48 49 static void 50 tb_dealloc(PyTracebackObject *tb) 51 { 52 PyObject_GC_UnTrack(tb); 53 Py_TRASHCAN_SAFE_BEGIN(tb) 54 Py_XDECREF(tb->tb_next); 55 Py_XDECREF(tb->tb_frame); 56 PyObject_GC_Del(tb); 57 Py_TRASHCAN_SAFE_END(tb) 58 } 59 60 static int 61 tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg) 62 { 63 Py_VISIT(tb->tb_next); 64 Py_VISIT(tb->tb_frame); 65 return 0; 66 } 67 68 static void 69 tb_clear(PyTracebackObject *tb) 70 { 71 Py_CLEAR(tb->tb_next); 72 Py_CLEAR(tb->tb_frame); 73 } 74 75 PyTypeObject PyTraceBack_Type = { 76 PyVarObject_HEAD_INIT(&PyType_Type, 0) 77 "traceback", 78 sizeof(PyTracebackObject), 79 0, 80 (destructor)tb_dealloc, /*tp_dealloc*/ 81 0, /*tp_print*/ 82 0, /*tp_getattr*/ 83 0, /*tp_setattr*/ 84 0, /*tp_reserved*/ 85 0, /*tp_repr*/ 86 0, /*tp_as_number*/ 87 0, /*tp_as_sequence*/ 88 0, /*tp_as_mapping*/ 89 0, /* tp_hash */ 90 0, /* tp_call */ 91 0, /* tp_str */ 92 PyObject_GenericGetAttr, /* tp_getattro */ 93 0, /* tp_setattro */ 94 0, /* tp_as_buffer */ 95 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ 96 0, /* tp_doc */ 97 (traverseproc)tb_traverse, /* tp_traverse */ 98 (inquiry)tb_clear, /* tp_clear */ 99 0, /* tp_richcompare */ 100 0, /* tp_weaklistoffset */ 101 0, /* tp_iter */ 102 0, /* tp_iternext */ 103 tb_methods, /* tp_methods */ 104 tb_memberlist, /* tp_members */ 105 0, /* tp_getset */ 106 0, /* tp_base */ 107 0, /* tp_dict */ 108 }; 109 110 static PyTracebackObject * 111 newtracebackobject(PyTracebackObject *next, PyFrameObject *frame) 112 { 113 PyTracebackObject *tb; 114 if ((next != NULL && !PyTraceBack_Check(next)) || 115 frame == NULL || !PyFrame_Check(frame)) { 116 PyErr_BadInternalCall(); 117 return NULL; 118 } 119 tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type); 120 if (tb != NULL) { 121 Py_XINCREF(next); 122 tb->tb_next = next; 123 Py_XINCREF(frame); 124 tb->tb_frame = frame; 125 tb->tb_lasti = frame->f_lasti; 126 tb->tb_lineno = PyFrame_GetLineNumber(frame); 127 PyObject_GC_Track(tb); 128 } 129 return tb; 130 } 131 132 int 133 PyTraceBack_Here(PyFrameObject *frame) 134 { 135 PyObject *exc, *val, *tb, *newtb; 136 PyErr_Fetch(&exc, &val, &tb); 137 newtb = (PyObject *)newtracebackobject((PyTracebackObject *)tb, frame); 138 if (newtb == NULL) { 139 _PyErr_ChainExceptions(exc, val, tb); 140 return -1; 141 } 142 PyErr_Restore(exc, val, newtb); 143 Py_XDECREF(tb); 144 return 0; 145 } 146 147 /* Insert a frame into the traceback for (funcname, filename, lineno). */ 148 void _PyTraceback_Add(const char *funcname, const char *filename, int lineno) 149 { 150 PyObject *globals; 151 PyCodeObject *code; 152 PyFrameObject *frame; 153 PyObject *exc, *val, *tb; 154 155 /* Save and clear the current exception. Python functions must not be 156 called with an exception set. Calling Python functions happens when 157 the codec of the filesystem encoding is implemented in pure Python. */ 158 PyErr_Fetch(&exc, &val, &tb); 159 160 globals = PyDict_New(); 161 if (!globals) 162 goto error; 163 code = PyCode_NewEmpty(filename, funcname, lineno); 164 if (!code) { 165 Py_DECREF(globals); 166 goto error; 167 } 168 frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL); 169 Py_DECREF(globals); 170 Py_DECREF(code); 171 if (!frame) 172 goto error; 173 frame->f_lineno = lineno; 174 175 PyErr_Restore(exc, val, tb); 176 PyTraceBack_Here(frame); 177 Py_DECREF(frame); 178 return; 179 180 error: 181 _PyErr_ChainExceptions(exc, val, tb); 182 } 183 184 static PyObject * 185 _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io) 186 { 187 Py_ssize_t i; 188 PyObject *binary; 189 PyObject *v; 190 Py_ssize_t npath; 191 size_t taillen; 192 PyObject *syspath; 193 PyObject *path; 194 const char* tail; 195 PyObject *filebytes; 196 const char* filepath; 197 Py_ssize_t len; 198 PyObject* result; 199 200 filebytes = PyUnicode_EncodeFSDefault(filename); 201 if (filebytes == NULL) { 202 PyErr_Clear(); 203 return NULL; 204 } 205 filepath = PyBytes_AS_STRING(filebytes); 206 207 /* Search tail of filename in sys.path before giving up */ 208 tail = strrchr(filepath, SEP); 209 if (tail == NULL) 210 tail = filepath; 211 else 212 tail++; 213 taillen = strlen(tail); 214 215 syspath = _PySys_GetObjectId(&PyId_path); 216 if (syspath == NULL || !PyList_Check(syspath)) 217 goto error; 218 npath = PyList_Size(syspath); 219 220 for (i = 0; i < npath; i++) { 221 v = PyList_GetItem(syspath, i); 222 if (v == NULL) { 223 PyErr_Clear(); 224 break; 225 } 226 if (!PyUnicode_Check(v)) 227 continue; 228 path = PyUnicode_EncodeFSDefault(v); 229 if (path == NULL) { 230 PyErr_Clear(); 231 continue; 232 } 233 len = PyBytes_GET_SIZE(path); 234 if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) { 235 Py_DECREF(path); 236 continue; /* Too long */ 237 } 238 strcpy(namebuf, PyBytes_AS_STRING(path)); 239 Py_DECREF(path); 240 if (strlen(namebuf) != (size_t)len) 241 continue; /* v contains '\0' */ 242 if (len > 0 && namebuf[len-1] != SEP) 243 namebuf[len++] = SEP; 244 strcpy(namebuf+len, tail); 245 246 binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb"); 247 if (binary != NULL) { 248 result = binary; 249 goto finally; 250 } 251 PyErr_Clear(); 252 } 253 goto error; 254 255 error: 256 result = NULL; 257 finally: 258 Py_DECREF(filebytes); 259 return result; 260 } 261 262 int 263 _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) 264 { 265 int err = 0; 266 int fd; 267 int i; 268 char *found_encoding; 269 char *encoding; 270 PyObject *io; 271 PyObject *binary; 272 PyObject *fob = NULL; 273 PyObject *lineobj = NULL; 274 PyObject *res; 275 char buf[MAXPATHLEN+1]; 276 int kind; 277 void *data; 278 279 /* open the file */ 280 if (filename == NULL) 281 return 0; 282 283 io = PyImport_ImportModuleNoBlock("io"); 284 if (io == NULL) 285 return -1; 286 binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb"); 287 288 if (binary == NULL) { 289 PyErr_Clear(); 290 291 binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io); 292 if (binary == NULL) { 293 Py_DECREF(io); 294 return -1; 295 } 296 } 297 298 /* use the right encoding to decode the file as unicode */ 299 fd = PyObject_AsFileDescriptor(binary); 300 if (fd < 0) { 301 Py_DECREF(io); 302 Py_DECREF(binary); 303 return 0; 304 } 305 found_encoding = PyTokenizer_FindEncodingFilename(fd, filename); 306 if (found_encoding == NULL) 307 PyErr_Clear(); 308 encoding = (found_encoding != NULL) ? found_encoding : "utf-8"; 309 /* Reset position */ 310 if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { 311 Py_DECREF(io); 312 Py_DECREF(binary); 313 PyMem_FREE(found_encoding); 314 return 0; 315 } 316 fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding); 317 Py_DECREF(io); 318 PyMem_FREE(found_encoding); 319 320 if (fob == NULL) { 321 PyErr_Clear(); 322 323 res = _PyObject_CallMethodId(binary, &PyId_close, NULL); 324 Py_DECREF(binary); 325 if (res) 326 Py_DECREF(res); 327 else 328 PyErr_Clear(); 329 return 0; 330 } 331 Py_DECREF(binary); 332 333 /* get the line number lineno */ 334 for (i = 0; i < lineno; i++) { 335 Py_XDECREF(lineobj); 336 lineobj = PyFile_GetLine(fob, -1); 337 if (!lineobj) { 338 PyErr_Clear(); 339 err = -1; 340 break; 341 } 342 } 343 res = _PyObject_CallMethodId(fob, &PyId_close, NULL); 344 if (res) 345 Py_DECREF(res); 346 else 347 PyErr_Clear(); 348 Py_DECREF(fob); 349 if (!lineobj || !PyUnicode_Check(lineobj)) { 350 Py_XDECREF(lineobj); 351 return err; 352 } 353 354 /* remove the indentation of the line */ 355 kind = PyUnicode_KIND(lineobj); 356 data = PyUnicode_DATA(lineobj); 357 for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) { 358 Py_UCS4 ch = PyUnicode_READ(kind, data, i); 359 if (ch != ' ' && ch != '\t' && ch != '\014') 360 break; 361 } 362 if (i) { 363 PyObject *truncated; 364 truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj)); 365 if (truncated) { 366 Py_DECREF(lineobj); 367 lineobj = truncated; 368 } else { 369 PyErr_Clear(); 370 } 371 } 372 373 /* Write some spaces before the line */ 374 strcpy(buf, " "); 375 assert (strlen(buf) == 10); 376 while (indent > 0) { 377 if (indent < 10) 378 buf[indent] = '\0'; 379 err = PyFile_WriteString(buf, f); 380 if (err != 0) 381 break; 382 indent -= 10; 383 } 384 385 /* finally display the line */ 386 if (err == 0) 387 err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW); 388 Py_DECREF(lineobj); 389 if (err == 0) 390 err = PyFile_WriteString("\n", f); 391 return err; 392 } 393 394 static int 395 tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name) 396 { 397 int err; 398 PyObject *line; 399 400 if (filename == NULL || name == NULL) 401 return -1; 402 line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n", 403 filename, lineno, name); 404 if (line == NULL) 405 return -1; 406 err = PyFile_WriteObject(line, f, Py_PRINT_RAW); 407 Py_DECREF(line); 408 if (err != 0) 409 return err; 410 /* ignore errors since we can't report them, can we? */ 411 if (_Py_DisplaySourceLine(f, filename, lineno, 4)) 412 PyErr_Clear(); 413 return err; 414 } 415 416 static int 417 tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit) 418 { 419 int err = 0; 420 long depth = 0; 421 PyObject *last_file = NULL; 422 int last_line = -1; 423 PyObject *last_name = NULL; 424 long cnt = 0; 425 PyObject *line; 426 PyTracebackObject *tb1 = tb; 427 while (tb1 != NULL) { 428 depth++; 429 tb1 = tb1->tb_next; 430 } 431 while (tb != NULL && err == 0) { 432 if (depth <= limit) { 433 if (last_file != NULL && 434 tb->tb_frame->f_code->co_filename == last_file && 435 last_line != -1 && tb->tb_lineno == last_line && 436 last_name != NULL && 437 tb->tb_frame->f_code->co_name == last_name) { 438 cnt++; 439 } else { 440 if (cnt > 3) { 441 line = PyUnicode_FromFormat( 442 " [Previous line repeated %d more times]\n", cnt-3); 443 err = PyFile_WriteObject(line, f, Py_PRINT_RAW); 444 Py_DECREF(line); 445 } 446 last_file = tb->tb_frame->f_code->co_filename; 447 last_line = tb->tb_lineno; 448 last_name = tb->tb_frame->f_code->co_name; 449 cnt = 0; 450 } 451 if (cnt < 3) 452 err = tb_displayline(f, 453 tb->tb_frame->f_code->co_filename, 454 tb->tb_lineno, 455 tb->tb_frame->f_code->co_name); 456 } 457 depth--; 458 tb = tb->tb_next; 459 if (err == 0) 460 err = PyErr_CheckSignals(); 461 } 462 if (cnt > 3) { 463 line = PyUnicode_FromFormat( 464 " [Previous line repeated %d more times]\n", cnt-3); 465 err = PyFile_WriteObject(line, f, Py_PRINT_RAW); 466 Py_DECREF(line); 467 } 468 return err; 469 } 470 471 #define PyTraceBack_LIMIT 1000 472 473 int 474 PyTraceBack_Print(PyObject *v, PyObject *f) 475 { 476 int err; 477 PyObject *limitv; 478 long limit = PyTraceBack_LIMIT; 479 480 if (v == NULL) 481 return 0; 482 if (!PyTraceBack_Check(v)) { 483 PyErr_BadInternalCall(); 484 return -1; 485 } 486 limitv = PySys_GetObject("tracebacklimit"); 487 if (limitv) { 488 PyObject *exc_type, *exc_value, *exc_tb; 489 490 PyErr_Fetch(&exc_type, &exc_value, &exc_tb); 491 limit = PyLong_AsLong(limitv); 492 if (limit == -1 && PyErr_Occurred()) { 493 if (PyErr_ExceptionMatches(PyExc_OverflowError)) { 494 limit = PyTraceBack_LIMIT; 495 } 496 else { 497 Py_XDECREF(exc_type); 498 Py_XDECREF(exc_value); 499 Py_XDECREF(exc_tb); 500 return 0; 501 } 502 } 503 else if (limit <= 0) { 504 limit = PyTraceBack_LIMIT; 505 } 506 PyErr_Restore(exc_type, exc_value, exc_tb); 507 } 508 err = PyFile_WriteString("Traceback (most recent call last):\n", f); 509 if (!err) 510 err = tb_printinternal((PyTracebackObject *)v, f, limit); 511 return err; 512 } 513 514 /* Reverse a string. For example, "abcd" becomes "dcba". 515 516 This function is signal safe. */ 517 518 void 519 _Py_DumpDecimal(int fd, unsigned long value) 520 { 521 /* maximum number of characters required for output of %lld or %p. 522 We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits, 523 plus 1 for the null byte. 53/22 is an upper bound for log10(256). */ 524 char buffer[1 + (sizeof(unsigned long)*53-1) / 22 + 1]; 525 char *ptr, *end; 526 527 end = &buffer[Py_ARRAY_LENGTH(buffer) - 1]; 528 ptr = end; 529 *ptr = '\0'; 530 do { 531 --ptr; 532 assert(ptr >= buffer); 533 *ptr = '0' + (value % 10); 534 value /= 10; 535 } while (value); 536 537 _Py_write_noraise(fd, ptr, end - ptr); 538 } 539 540 /* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits, 541 and write it into the file fd. 542 543 This function is signal safe. */ 544 545 void 546 _Py_DumpHexadecimal(int fd, unsigned long value, Py_ssize_t width) 547 { 548 char buffer[sizeof(unsigned long) * 2 + 1], *ptr, *end; 549 const Py_ssize_t size = Py_ARRAY_LENGTH(buffer) - 1; 550 551 if (width > size) 552 width = size; 553 /* it's ok if width is negative */ 554 555 end = &buffer[size]; 556 ptr = end; 557 *ptr = '\0'; 558 do { 559 --ptr; 560 assert(ptr >= buffer); 561 *ptr = Py_hexdigits[value & 15]; 562 value >>= 4; 563 } while ((end - ptr) < width || value); 564 565 _Py_write_noraise(fd, ptr, end - ptr); 566 } 567 568 void 569 _Py_DumpASCII(int fd, PyObject *text) 570 { 571 PyASCIIObject *ascii = (PyASCIIObject *)text; 572 Py_ssize_t i, size; 573 int truncated; 574 int kind; 575 void *data = NULL; 576 wchar_t *wstr = NULL; 577 Py_UCS4 ch; 578 579 if (!PyUnicode_Check(text)) 580 return; 581 582 size = ascii->length; 583 kind = ascii->state.kind; 584 if (kind == PyUnicode_WCHAR_KIND) { 585 wstr = ((PyASCIIObject *)text)->wstr; 586 if (wstr == NULL) 587 return; 588 size = ((PyCompactUnicodeObject *)text)->wstr_length; 589 } 590 else if (ascii->state.compact) { 591 if (ascii->state.ascii) 592 data = ((PyASCIIObject*)text) + 1; 593 else 594 data = ((PyCompactUnicodeObject*)text) + 1; 595 } 596 else { 597 data = ((PyUnicodeObject *)text)->data.any; 598 if (data == NULL) 599 return; 600 } 601 602 if (MAX_STRING_LENGTH < size) { 603 size = MAX_STRING_LENGTH; 604 truncated = 1; 605 } 606 else { 607 truncated = 0; 608 } 609 610 for (i=0; i < size; i++) { 611 if (kind != PyUnicode_WCHAR_KIND) 612 ch = PyUnicode_READ(kind, data, i); 613 else 614 ch = wstr[i]; 615 if (' ' <= ch && ch <= 126) { 616 /* printable ASCII character */ 617 char c = (char)ch; 618 _Py_write_noraise(fd, &c, 1); 619 } 620 else if (ch <= 0xff) { 621 PUTS(fd, "\\x"); 622 _Py_DumpHexadecimal(fd, ch, 2); 623 } 624 else if (ch <= 0xffff) { 625 PUTS(fd, "\\u"); 626 _Py_DumpHexadecimal(fd, ch, 4); 627 } 628 else { 629 PUTS(fd, "\\U"); 630 _Py_DumpHexadecimal(fd, ch, 8); 631 } 632 } 633 if (truncated) { 634 PUTS(fd, "..."); 635 } 636 } 637 638 /* Write a frame into the file fd: "File "xxx", line xxx in xxx". 639 640 This function is signal safe. */ 641 642 static void 643 dump_frame(int fd, PyFrameObject *frame) 644 { 645 PyCodeObject *code; 646 int lineno; 647 648 code = frame->f_code; 649 PUTS(fd, " File "); 650 if (code != NULL && code->co_filename != NULL 651 && PyUnicode_Check(code->co_filename)) 652 { 653 PUTS(fd, "\""); 654 _Py_DumpASCII(fd, code->co_filename); 655 PUTS(fd, "\""); 656 } else { 657 PUTS(fd, "???"); 658 } 659 660 /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */ 661 lineno = PyCode_Addr2Line(code, frame->f_lasti); 662 PUTS(fd, ", line "); 663 if (lineno >= 0) { 664 _Py_DumpDecimal(fd, (unsigned long)lineno); 665 } 666 else { 667 PUTS(fd, "???"); 668 } 669 PUTS(fd, " in "); 670 671 if (code != NULL && code->co_name != NULL 672 && PyUnicode_Check(code->co_name)) { 673 _Py_DumpASCII(fd, code->co_name); 674 } 675 else { 676 PUTS(fd, "???"); 677 } 678 679 PUTS(fd, "\n"); 680 } 681 682 static void 683 dump_traceback(int fd, PyThreadState *tstate, int write_header) 684 { 685 PyFrameObject *frame; 686 unsigned int depth; 687 688 if (write_header) 689 PUTS(fd, "Stack (most recent call first):\n"); 690 691 frame = _PyThreadState_GetFrame(tstate); 692 if (frame == NULL) 693 return; 694 695 depth = 0; 696 while (frame != NULL) { 697 if (MAX_FRAME_DEPTH <= depth) { 698 PUTS(fd, " ...\n"); 699 break; 700 } 701 if (!PyFrame_Check(frame)) 702 break; 703 dump_frame(fd, frame); 704 frame = frame->f_back; 705 depth++; 706 } 707 } 708 709 /* Dump the traceback of a Python thread into fd. Use write() to write the 710 traceback and retry if write() is interrupted by a signal (failed with 711 EINTR), but don't call the Python signal handler. 712 713 The caller is responsible to call PyErr_CheckSignals() to call Python signal 714 handlers if signals were received. */ 715 void 716 _Py_DumpTraceback(int fd, PyThreadState *tstate) 717 { 718 dump_traceback(fd, tstate, 1); 719 } 720 721 /* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if 722 is_current is true, "Thread 0xHHHH:\n" otherwise. 723 724 This function is signal safe. */ 725 726 static void 727 write_thread_id(int fd, PyThreadState *tstate, int is_current) 728 { 729 if (is_current) 730 PUTS(fd, "Current thread 0x"); 731 else 732 PUTS(fd, "Thread 0x"); 733 _Py_DumpHexadecimal(fd, 734 (unsigned long)tstate->thread_id, 735 sizeof(unsigned long) * 2); 736 PUTS(fd, " (most recent call first):\n"); 737 } 738 739 /* Dump the traceback of all Python threads into fd. Use write() to write the 740 traceback and retry if write() is interrupted by a signal (failed with 741 EINTR), but don't call the Python signal handler. 742 743 The caller is responsible to call PyErr_CheckSignals() to call Python signal 744 handlers if signals were received. */ 745 const char* 746 _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, 747 PyThreadState *current_tstate) 748 { 749 PyThreadState *tstate; 750 unsigned int nthreads; 751 752 #ifdef WITH_THREAD 753 if (current_tstate == NULL) { 754 /* _Py_DumpTracebackThreads() is called from signal handlers by 755 faulthandler. 756 757 SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals 758 and are thus delivered to the thread that caused the fault. Get the 759 Python thread state of the current thread. 760 761 PyThreadState_Get() doesn't give the state of the thread that caused 762 the fault if the thread released the GIL, and so this function 763 cannot be used. Read the thread local storage (TLS) instead: call 764 PyGILState_GetThisThreadState(). */ 765 current_tstate = PyGILState_GetThisThreadState(); 766 } 767 768 if (interp == NULL) { 769 if (current_tstate == NULL) { 770 interp = _PyGILState_GetInterpreterStateUnsafe(); 771 if (interp == NULL) { 772 /* We need the interpreter state to get Python threads */ 773 return "unable to get the interpreter state"; 774 } 775 } 776 else { 777 interp = current_tstate->interp; 778 } 779 } 780 #else 781 if (current_tstate == NULL) { 782 /* Call _PyThreadState_UncheckedGet() instead of PyThreadState_Get() 783 to not fail with a fatal error if the thread state is NULL. */ 784 current_tstate = _PyThreadState_UncheckedGet(); 785 } 786 787 if (interp == NULL) { 788 if (current_tstate == NULL) { 789 /* We need the interpreter state to get Python threads */ 790 return "unable to get the interpreter state"; 791 } 792 interp = current_tstate->interp; 793 } 794 #endif 795 assert(interp != NULL); 796 797 /* Get the current interpreter from the current thread */ 798 tstate = PyInterpreterState_ThreadHead(interp); 799 if (tstate == NULL) 800 return "unable to get the thread head state"; 801 802 /* Dump the traceback of each thread */ 803 tstate = PyInterpreterState_ThreadHead(interp); 804 nthreads = 0; 805 _Py_BEGIN_SUPPRESS_IPH 806 do 807 { 808 if (nthreads != 0) 809 PUTS(fd, "\n"); 810 if (nthreads >= MAX_NTHREADS) { 811 PUTS(fd, "...\n"); 812 break; 813 } 814 write_thread_id(fd, tstate, tstate == current_tstate); 815 dump_traceback(fd, tstate, 0); 816 tstate = PyThreadState_Next(tstate); 817 nthreads++; 818 } while (tstate != NULL); 819 _Py_END_SUPPRESS_IPH 820 821 return NULL; 822 } 823 824