ยปCore Development>Code coverage>Python/traceback.c

Python code coverage for Python/traceback.c

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