blob: 7d6f7f435a6ba6972300059c1db22a513a27a860 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum3f5da241990-12-20 15:06:42 +00002/* Traceback implementation */
3
Guido van Rossum65bf9f21997-04-29 18:33:38 +00004#include "Python.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +00005
Jeremy Hylton3e0055f2005-10-20 19:59:25 +00006#include "code.h"
Victor Stinner9b0bbb92021-06-21 14:23:13 +02007#include "pycore_interp.h" // PyInterpreterState.gc
Victor Stinner70364772020-04-29 03:28:46 +02008#include "frameobject.h" // PyFrame_GetBack()
Victor Stinner4a21e572020-04-15 02:35:41 +02009#include "structmember.h" // PyMemberDef
Victor Stinner361dcdc2020-04-15 03:24:57 +020010#include "osdefs.h" // SEP
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +000011#ifdef HAVE_FCNTL_H
12#include <fcntl.h>
13#endif
Guido van Rossum3f5da241990-12-20 15:06:42 +000014
Nicholas Bastina7604bf2004-03-21 18:37:23 +000015#define OFF(x) offsetof(PyTracebackObject, x)
Guido van Rossum3f5da241990-12-20 15:06:42 +000016
Victor Stinner97f86b82015-04-01 18:38:01 +020017#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str))
Victor Stinner54f939b2012-07-30 13:08:58 +020018#define MAX_STRING_LENGTH 500
Victor Stinner024e37a2011-03-31 01:31:06 +020019#define MAX_FRAME_DEPTH 100
20#define MAX_NTHREADS 100
21
Victor Stinnerfe7c5b52011-04-05 01:48:03 +020022/* Function from Parser/tokenizer.c */
23extern char * PyTokenizer_FindEncodingFilename(int, PyObject *);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +000024
Victor Stinnerbd303c12013-11-07 23:07:29 +010025_Py_IDENTIFIER(TextIOWrapper);
26_Py_IDENTIFIER(close);
27_Py_IDENTIFIER(open);
28_Py_IDENTIFIER(path);
29
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -080030/*[clinic input]
31class TracebackType "PyTracebackObject *" "&PyTraceback_Type"
32[clinic start generated code]*/
33/*[clinic end generated code: output=da39a3ee5e6b4b0d input=928fa06c10151120]*/
34
35#include "clinic/traceback.c.h"
36
37static PyObject *
38tb_create_raw(PyTracebackObject *next, PyFrameObject *frame, int lasti,
39 int lineno)
40{
41 PyTracebackObject *tb;
42 if ((next != NULL && !PyTraceBack_Check(next)) ||
43 frame == NULL || !PyFrame_Check(frame)) {
44 PyErr_BadInternalCall();
45 return NULL;
46 }
47 tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
48 if (tb != NULL) {
49 Py_XINCREF(next);
50 tb->tb_next = next;
51 Py_XINCREF(frame);
52 tb->tb_frame = frame;
53 tb->tb_lasti = lasti;
54 tb->tb_lineno = lineno;
55 PyObject_GC_Track(tb);
56 }
57 return (PyObject *)tb;
58}
59
60/*[clinic input]
61@classmethod
62TracebackType.__new__ as tb_new
63
64 tb_next: object
65 tb_frame: object(type='PyFrameObject *', subclass_of='&PyFrame_Type')
66 tb_lasti: int
67 tb_lineno: int
68
69Create a new traceback object.
70[clinic start generated code]*/
71
72static PyObject *
73tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame,
74 int tb_lasti, int tb_lineno)
75/*[clinic end generated code: output=fa077debd72d861a input=01cbe8ec8783fca7]*/
76{
77 if (tb_next == Py_None) {
78 tb_next = NULL;
79 } else if (!PyTraceBack_Check(tb_next)) {
80 return PyErr_Format(PyExc_TypeError,
81 "expected traceback object or None, got '%s'",
82 Py_TYPE(tb_next)->tp_name);
83 }
84
85 return tb_create_raw((PyTracebackObject *)tb_next, tb_frame, tb_lasti,
86 tb_lineno);
87}
88
Collin Winter3eed7652007-08-14 17:53:54 +000089static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +053090tb_dir(PyTracebackObject *self, PyObject *Py_UNUSED(ignored))
Collin Winter3eed7652007-08-14 17:53:54 +000091{
92 return Py_BuildValue("[ssss]", "tb_frame", "tb_next",
93 "tb_lasti", "tb_lineno");
94}
95
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -080096static PyObject *
97tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_))
98{
99 PyObject* ret = (PyObject*)self->tb_next;
100 if (!ret) {
101 ret = Py_None;
102 }
103 Py_INCREF(ret);
104 return ret;
105}
106
107static int
108tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_))
109{
110 if (!new_next) {
111 PyErr_Format(PyExc_TypeError, "can't delete tb_next attribute");
112 return -1;
113 }
114
115 /* We accept None or a traceback object, and map None -> NULL (inverse of
116 tb_next_get) */
117 if (new_next == Py_None) {
118 new_next = NULL;
119 } else if (!PyTraceBack_Check(new_next)) {
120 PyErr_Format(PyExc_TypeError,
121 "expected traceback object, got '%s'",
122 Py_TYPE(new_next)->tp_name);
123 return -1;
124 }
125
126 /* Check for loops */
127 PyTracebackObject *cursor = (PyTracebackObject *)new_next;
128 while (cursor) {
129 if (cursor == self) {
130 PyErr_Format(PyExc_ValueError, "traceback loop detected");
131 return -1;
132 }
133 cursor = cursor->tb_next;
134 }
135
136 PyObject *old_next = (PyObject*)self->tb_next;
137 Py_XINCREF(new_next);
138 self->tb_next = (PyTracebackObject *)new_next;
139 Py_XDECREF(old_next);
140
141 return 0;
142}
143
144
Collin Winter3eed7652007-08-14 17:53:54 +0000145static PyMethodDef tb_methods[] = {
146 {"__dir__", (PyCFunction)tb_dir, METH_NOARGS},
147 {NULL, NULL, 0, NULL},
148};
149
Neal Norwitz8dfc4a92007-08-11 06:39:53 +0000150static PyMemberDef tb_memberlist[] = {
Steve Dower87655e22021-04-30 01:08:55 +0100151 {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|PY_AUDIT_READ},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 {"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
153 {"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
154 {NULL} /* Sentinel */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000155};
156
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -0800157static PyGetSetDef tb_getsetters[] = {
158 {"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL},
159 {NULL} /* Sentinel */
160};
161
Guido van Rossum3f5da241990-12-20 15:06:42 +0000162static void
Nicholas Bastina7604bf2004-03-21 18:37:23 +0000163tb_dealloc(PyTracebackObject *tb)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 PyObject_GC_UnTrack(tb);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200166 Py_TRASHCAN_BEGIN(tb, tb_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 Py_XDECREF(tb->tb_next);
168 Py_XDECREF(tb->tb_frame);
169 PyObject_GC_Del(tb);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200170 Py_TRASHCAN_END
Guido van Rossum3f5da241990-12-20 15:06:42 +0000171}
172
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +0000173static int
Nicholas Bastina7604bf2004-03-21 18:37:23 +0000174tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +0000175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 Py_VISIT(tb->tb_next);
177 Py_VISIT(tb->tb_frame);
178 return 0;
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +0000179}
180
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200181static int
Nicholas Bastina7604bf2004-03-21 18:37:23 +0000182tb_clear(PyTracebackObject *tb)
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +0000183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 Py_CLEAR(tb->tb_next);
185 Py_CLEAR(tb->tb_frame);
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200186 return 0;
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +0000187}
188
Tim Petersd7c36522001-10-22 19:34:09 +0000189PyTypeObject PyTraceBack_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000190 PyVarObject_HEAD_INIT(&PyType_Type, 0)
191 "traceback",
192 sizeof(PyTracebackObject),
193 0,
194 (destructor)tb_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200195 0, /*tp_vectorcall_offset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 0, /*tp_getattr*/
197 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200198 0, /*tp_as_async*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 0, /*tp_repr*/
200 0, /*tp_as_number*/
201 0, /*tp_as_sequence*/
202 0, /*tp_as_mapping*/
203 0, /* tp_hash */
204 0, /* tp_call */
205 0, /* tp_str */
206 PyObject_GenericGetAttr, /* tp_getattro */
207 0, /* tp_setattro */
208 0, /* tp_as_buffer */
209 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -0800210 tb_new__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 (traverseproc)tb_traverse, /* tp_traverse */
212 (inquiry)tb_clear, /* tp_clear */
213 0, /* tp_richcompare */
214 0, /* tp_weaklistoffset */
215 0, /* tp_iter */
216 0, /* tp_iternext */
217 tb_methods, /* tp_methods */
218 tb_memberlist, /* tp_members */
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -0800219 tb_getsetters, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 0, /* tp_base */
221 0, /* tp_dict */
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -0800222 0, /* tp_descr_get */
223 0, /* tp_descr_set */
224 0, /* tp_dictoffset */
225 0, /* tp_init */
226 0, /* tp_alloc */
227 tb_new, /* tp_new */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000228};
229
Victor Stinnerdf22c032019-05-23 01:00:58 +0200230
231PyObject*
232_PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
233{
234 assert(tb_next == NULL || PyTraceBack_Check(tb_next));
235 assert(frame != NULL);
236
Serhiy Storchakab5499782021-10-04 15:01:11 +0300237 return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti*sizeof(_Py_CODEUNIT),
Victor Stinnerdf22c032019-05-23 01:00:58 +0200238 PyFrame_GetLineNumber(frame));
239}
240
241
Guido van Rossum3f5da241990-12-20 15:06:42 +0000242int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000243PyTraceBack_Here(PyFrameObject *frame)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000244{
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300245 PyObject *exc, *val, *tb, *newtb;
246 PyErr_Fetch(&exc, &val, &tb);
Victor Stinnerdf22c032019-05-23 01:00:58 +0200247 newtb = _PyTraceBack_FromFrame(tb, frame);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300248 if (newtb == NULL) {
249 _PyErr_ChainExceptions(exc, val, tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 return -1;
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300251 }
252 PyErr_Restore(exc, val, newtb);
253 Py_XDECREF(tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 return 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000255}
256
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200257/* Insert a frame into the traceback for (funcname, filename, lineno). */
Serhiy Storchaka73c95f12015-06-21 15:59:46 +0300258void _PyTraceback_Add(const char *funcname, const char *filename, int lineno)
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200259{
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300260 PyObject *globals;
261 PyCodeObject *code;
262 PyFrameObject *frame;
263 PyObject *exc, *val, *tb;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200264
265 /* Save and clear the current exception. Python functions must not be
266 called with an exception set. Calling Python functions happens when
267 the codec of the filesystem encoding is implemented in pure Python. */
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300268 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200269
270 globals = PyDict_New();
271 if (!globals)
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300272 goto error;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200273 code = PyCode_NewEmpty(filename, funcname, lineno);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300274 if (!code) {
275 Py_DECREF(globals);
276 goto error;
277 }
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200278 frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300279 Py_DECREF(globals);
280 Py_DECREF(code);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200281 if (!frame)
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300282 goto error;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200283 frame->f_lineno = lineno;
284
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300285 PyErr_Restore(exc, val, tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200286 PyTraceBack_Here(frame);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300287 Py_DECREF(frame);
288 return;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200289
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300290error:
291 _PyErr_ChainExceptions(exc, val, tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200292}
293
Victor Stinner0fe25a42010-06-17 23:08:50 +0000294static PyObject *
295_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000296{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000297 Py_ssize_t i;
298 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 PyObject *v;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000300 Py_ssize_t npath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 size_t taillen;
302 PyObject *syspath;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000303 PyObject *path;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 const char* tail;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000305 PyObject *filebytes;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000306 const char* filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 Py_ssize_t len;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000308 PyObject* result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000309
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000310 filebytes = PyUnicode_EncodeFSDefault(filename);
311 if (filebytes == NULL) {
Victor Stinner0fe25a42010-06-17 23:08:50 +0000312 PyErr_Clear();
313 return NULL;
314 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000315 filepath = PyBytes_AS_STRING(filebytes);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 /* Search tail of filename in sys.path before giving up */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000318 tail = strrchr(filepath, SEP);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 if (tail == NULL)
Victor Stinner0fe25a42010-06-17 23:08:50 +0000320 tail = filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 else
322 tail++;
323 taillen = strlen(tail);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000324
Victor Stinnerbd303c12013-11-07 23:07:29 +0100325 syspath = _PySys_GetObjectId(&PyId_path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 if (syspath == NULL || !PyList_Check(syspath))
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000327 goto error;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000328 npath = PyList_Size(syspath);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 for (i = 0; i < npath; i++) {
331 v = PyList_GetItem(syspath, i);
332 if (v == NULL) {
333 PyErr_Clear();
334 break;
335 }
336 if (!PyUnicode_Check(v))
337 continue;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000338 path = PyUnicode_EncodeFSDefault(v);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000339 if (path == NULL) {
340 PyErr_Clear();
341 continue;
342 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000343 len = PyBytes_GET_SIZE(path);
344 if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) {
345 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 continue; /* Too long */
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000347 }
348 strcpy(namebuf, PyBytes_AS_STRING(path));
349 Py_DECREF(path);
Victor Stinner98ea54c2014-08-15 23:30:40 +0200350 if (strlen(namebuf) != (size_t)len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 continue; /* v contains '\0' */
352 if (len > 0 && namebuf[len-1] != SEP)
353 namebuf[len++] = SEP;
354 strcpy(namebuf+len, tail);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000355
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200356 binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb");
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000357 if (binary != NULL) {
358 result = binary;
359 goto finally;
360 }
Victor Stinner0fe25a42010-06-17 23:08:50 +0000361 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000363 goto error;
364
365error:
366 result = NULL;
367finally:
368 Py_DECREF(filebytes);
369 return result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000370}
371
Christian Heimes33fe8092008-04-13 13:53:33 +0000372int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000373_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 int err = 0;
376 int fd;
377 int i;
378 char *found_encoding;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300379 const char *encoding;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000380 PyObject *io;
381 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 PyObject *fob = NULL;
383 PyObject *lineobj = NULL;
Antoine Pitroub86680e2010-10-14 21:15:17 +0000384 PyObject *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 char buf[MAXPATHLEN+1];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200386 int kind;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300387 const void *data;
Christian Heimes679db4a2008-01-18 09:56:22 +0000388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 /* open the file */
390 if (filename == NULL)
391 return 0;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000392
393 io = PyImport_ImportModuleNoBlock("io");
394 if (io == NULL)
395 return -1;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200396 binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");
Victor Stinner0fe25a42010-06-17 23:08:50 +0000397
398 if (binary == NULL) {
Victor Stinnerceceaa02013-07-16 00:32:14 +0200399 PyErr_Clear();
400
Victor Stinner0fe25a42010-06-17 23:08:50 +0000401 binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
402 if (binary == NULL) {
403 Py_DECREF(io);
Victor Stinnerceceaa02013-07-16 00:32:14 +0200404 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000405 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 /* use the right encoding to decode the file as unicode */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000409 fd = PyObject_AsFileDescriptor(binary);
Christian Heimes8c077bc2013-07-21 01:53:10 +0200410 if (fd < 0) {
411 Py_DECREF(io);
412 Py_DECREF(binary);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700413 return 0;
Christian Heimes8c077bc2013-07-21 01:53:10 +0200414 }
Victor Stinnerfe7c5b52011-04-05 01:48:03 +0200415 found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
Victor Stinner5272fa92013-12-19 13:39:32 +0100416 if (found_encoding == NULL)
417 PyErr_Clear();
Victor Stinner0fe25a42010-06-17 23:08:50 +0000418 encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
Christian Heimes1f347292013-07-21 02:12:35 +0200419 /* Reset position */
420 if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
421 Py_DECREF(io);
422 Py_DECREF(binary);
Victor Stinner00d7abd2020-12-01 09:56:42 +0100423 PyMem_Free(found_encoding);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700424 return 0;
Christian Heimes1f347292013-07-21 02:12:35 +0200425 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200426 fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000427 Py_DECREF(io);
Victor Stinner00d7abd2020-12-01 09:56:42 +0100428 PyMem_Free(found_encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 if (fob == NULL) {
431 PyErr_Clear();
Victor Stinner81f241a2015-03-25 02:25:25 +0100432
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200433 res = _PyObject_CallMethodIdNoArgs(binary, &PyId_close);
Victor Stinner81f241a2015-03-25 02:25:25 +0100434 Py_DECREF(binary);
435 if (res)
436 Py_DECREF(res);
437 else
438 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 return 0;
440 }
Victor Stinner81f241a2015-03-25 02:25:25 +0100441 Py_DECREF(binary);
Christian Heimes33fe8092008-04-13 13:53:33 +0000442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 /* get the line number lineno */
444 for (i = 0; i < lineno; i++) {
445 Py_XDECREF(lineobj);
446 lineobj = PyFile_GetLine(fob, -1);
447 if (!lineobj) {
Victor Stinner5e78f4d2014-10-30 10:17:27 +0100448 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 err = -1;
450 break;
451 }
452 }
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200453 res = _PyObject_CallMethodIdNoArgs(fob, &PyId_close);
Antoine Pitroub86680e2010-10-14 21:15:17 +0000454 if (res)
455 Py_DECREF(res);
456 else
457 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 Py_DECREF(fob);
459 if (!lineobj || !PyUnicode_Check(lineobj)) {
460 Py_XDECREF(lineobj);
461 return err;
462 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 /* remove the indentation of the line */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200465 kind = PyUnicode_KIND(lineobj);
466 data = PyUnicode_DATA(lineobj);
467 for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) {
468 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
469 if (ch != ' ' && ch != '\t' && ch != '\014')
470 break;
471 }
472 if (i) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 PyObject *truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200474 truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 if (truncated) {
476 Py_DECREF(lineobj);
477 lineobj = truncated;
478 } else {
479 PyErr_Clear();
480 }
481 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 /* Write some spaces before the line */
484 strcpy(buf, " ");
485 assert (strlen(buf) == 10);
486 while (indent > 0) {
Benjamin Peterson0f9b7d32013-07-21 13:29:37 -0700487 if (indent < 10)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 buf[indent] = '\0';
489 err = PyFile_WriteString(buf, f);
490 if (err != 0)
491 break;
492 indent -= 10;
493 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 /* finally display the line */
496 if (err == 0)
497 err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
498 Py_DECREF(lineobj);
499 if (err == 0)
500 err = PyFile_WriteString("\n", f);
501 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000502}
503
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000504static int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000505tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000506{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000507 int err;
508 PyObject *line;
Christian Heimes33fe8092008-04-13 13:53:33 +0000509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 if (filename == NULL || name == NULL)
511 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000512 line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
513 filename, lineno, name);
514 if (line == NULL)
515 return -1;
516 err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
517 Py_DECREF(line);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 if (err != 0)
519 return err;
Kristján Valur Jónssonc5963d32012-07-19 21:02:03 +0000520 /* ignore errors since we can't report them, can we? */
521 if (_Py_DisplaySourceLine(f, filename, lineno, 4))
522 PyErr_Clear();
523 return err;
Christian Heimes33fe8092008-04-13 13:53:33 +0000524}
525
Benjamin Petersond5458692018-09-10 08:43:10 -0700526static const int TB_RECURSIVE_CUTOFF = 3; // Also hardcoded in traceback.py.
527
Christian Heimes33fe8092008-04-13 13:53:33 +0000528static int
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200529tb_print_line_repeated(PyObject *f, long cnt)
530{
Benjamin Petersond5458692018-09-10 08:43:10 -0700531 cnt -= TB_RECURSIVE_CUTOFF;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200532 PyObject *line = PyUnicode_FromFormat(
Benjamin Petersond5458692018-09-10 08:43:10 -0700533 (cnt > 1)
534 ? " [Previous line repeated %ld more times]\n"
535 : " [Previous line repeated %ld more time]\n",
536 cnt);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200537 if (line == NULL) {
538 return -1;
539 }
Benjamin Petersond5458692018-09-10 08:43:10 -0700540 int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200541 Py_DECREF(line);
542 return err;
543}
544
545static int
Christian Heimes33fe8092008-04-13 13:53:33 +0000546tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 int err = 0;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200549 Py_ssize_t depth = 0;
Nick Coghland0034232016-08-15 13:11:34 +1000550 PyObject *last_file = NULL;
551 int last_line = -1;
552 PyObject *last_name = NULL;
553 long cnt = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 PyTracebackObject *tb1 = tb;
555 while (tb1 != NULL) {
556 depth++;
557 tb1 = tb1->tb_next;
558 }
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200559 while (tb != NULL && depth > limit) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 depth--;
561 tb = tb->tb_next;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 }
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200563 while (tb != NULL && err == 0) {
Victor Stinnera42ca742020-04-28 19:01:31 +0200564 PyCodeObject *code = PyFrame_GetCode(tb->tb_frame);
Benjamin Petersond5458692018-09-10 08:43:10 -0700565 if (last_file == NULL ||
Victor Stinnera42ca742020-04-28 19:01:31 +0200566 code->co_filename != last_file ||
Benjamin Petersond5458692018-09-10 08:43:10 -0700567 last_line == -1 || tb->tb_lineno != last_line ||
Victor Stinnera42ca742020-04-28 19:01:31 +0200568 last_name == NULL || code->co_name != last_name) {
Benjamin Petersond5458692018-09-10 08:43:10 -0700569 if (cnt > TB_RECURSIVE_CUTOFF) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200570 err = tb_print_line_repeated(f, cnt);
571 }
Victor Stinnera42ca742020-04-28 19:01:31 +0200572 last_file = code->co_filename;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200573 last_line = tb->tb_lineno;
Victor Stinnera42ca742020-04-28 19:01:31 +0200574 last_name = code->co_name;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200575 cnt = 0;
576 }
Benjamin Petersond5458692018-09-10 08:43:10 -0700577 cnt++;
578 if (err == 0 && cnt <= TB_RECURSIVE_CUTOFF) {
Victor Stinnera42ca742020-04-28 19:01:31 +0200579 err = tb_displayline(f, code->co_filename, tb->tb_lineno,
580 code->co_name);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200581 if (err == 0) {
582 err = PyErr_CheckSignals();
583 }
584 }
Victor Stinner8852ad42020-04-29 01:28:13 +0200585 Py_DECREF(code);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200586 tb = tb->tb_next;
587 }
Benjamin Petersond5458692018-09-10 08:43:10 -0700588 if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200589 err = tb_print_line_repeated(f, cnt);
Nick Coghland0034232016-08-15 13:11:34 +1000590 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000592}
593
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000594#define PyTraceBack_LIMIT 1000
595
Guido van Rossum3f5da241990-12-20 15:06:42 +0000596int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000597PyTraceBack_Print(PyObject *v, PyObject *f)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000598{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 int err;
600 PyObject *limitv;
601 long limit = PyTraceBack_LIMIT;
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 if (v == NULL)
604 return 0;
605 if (!PyTraceBack_Check(v)) {
606 PyErr_BadInternalCall();
607 return -1;
608 }
609 limitv = PySys_GetObject("tracebacklimit");
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200610 if (limitv && PyLong_Check(limitv)) {
611 int overflow;
612 limit = PyLong_AsLongAndOverflow(limitv, &overflow);
613 if (overflow > 0) {
614 limit = LONG_MAX;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 }
616 else if (limit <= 0) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200617 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 }
620 err = PyFile_WriteString("Traceback (most recent call last):\n", f);
621 if (!err)
622 err = tb_printinternal((PyTracebackObject *)v, f, limit);
623 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000624}
Victor Stinner024e37a2011-03-31 01:31:06 +0200625
Irit Katriel40125ab2020-12-17 12:33:07 +0000626/* Format an integer in range [0; 0xffffffff] to decimal and write it
627 into the file fd.
Victor Stinner024e37a2011-03-31 01:31:06 +0200628
629 This function is signal safe. */
630
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100631void
Victor Stinner66f77ca2021-01-19 23:35:27 +0100632_Py_DumpDecimal(int fd, size_t value)
Victor Stinner024e37a2011-03-31 01:31:06 +0200633{
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100634 /* maximum number of characters required for output of %lld or %p.
635 We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits,
636 plus 1 for the null byte. 53/22 is an upper bound for log10(256). */
Victor Stinner66f77ca2021-01-19 23:35:27 +0100637 char buffer[1 + (sizeof(size_t)*53-1) / 22 + 1];
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100638 char *ptr, *end;
Victor Stinner024e37a2011-03-31 01:31:06 +0200639
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100640 end = &buffer[Py_ARRAY_LENGTH(buffer) - 1];
641 ptr = end;
642 *ptr = '\0';
Victor Stinner024e37a2011-03-31 01:31:06 +0200643 do {
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100644 --ptr;
645 assert(ptr >= buffer);
646 *ptr = '0' + (value % 10);
Victor Stinner024e37a2011-03-31 01:31:06 +0200647 value /= 10;
Victor Stinner024e37a2011-03-31 01:31:06 +0200648 } while (value);
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100649
650 _Py_write_noraise(fd, ptr, end - ptr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200651}
652
Victor Stinner314b8782021-01-18 18:34:56 +0100653/* Format an integer as hexadecimal with width digits into fd file descriptor.
654 The function is signal safe. */
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100655void
Victor Stinner314b8782021-01-18 18:34:56 +0100656_Py_DumpHexadecimal(int fd, uintptr_t value, Py_ssize_t width)
Victor Stinner024e37a2011-03-31 01:31:06 +0200657{
Victor Stinner314b8782021-01-18 18:34:56 +0100658 char buffer[sizeof(uintptr_t) * 2 + 1], *ptr, *end;
Victor Stinner013024e2016-03-16 09:43:14 +0100659 const Py_ssize_t size = Py_ARRAY_LENGTH(buffer) - 1;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100660
661 if (width > size)
662 width = size;
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100663 /* it's ok if width is negative */
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100664
Victor Stinner013024e2016-03-16 09:43:14 +0100665 end = &buffer[size];
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100666 ptr = end;
667 *ptr = '\0';
Victor Stinner024e37a2011-03-31 01:31:06 +0200668 do {
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100669 --ptr;
670 assert(ptr >= buffer);
671 *ptr = Py_hexdigits[value & 15];
Victor Stinner024e37a2011-03-31 01:31:06 +0200672 value >>= 4;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100673 } while ((end - ptr) < width || value);
674
675 _Py_write_noraise(fd, ptr, end - ptr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200676}
677
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100678void
679_Py_DumpASCII(int fd, PyObject *text)
Victor Stinner024e37a2011-03-31 01:31:06 +0200680{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200681 PyASCIIObject *ascii = (PyASCIIObject *)text;
Victor Stinner024e37a2011-03-31 01:31:06 +0200682 Py_ssize_t i, size;
683 int truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200684 int kind;
Victor Stinnera336de72011-10-05 22:44:12 +0200685 void *data = NULL;
686 wchar_t *wstr = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200687 Py_UCS4 ch;
Victor Stinner024e37a2011-03-31 01:31:06 +0200688
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100689 if (!PyUnicode_Check(text))
690 return;
691
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200692 size = ascii->length;
693 kind = ascii->state.kind;
Victor Stinner1c3069a2016-03-23 16:10:07 +0100694 if (kind == PyUnicode_WCHAR_KIND) {
695 wstr = ((PyASCIIObject *)text)->wstr;
696 if (wstr == NULL)
697 return;
698 size = ((PyCompactUnicodeObject *)text)->wstr_length;
699 }
700 else if (ascii->state.compact) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200701 if (ascii->state.ascii)
702 data = ((PyASCIIObject*)text) + 1;
703 else
704 data = ((PyCompactUnicodeObject*)text) + 1;
705 }
Victor Stinner1c3069a2016-03-23 16:10:07 +0100706 else {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200707 data = ((PyUnicodeObject *)text)->data.any;
708 if (data == NULL)
709 return;
710 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200711
712 if (MAX_STRING_LENGTH < size) {
713 size = MAX_STRING_LENGTH;
714 truncated = 1;
715 }
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100716 else {
Victor Stinner024e37a2011-03-31 01:31:06 +0200717 truncated = 0;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100718 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200719
Miss Islington (bot)4ffde902021-11-17 13:59:19 -0800720 // Is an ASCII string?
721 if (ascii->state.ascii) {
722 assert(kind == PyUnicode_1BYTE_KIND);
723 char *str = data;
724
725 int need_escape = 0;
726 for (i=0; i < size; i++) {
727 ch = str[i];
728 if (!(' ' <= ch && ch <= 126)) {
729 need_escape = 1;
730 break;
731 }
732 }
733 if (!need_escape) {
734 // The string can be written with a single write() syscall
735 _Py_write_noraise(fd, str, size);
736 goto done;
737 }
738 }
739
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200740 for (i=0; i < size; i++) {
Victor Stinnera336de72011-10-05 22:44:12 +0200741 if (kind != PyUnicode_WCHAR_KIND)
742 ch = PyUnicode_READ(kind, data, i);
743 else
744 ch = wstr[i];
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200745 if (' ' <= ch && ch <= 126) {
746 /* printable ASCII character */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200747 char c = (char)ch;
Victor Stinner97f86b82015-04-01 18:38:01 +0200748 _Py_write_noraise(fd, &c, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200749 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200750 else if (ch <= 0xff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200751 PUTS(fd, "\\x");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100752 _Py_DumpHexadecimal(fd, ch, 2);
Victor Stinner024e37a2011-03-31 01:31:06 +0200753 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200754 else if (ch <= 0xffff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200755 PUTS(fd, "\\u");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100756 _Py_DumpHexadecimal(fd, ch, 4);
Victor Stinner024e37a2011-03-31 01:31:06 +0200757 }
758 else {
759 PUTS(fd, "\\U");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100760 _Py_DumpHexadecimal(fd, ch, 8);
Victor Stinner024e37a2011-03-31 01:31:06 +0200761 }
762 }
Miss Islington (bot)4ffde902021-11-17 13:59:19 -0800763
764done:
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100765 if (truncated) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200766 PUTS(fd, "...");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100767 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200768}
769
770/* Write a frame into the file fd: "File "xxx", line xxx in xxx".
771
772 This function is signal safe. */
773
774static void
775dump_frame(int fd, PyFrameObject *frame)
776{
Victor Stinner8852ad42020-04-29 01:28:13 +0200777 PyCodeObject *code = PyFrame_GetCode(frame);
Victor Stinner024e37a2011-03-31 01:31:06 +0200778 PUTS(fd, " File ");
Victor Stinner8852ad42020-04-29 01:28:13 +0200779 if (code->co_filename != NULL
Victor Stinner024e37a2011-03-31 01:31:06 +0200780 && PyUnicode_Check(code->co_filename))
781 {
Victor Stinner97f86b82015-04-01 18:38:01 +0200782 PUTS(fd, "\"");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100783 _Py_DumpASCII(fd, code->co_filename);
Victor Stinner97f86b82015-04-01 18:38:01 +0200784 PUTS(fd, "\"");
Victor Stinner024e37a2011-03-31 01:31:06 +0200785 } else {
786 PUTS(fd, "???");
787 }
788
Mark Shannonfcb55c02021-04-01 16:00:31 +0100789 int lineno = PyFrame_GetLineNumber(frame);
Victor Stinner024e37a2011-03-31 01:31:06 +0200790 PUTS(fd, ", line ");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100791 if (lineno >= 0) {
Victor Stinner66f77ca2021-01-19 23:35:27 +0100792 _Py_DumpDecimal(fd, (size_t)lineno);
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100793 }
794 else {
795 PUTS(fd, "???");
796 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200797 PUTS(fd, " in ");
798
Victor Stinner8852ad42020-04-29 01:28:13 +0200799 if (code->co_name != NULL
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100800 && PyUnicode_Check(code->co_name)) {
801 _Py_DumpASCII(fd, code->co_name);
802 }
803 else {
Victor Stinner024e37a2011-03-31 01:31:06 +0200804 PUTS(fd, "???");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100805 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200806
Victor Stinner97f86b82015-04-01 18:38:01 +0200807 PUTS(fd, "\n");
Victor Stinner8852ad42020-04-29 01:28:13 +0200808 Py_DECREF(code);
Victor Stinner024e37a2011-03-31 01:31:06 +0200809}
810
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200811static void
Victor Stinner024e37a2011-03-31 01:31:06 +0200812dump_traceback(int fd, PyThreadState *tstate, int write_header)
813{
814 PyFrameObject *frame;
815 unsigned int depth;
816
Victor Stinner8fa3e172019-09-17 23:36:16 +0200817 if (write_header) {
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700818 PUTS(fd, "Stack (most recent call first):\n");
Victor Stinner8fa3e172019-09-17 23:36:16 +0200819 }
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200820
Victor Stinnerfe997e12021-08-30 15:24:39 +0200821 // Use a borrowed reference. Avoid Py_INCREF/Py_DECREF, since this function
822 // can be called in a signal handler by the faulthandler module which must
823 // not modify Python objects.
824 frame = tstate->frame;
Victor Stinner8fa3e172019-09-17 23:36:16 +0200825 if (frame == NULL) {
Miss Islington (bot)c4c57e52021-08-31 08:53:17 -0700826 PUTS(fd, " <no Python frame>\n");
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200827 return;
Victor Stinner8fa3e172019-09-17 23:36:16 +0200828 }
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200829
Victor Stinner024e37a2011-03-31 01:31:06 +0200830 depth = 0;
Victor Stinner70364772020-04-29 03:28:46 +0200831 while (1) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200832 if (MAX_FRAME_DEPTH <= depth) {
833 PUTS(fd, " ...\n");
834 break;
835 }
Victor Stinner70364772020-04-29 03:28:46 +0200836 if (!PyFrame_Check(frame)) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200837 break;
Victor Stinner70364772020-04-29 03:28:46 +0200838 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200839 dump_frame(fd, frame);
Victor Stinnerfe997e12021-08-30 15:24:39 +0200840 PyFrameObject *back = frame->f_back;
Victor Stinner70364772020-04-29 03:28:46 +0200841
842 if (back == NULL) {
843 break;
844 }
845 frame = back;
Victor Stinner024e37a2011-03-31 01:31:06 +0200846 depth++;
847 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200848}
849
Victor Stinner97f86b82015-04-01 18:38:01 +0200850/* Dump the traceback of a Python thread into fd. Use write() to write the
851 traceback and retry if write() is interrupted by a signal (failed with
852 EINTR), but don't call the Python signal handler.
853
854 The caller is responsible to call PyErr_CheckSignals() to call Python signal
855 handlers if signals were received. */
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200856void
Victor Stinner024e37a2011-03-31 01:31:06 +0200857_Py_DumpTraceback(int fd, PyThreadState *tstate)
858{
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200859 dump_traceback(fd, tstate, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200860}
861
862/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
863 is_current is true, "Thread 0xHHHH:\n" otherwise.
864
865 This function is signal safe. */
866
867static void
868write_thread_id(int fd, PyThreadState *tstate, int is_current)
869{
870 if (is_current)
871 PUTS(fd, "Current thread 0x");
872 else
873 PUTS(fd, "Thread 0x");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100874 _Py_DumpHexadecimal(fd,
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200875 tstate->thread_id,
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100876 sizeof(unsigned long) * 2);
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700877 PUTS(fd, " (most recent call first):\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200878}
879
Victor Stinner97f86b82015-04-01 18:38:01 +0200880/* Dump the traceback of all Python threads into fd. Use write() to write the
881 traceback and retry if write() is interrupted by a signal (failed with
882 EINTR), but don't call the Python signal handler.
883
884 The caller is responsible to call PyErr_CheckSignals() to call Python signal
885 handlers if signals were received. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200886const char*
887_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
Victor Stinner861d9ab2016-03-16 22:45:24 +0100888 PyThreadState *current_tstate)
Victor Stinner024e37a2011-03-31 01:31:06 +0200889{
890 PyThreadState *tstate;
891 unsigned int nthreads;
892
Victor Stinner861d9ab2016-03-16 22:45:24 +0100893 if (current_tstate == NULL) {
894 /* _Py_DumpTracebackThreads() is called from signal handlers by
895 faulthandler.
896
897 SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals
898 and are thus delivered to the thread that caused the fault. Get the
899 Python thread state of the current thread.
900
901 PyThreadState_Get() doesn't give the state of the thread that caused
Victor Stinner8fa3e172019-09-17 23:36:16 +0200902 the fault if the thread released the GIL, and so
903 _PyThreadState_GET() cannot be used. Read the thread specific
904 storage (TSS) instead: call PyGILState_GetThisThreadState(). */
Victor Stinner861d9ab2016-03-16 22:45:24 +0100905 current_tstate = PyGILState_GetThisThreadState();
906 }
907
908 if (interp == NULL) {
909 if (current_tstate == NULL) {
910 interp = _PyGILState_GetInterpreterStateUnsafe();
911 if (interp == NULL) {
912 /* We need the interpreter state to get Python threads */
913 return "unable to get the interpreter state";
914 }
915 }
916 else {
917 interp = current_tstate->interp;
918 }
919 }
Victor Stinner861d9ab2016-03-16 22:45:24 +0100920 assert(interp != NULL);
921
Victor Stinner024e37a2011-03-31 01:31:06 +0200922 /* Get the current interpreter from the current thread */
923 tstate = PyInterpreterState_ThreadHead(interp);
924 if (tstate == NULL)
925 return "unable to get the thread head state";
926
927 /* Dump the traceback of each thread */
928 tstate = PyInterpreterState_ThreadHead(interp);
929 nthreads = 0;
Steve Dower8fc89802015-04-12 00:26:27 -0400930 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner024e37a2011-03-31 01:31:06 +0200931 do
932 {
933 if (nthreads != 0)
Victor Stinner97f86b82015-04-01 18:38:01 +0200934 PUTS(fd, "\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200935 if (nthreads >= MAX_NTHREADS) {
936 PUTS(fd, "...\n");
937 break;
938 }
Victor Stinner861d9ab2016-03-16 22:45:24 +0100939 write_thread_id(fd, tstate, tstate == current_tstate);
Victor Stinner9b0bbb92021-06-21 14:23:13 +0200940 if (tstate == current_tstate && tstate->interp->gc.collecting) {
941 PUTS(fd, " Garbage-collecting\n");
942 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200943 dump_traceback(fd, tstate, 0);
944 tstate = PyThreadState_Next(tstate);
945 nthreads++;
946 } while (tstate != NULL);
Steve Dower8fc89802015-04-12 00:26:27 -0400947 _Py_END_SUPPRESS_IPH
Victor Stinner024e37a2011-03-31 01:31:06 +0200948
949 return NULL;
950}
951