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 *
tb_dir(PyTracebackObject * self)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
tb_dealloc(PyTracebackObject * tb)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
tb_traverse(PyTracebackObject * tb,visitproc visit,void * arg)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
tb_clear(PyTracebackObject * tb)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 *
newtracebackobject(PyTracebackObject * next,PyFrameObject * frame)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
PyTraceBack_Here(PyFrameObject * frame)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). */
_PyTraceback_Add(const char * funcname,const char * filename,int 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 *
_Py_FindSourceFile(PyObject * filename,char * namebuf,size_t namelen,PyObject * io)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
_Py_DisplaySourceLine(PyObject * f,PyObject * filename,int lineno,int indent)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
tb_displayline(PyObject * f,PyObject * filename,int lineno,PyObject * name)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
tb_printinternal(PyTracebackObject * tb,PyObject * f,long limit)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
PyTraceBack_Print(PyObject * v,PyObject * f)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
_Py_DumpDecimal(int fd,unsigned long value)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
_Py_DumpHexadecimal(int fd,unsigned long value,Py_ssize_t width)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
_Py_DumpASCII(int fd,PyObject * text)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
dump_frame(int fd,PyFrameObject * frame)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
dump_traceback(int fd,PyThreadState * tstate,int write_header)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
_Py_DumpTraceback(int fd,PyThreadState * tstate)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
write_thread_id(int fd,PyThreadState * tstate,int is_current)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*
_Py_DumpTracebackThreads(int fd,PyInterpreterState * interp,PyThreadState * current_tstate)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