blob: 470324b1afd83f5ba9da4203b0fc49818ccf99ae [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 Stinner70364772020-04-29 03:28:46 +02007#include "frameobject.h" // PyFrame_GetBack()
Victor Stinner4a21e572020-04-15 02:35:41 +02008#include "structmember.h" // PyMemberDef
Victor Stinner361dcdc2020-04-15 03:24:57 +02009#include "osdefs.h" // SEP
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +000010#ifdef HAVE_FCNTL_H
11#include <fcntl.h>
12#endif
Guido van Rossum3f5da241990-12-20 15:06:42 +000013
Nicholas Bastina7604bf2004-03-21 18:37:23 +000014#define OFF(x) offsetof(PyTracebackObject, x)
Guido van Rossum3f5da241990-12-20 15:06:42 +000015
Victor Stinner97f86b82015-04-01 18:38:01 +020016#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str))
Victor Stinner54f939b2012-07-30 13:08:58 +020017#define MAX_STRING_LENGTH 500
Victor Stinner024e37a2011-03-31 01:31:06 +020018#define MAX_FRAME_DEPTH 100
19#define MAX_NTHREADS 100
20
Victor Stinnerfe7c5b52011-04-05 01:48:03 +020021/* Function from Parser/tokenizer.c */
22extern char * PyTokenizer_FindEncodingFilename(int, PyObject *);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +000023
Victor Stinnerbd303c12013-11-07 23:07:29 +010024_Py_IDENTIFIER(TextIOWrapper);
25_Py_IDENTIFIER(close);
26_Py_IDENTIFIER(open);
27_Py_IDENTIFIER(path);
28
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -080029/*[clinic input]
30class TracebackType "PyTracebackObject *" "&PyTraceback_Type"
31[clinic start generated code]*/
32/*[clinic end generated code: output=da39a3ee5e6b4b0d input=928fa06c10151120]*/
33
34#include "clinic/traceback.c.h"
35
36static PyObject *
37tb_create_raw(PyTracebackObject *next, PyFrameObject *frame, int lasti,
38 int lineno)
39{
40 PyTracebackObject *tb;
41 if ((next != NULL && !PyTraceBack_Check(next)) ||
42 frame == NULL || !PyFrame_Check(frame)) {
43 PyErr_BadInternalCall();
44 return NULL;
45 }
46 tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
47 if (tb != NULL) {
48 Py_XINCREF(next);
49 tb->tb_next = next;
50 Py_XINCREF(frame);
51 tb->tb_frame = frame;
52 tb->tb_lasti = lasti;
53 tb->tb_lineno = lineno;
54 PyObject_GC_Track(tb);
55 }
56 return (PyObject *)tb;
57}
58
59/*[clinic input]
60@classmethod
61TracebackType.__new__ as tb_new
62
63 tb_next: object
64 tb_frame: object(type='PyFrameObject *', subclass_of='&PyFrame_Type')
65 tb_lasti: int
66 tb_lineno: int
67
68Create a new traceback object.
69[clinic start generated code]*/
70
71static PyObject *
72tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame,
73 int tb_lasti, int tb_lineno)
74/*[clinic end generated code: output=fa077debd72d861a input=01cbe8ec8783fca7]*/
75{
76 if (tb_next == Py_None) {
77 tb_next = NULL;
78 } else if (!PyTraceBack_Check(tb_next)) {
79 return PyErr_Format(PyExc_TypeError,
80 "expected traceback object or None, got '%s'",
81 Py_TYPE(tb_next)->tp_name);
82 }
83
84 return tb_create_raw((PyTracebackObject *)tb_next, tb_frame, tb_lasti,
85 tb_lineno);
86}
87
Collin Winter3eed7652007-08-14 17:53:54 +000088static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +053089tb_dir(PyTracebackObject *self, PyObject *Py_UNUSED(ignored))
Collin Winter3eed7652007-08-14 17:53:54 +000090{
91 return Py_BuildValue("[ssss]", "tb_frame", "tb_next",
92 "tb_lasti", "tb_lineno");
93}
94
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -080095static PyObject *
96tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_))
97{
98 PyObject* ret = (PyObject*)self->tb_next;
99 if (!ret) {
100 ret = Py_None;
101 }
102 Py_INCREF(ret);
103 return ret;
104}
105
106static int
107tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_))
108{
109 if (!new_next) {
110 PyErr_Format(PyExc_TypeError, "can't delete tb_next attribute");
111 return -1;
112 }
113
114 /* We accept None or a traceback object, and map None -> NULL (inverse of
115 tb_next_get) */
116 if (new_next == Py_None) {
117 new_next = NULL;
118 } else if (!PyTraceBack_Check(new_next)) {
119 PyErr_Format(PyExc_TypeError,
120 "expected traceback object, got '%s'",
121 Py_TYPE(new_next)->tp_name);
122 return -1;
123 }
124
125 /* Check for loops */
126 PyTracebackObject *cursor = (PyTracebackObject *)new_next;
127 while (cursor) {
128 if (cursor == self) {
129 PyErr_Format(PyExc_ValueError, "traceback loop detected");
130 return -1;
131 }
132 cursor = cursor->tb_next;
133 }
134
135 PyObject *old_next = (PyObject*)self->tb_next;
136 Py_XINCREF(new_next);
137 self->tb_next = (PyTracebackObject *)new_next;
138 Py_XDECREF(old_next);
139
140 return 0;
141}
142
143
Collin Winter3eed7652007-08-14 17:53:54 +0000144static PyMethodDef tb_methods[] = {
145 {"__dir__", (PyCFunction)tb_dir, METH_NOARGS},
146 {NULL, NULL, 0, NULL},
147};
148
Neal Norwitz8dfc4a92007-08-11 06:39:53 +0000149static PyMemberDef tb_memberlist[] = {
Steve Dower87655e22021-04-30 01:08:55 +0100150 {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|PY_AUDIT_READ},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 {"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
152 {"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
153 {NULL} /* Sentinel */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000154};
155
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -0800156static PyGetSetDef tb_getsetters[] = {
157 {"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL},
158 {NULL} /* Sentinel */
159};
160
Guido van Rossum3f5da241990-12-20 15:06:42 +0000161static void
Nicholas Bastina7604bf2004-03-21 18:37:23 +0000162tb_dealloc(PyTracebackObject *tb)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 PyObject_GC_UnTrack(tb);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200165 Py_TRASHCAN_BEGIN(tb, tb_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 Py_XDECREF(tb->tb_next);
167 Py_XDECREF(tb->tb_frame);
168 PyObject_GC_Del(tb);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200169 Py_TRASHCAN_END
Guido van Rossum3f5da241990-12-20 15:06:42 +0000170}
171
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +0000172static int
Nicholas Bastina7604bf2004-03-21 18:37:23 +0000173tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +0000174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 Py_VISIT(tb->tb_next);
176 Py_VISIT(tb->tb_frame);
177 return 0;
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +0000178}
179
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200180static int
Nicholas Bastina7604bf2004-03-21 18:37:23 +0000181tb_clear(PyTracebackObject *tb)
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +0000182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000183 Py_CLEAR(tb->tb_next);
184 Py_CLEAR(tb->tb_frame);
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200185 return 0;
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +0000186}
187
Tim Petersd7c36522001-10-22 19:34:09 +0000188PyTypeObject PyTraceBack_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 PyVarObject_HEAD_INIT(&PyType_Type, 0)
190 "traceback",
191 sizeof(PyTracebackObject),
192 0,
193 (destructor)tb_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200194 0, /*tp_vectorcall_offset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 0, /*tp_getattr*/
196 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200197 0, /*tp_as_async*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 0, /*tp_repr*/
199 0, /*tp_as_number*/
200 0, /*tp_as_sequence*/
201 0, /*tp_as_mapping*/
202 0, /* tp_hash */
203 0, /* tp_call */
204 0, /* tp_str */
205 PyObject_GenericGetAttr, /* tp_getattro */
206 0, /* tp_setattro */
207 0, /* tp_as_buffer */
208 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -0800209 tb_new__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 (traverseproc)tb_traverse, /* tp_traverse */
211 (inquiry)tb_clear, /* tp_clear */
212 0, /* tp_richcompare */
213 0, /* tp_weaklistoffset */
214 0, /* tp_iter */
215 0, /* tp_iternext */
216 tb_methods, /* tp_methods */
217 tb_memberlist, /* tp_members */
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -0800218 tb_getsetters, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000219 0, /* tp_base */
220 0, /* tp_dict */
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -0800221 0, /* tp_descr_get */
222 0, /* tp_descr_set */
223 0, /* tp_dictoffset */
224 0, /* tp_init */
225 0, /* tp_alloc */
226 tb_new, /* tp_new */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000227};
228
Victor Stinnerdf22c032019-05-23 01:00:58 +0200229
230PyObject*
231_PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
232{
233 assert(tb_next == NULL || PyTraceBack_Check(tb_next));
234 assert(frame != NULL);
235
Mark Shannonfcb55c02021-04-01 16:00:31 +0100236 return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti*2,
Victor Stinnerdf22c032019-05-23 01:00:58 +0200237 PyFrame_GetLineNumber(frame));
238}
239
240
Guido van Rossum3f5da241990-12-20 15:06:42 +0000241int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000242PyTraceBack_Here(PyFrameObject *frame)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000243{
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300244 PyObject *exc, *val, *tb, *newtb;
245 PyErr_Fetch(&exc, &val, &tb);
Victor Stinnerdf22c032019-05-23 01:00:58 +0200246 newtb = _PyTraceBack_FromFrame(tb, frame);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300247 if (newtb == NULL) {
248 _PyErr_ChainExceptions(exc, val, tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 return -1;
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300250 }
251 PyErr_Restore(exc, val, newtb);
252 Py_XDECREF(tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 return 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000254}
255
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200256/* Insert a frame into the traceback for (funcname, filename, lineno). */
Serhiy Storchaka73c95f12015-06-21 15:59:46 +0300257void _PyTraceback_Add(const char *funcname, const char *filename, int lineno)
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200258{
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300259 PyObject *globals;
260 PyCodeObject *code;
261 PyFrameObject *frame;
262 PyObject *exc, *val, *tb;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200263
264 /* Save and clear the current exception. Python functions must not be
265 called with an exception set. Calling Python functions happens when
266 the codec of the filesystem encoding is implemented in pure Python. */
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300267 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200268
269 globals = PyDict_New();
270 if (!globals)
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300271 goto error;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200272 code = PyCode_NewEmpty(filename, funcname, lineno);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300273 if (!code) {
274 Py_DECREF(globals);
275 goto error;
276 }
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200277 frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300278 Py_DECREF(globals);
279 Py_DECREF(code);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200280 if (!frame)
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300281 goto error;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200282 frame->f_lineno = lineno;
283
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300284 PyErr_Restore(exc, val, tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200285 PyTraceBack_Here(frame);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300286 Py_DECREF(frame);
287 return;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200288
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300289error:
290 _PyErr_ChainExceptions(exc, val, tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200291}
292
Victor Stinner0fe25a42010-06-17 23:08:50 +0000293static PyObject *
294_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000295{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000296 Py_ssize_t i;
297 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 PyObject *v;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000299 Py_ssize_t npath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 size_t taillen;
301 PyObject *syspath;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000302 PyObject *path;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 const char* tail;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000304 PyObject *filebytes;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000305 const char* filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 Py_ssize_t len;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000307 PyObject* result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000308
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000309 filebytes = PyUnicode_EncodeFSDefault(filename);
310 if (filebytes == NULL) {
Victor Stinner0fe25a42010-06-17 23:08:50 +0000311 PyErr_Clear();
312 return NULL;
313 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000314 filepath = PyBytes_AS_STRING(filebytes);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 /* Search tail of filename in sys.path before giving up */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000317 tail = strrchr(filepath, SEP);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 if (tail == NULL)
Victor Stinner0fe25a42010-06-17 23:08:50 +0000319 tail = filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 else
321 tail++;
322 taillen = strlen(tail);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000323
Victor Stinnerbd303c12013-11-07 23:07:29 +0100324 syspath = _PySys_GetObjectId(&PyId_path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 if (syspath == NULL || !PyList_Check(syspath))
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000326 goto error;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000327 npath = PyList_Size(syspath);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 for (i = 0; i < npath; i++) {
330 v = PyList_GetItem(syspath, i);
331 if (v == NULL) {
332 PyErr_Clear();
333 break;
334 }
335 if (!PyUnicode_Check(v))
336 continue;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000337 path = PyUnicode_EncodeFSDefault(v);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000338 if (path == NULL) {
339 PyErr_Clear();
340 continue;
341 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000342 len = PyBytes_GET_SIZE(path);
343 if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) {
344 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 continue; /* Too long */
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000346 }
347 strcpy(namebuf, PyBytes_AS_STRING(path));
348 Py_DECREF(path);
Victor Stinner98ea54c2014-08-15 23:30:40 +0200349 if (strlen(namebuf) != (size_t)len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 continue; /* v contains '\0' */
351 if (len > 0 && namebuf[len-1] != SEP)
352 namebuf[len++] = SEP;
353 strcpy(namebuf+len, tail);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000354
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200355 binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb");
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000356 if (binary != NULL) {
357 result = binary;
358 goto finally;
359 }
Victor Stinner0fe25a42010-06-17 23:08:50 +0000360 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000362 goto error;
363
364error:
365 result = NULL;
366finally:
367 Py_DECREF(filebytes);
368 return result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000369}
370
Christian Heimes33fe8092008-04-13 13:53:33 +0000371int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000372_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 int err = 0;
375 int fd;
376 int i;
377 char *found_encoding;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300378 const char *encoding;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000379 PyObject *io;
380 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 PyObject *fob = NULL;
382 PyObject *lineobj = NULL;
Antoine Pitroub86680e2010-10-14 21:15:17 +0000383 PyObject *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 char buf[MAXPATHLEN+1];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200385 int kind;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300386 const void *data;
Christian Heimes679db4a2008-01-18 09:56:22 +0000387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 /* open the file */
389 if (filename == NULL)
390 return 0;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000391
392 io = PyImport_ImportModuleNoBlock("io");
393 if (io == NULL)
394 return -1;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200395 binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");
Victor Stinner0fe25a42010-06-17 23:08:50 +0000396
397 if (binary == NULL) {
Victor Stinnerceceaa02013-07-16 00:32:14 +0200398 PyErr_Clear();
399
Victor Stinner0fe25a42010-06-17 23:08:50 +0000400 binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
401 if (binary == NULL) {
402 Py_DECREF(io);
Victor Stinnerceceaa02013-07-16 00:32:14 +0200403 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000404 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 /* use the right encoding to decode the file as unicode */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000408 fd = PyObject_AsFileDescriptor(binary);
Christian Heimes8c077bc2013-07-21 01:53:10 +0200409 if (fd < 0) {
410 Py_DECREF(io);
411 Py_DECREF(binary);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700412 return 0;
Christian Heimes8c077bc2013-07-21 01:53:10 +0200413 }
Victor Stinnerfe7c5b52011-04-05 01:48:03 +0200414 found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
Victor Stinner5272fa92013-12-19 13:39:32 +0100415 if (found_encoding == NULL)
416 PyErr_Clear();
Victor Stinner0fe25a42010-06-17 23:08:50 +0000417 encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
Christian Heimes1f347292013-07-21 02:12:35 +0200418 /* Reset position */
419 if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
420 Py_DECREF(io);
421 Py_DECREF(binary);
Victor Stinner00d7abd2020-12-01 09:56:42 +0100422 PyMem_Free(found_encoding);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700423 return 0;
Christian Heimes1f347292013-07-21 02:12:35 +0200424 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200425 fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000426 Py_DECREF(io);
Victor Stinner00d7abd2020-12-01 09:56:42 +0100427 PyMem_Free(found_encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 if (fob == NULL) {
430 PyErr_Clear();
Victor Stinner81f241a2015-03-25 02:25:25 +0100431
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200432 res = _PyObject_CallMethodIdNoArgs(binary, &PyId_close);
Victor Stinner81f241a2015-03-25 02:25:25 +0100433 Py_DECREF(binary);
434 if (res)
435 Py_DECREF(res);
436 else
437 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 return 0;
439 }
Victor Stinner81f241a2015-03-25 02:25:25 +0100440 Py_DECREF(binary);
Christian Heimes33fe8092008-04-13 13:53:33 +0000441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 /* get the line number lineno */
443 for (i = 0; i < lineno; i++) {
444 Py_XDECREF(lineobj);
445 lineobj = PyFile_GetLine(fob, -1);
446 if (!lineobj) {
Victor Stinner5e78f4d2014-10-30 10:17:27 +0100447 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 err = -1;
449 break;
450 }
451 }
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200452 res = _PyObject_CallMethodIdNoArgs(fob, &PyId_close);
Antoine Pitroub86680e2010-10-14 21:15:17 +0000453 if (res)
454 Py_DECREF(res);
455 else
456 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 Py_DECREF(fob);
458 if (!lineobj || !PyUnicode_Check(lineobj)) {
459 Py_XDECREF(lineobj);
460 return err;
461 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 /* remove the indentation of the line */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200464 kind = PyUnicode_KIND(lineobj);
465 data = PyUnicode_DATA(lineobj);
466 for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) {
467 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
468 if (ch != ' ' && ch != '\t' && ch != '\014')
469 break;
470 }
471 if (i) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 PyObject *truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200473 truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 if (truncated) {
475 Py_DECREF(lineobj);
476 lineobj = truncated;
477 } else {
478 PyErr_Clear();
479 }
480 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 /* Write some spaces before the line */
483 strcpy(buf, " ");
484 assert (strlen(buf) == 10);
485 while (indent > 0) {
Benjamin Peterson0f9b7d32013-07-21 13:29:37 -0700486 if (indent < 10)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 buf[indent] = '\0';
488 err = PyFile_WriteString(buf, f);
489 if (err != 0)
490 break;
491 indent -= 10;
492 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 /* finally display the line */
495 if (err == 0)
496 err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
497 Py_DECREF(lineobj);
498 if (err == 0)
499 err = PyFile_WriteString("\n", f);
500 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000501}
502
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000503static int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000504tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000505{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000506 int err;
507 PyObject *line;
Christian Heimes33fe8092008-04-13 13:53:33 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 if (filename == NULL || name == NULL)
510 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000511 line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
512 filename, lineno, name);
513 if (line == NULL)
514 return -1;
515 err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
516 Py_DECREF(line);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 if (err != 0)
518 return err;
Kristján Valur Jónssonc5963d32012-07-19 21:02:03 +0000519 /* ignore errors since we can't report them, can we? */
520 if (_Py_DisplaySourceLine(f, filename, lineno, 4))
521 PyErr_Clear();
522 return err;
Christian Heimes33fe8092008-04-13 13:53:33 +0000523}
524
Benjamin Petersond5458692018-09-10 08:43:10 -0700525static const int TB_RECURSIVE_CUTOFF = 3; // Also hardcoded in traceback.py.
526
Christian Heimes33fe8092008-04-13 13:53:33 +0000527static int
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200528tb_print_line_repeated(PyObject *f, long cnt)
529{
Benjamin Petersond5458692018-09-10 08:43:10 -0700530 cnt -= TB_RECURSIVE_CUTOFF;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200531 PyObject *line = PyUnicode_FromFormat(
Benjamin Petersond5458692018-09-10 08:43:10 -0700532 (cnt > 1)
533 ? " [Previous line repeated %ld more times]\n"
534 : " [Previous line repeated %ld more time]\n",
535 cnt);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200536 if (line == NULL) {
537 return -1;
538 }
Benjamin Petersond5458692018-09-10 08:43:10 -0700539 int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200540 Py_DECREF(line);
541 return err;
542}
543
544static int
Christian Heimes33fe8092008-04-13 13:53:33 +0000545tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
546{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 int err = 0;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200548 Py_ssize_t depth = 0;
Nick Coghland0034232016-08-15 13:11:34 +1000549 PyObject *last_file = NULL;
550 int last_line = -1;
551 PyObject *last_name = NULL;
552 long cnt = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000553 PyTracebackObject *tb1 = tb;
554 while (tb1 != NULL) {
555 depth++;
556 tb1 = tb1->tb_next;
557 }
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200558 while (tb != NULL && depth > limit) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 depth--;
560 tb = tb->tb_next;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 }
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200562 while (tb != NULL && err == 0) {
Victor Stinnera42ca742020-04-28 19:01:31 +0200563 PyCodeObject *code = PyFrame_GetCode(tb->tb_frame);
Benjamin Petersond5458692018-09-10 08:43:10 -0700564 if (last_file == NULL ||
Victor Stinnera42ca742020-04-28 19:01:31 +0200565 code->co_filename != last_file ||
Benjamin Petersond5458692018-09-10 08:43:10 -0700566 last_line == -1 || tb->tb_lineno != last_line ||
Victor Stinnera42ca742020-04-28 19:01:31 +0200567 last_name == NULL || code->co_name != last_name) {
Benjamin Petersond5458692018-09-10 08:43:10 -0700568 if (cnt > TB_RECURSIVE_CUTOFF) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200569 err = tb_print_line_repeated(f, cnt);
570 }
Victor Stinnera42ca742020-04-28 19:01:31 +0200571 last_file = code->co_filename;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200572 last_line = tb->tb_lineno;
Victor Stinnera42ca742020-04-28 19:01:31 +0200573 last_name = code->co_name;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200574 cnt = 0;
575 }
Benjamin Petersond5458692018-09-10 08:43:10 -0700576 cnt++;
577 if (err == 0 && cnt <= TB_RECURSIVE_CUTOFF) {
Victor Stinnera42ca742020-04-28 19:01:31 +0200578 err = tb_displayline(f, code->co_filename, tb->tb_lineno,
579 code->co_name);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200580 if (err == 0) {
581 err = PyErr_CheckSignals();
582 }
583 }
Victor Stinner8852ad42020-04-29 01:28:13 +0200584 Py_DECREF(code);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200585 tb = tb->tb_next;
586 }
Benjamin Petersond5458692018-09-10 08:43:10 -0700587 if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200588 err = tb_print_line_repeated(f, cnt);
Nick Coghland0034232016-08-15 13:11:34 +1000589 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000591}
592
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000593#define PyTraceBack_LIMIT 1000
594
Guido van Rossum3f5da241990-12-20 15:06:42 +0000595int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000596PyTraceBack_Print(PyObject *v, PyObject *f)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000597{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 int err;
599 PyObject *limitv;
600 long limit = PyTraceBack_LIMIT;
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 if (v == NULL)
603 return 0;
604 if (!PyTraceBack_Check(v)) {
605 PyErr_BadInternalCall();
606 return -1;
607 }
608 limitv = PySys_GetObject("tracebacklimit");
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200609 if (limitv && PyLong_Check(limitv)) {
610 int overflow;
611 limit = PyLong_AsLongAndOverflow(limitv, &overflow);
612 if (overflow > 0) {
613 limit = LONG_MAX;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 }
615 else if (limit <= 0) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200616 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 }
619 err = PyFile_WriteString("Traceback (most recent call last):\n", f);
620 if (!err)
621 err = tb_printinternal((PyTracebackObject *)v, f, limit);
622 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000623}
Victor Stinner024e37a2011-03-31 01:31:06 +0200624
Irit Katriel40125ab2020-12-17 12:33:07 +0000625/* Format an integer in range [0; 0xffffffff] to decimal and write it
626 into the file fd.
Victor Stinner024e37a2011-03-31 01:31:06 +0200627
628 This function is signal safe. */
629
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100630void
Victor Stinner66f77ca2021-01-19 23:35:27 +0100631_Py_DumpDecimal(int fd, size_t value)
Victor Stinner024e37a2011-03-31 01:31:06 +0200632{
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100633 /* maximum number of characters required for output of %lld or %p.
634 We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits,
635 plus 1 for the null byte. 53/22 is an upper bound for log10(256). */
Victor Stinner66f77ca2021-01-19 23:35:27 +0100636 char buffer[1 + (sizeof(size_t)*53-1) / 22 + 1];
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100637 char *ptr, *end;
Victor Stinner024e37a2011-03-31 01:31:06 +0200638
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100639 end = &buffer[Py_ARRAY_LENGTH(buffer) - 1];
640 ptr = end;
641 *ptr = '\0';
Victor Stinner024e37a2011-03-31 01:31:06 +0200642 do {
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100643 --ptr;
644 assert(ptr >= buffer);
645 *ptr = '0' + (value % 10);
Victor Stinner024e37a2011-03-31 01:31:06 +0200646 value /= 10;
Victor Stinner024e37a2011-03-31 01:31:06 +0200647 } while (value);
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100648
649 _Py_write_noraise(fd, ptr, end - ptr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200650}
651
Victor Stinner314b8782021-01-18 18:34:56 +0100652/* Format an integer as hexadecimal with width digits into fd file descriptor.
653 The function is signal safe. */
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100654void
Victor Stinner314b8782021-01-18 18:34:56 +0100655_Py_DumpHexadecimal(int fd, uintptr_t value, Py_ssize_t width)
Victor Stinner024e37a2011-03-31 01:31:06 +0200656{
Victor Stinner314b8782021-01-18 18:34:56 +0100657 char buffer[sizeof(uintptr_t) * 2 + 1], *ptr, *end;
Victor Stinner013024e2016-03-16 09:43:14 +0100658 const Py_ssize_t size = Py_ARRAY_LENGTH(buffer) - 1;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100659
660 if (width > size)
661 width = size;
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100662 /* it's ok if width is negative */
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100663
Victor Stinner013024e2016-03-16 09:43:14 +0100664 end = &buffer[size];
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100665 ptr = end;
666 *ptr = '\0';
Victor Stinner024e37a2011-03-31 01:31:06 +0200667 do {
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100668 --ptr;
669 assert(ptr >= buffer);
670 *ptr = Py_hexdigits[value & 15];
Victor Stinner024e37a2011-03-31 01:31:06 +0200671 value >>= 4;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100672 } while ((end - ptr) < width || value);
673
674 _Py_write_noraise(fd, ptr, end - ptr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200675}
676
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100677void
678_Py_DumpASCII(int fd, PyObject *text)
Victor Stinner024e37a2011-03-31 01:31:06 +0200679{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200680 PyASCIIObject *ascii = (PyASCIIObject *)text;
Victor Stinner024e37a2011-03-31 01:31:06 +0200681 Py_ssize_t i, size;
682 int truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200683 int kind;
Victor Stinnera336de72011-10-05 22:44:12 +0200684 void *data = NULL;
685 wchar_t *wstr = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200686 Py_UCS4 ch;
Victor Stinner024e37a2011-03-31 01:31:06 +0200687
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100688 if (!PyUnicode_Check(text))
689 return;
690
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200691 size = ascii->length;
692 kind = ascii->state.kind;
Victor Stinner1c3069a2016-03-23 16:10:07 +0100693 if (kind == PyUnicode_WCHAR_KIND) {
694 wstr = ((PyASCIIObject *)text)->wstr;
695 if (wstr == NULL)
696 return;
697 size = ((PyCompactUnicodeObject *)text)->wstr_length;
698 }
699 else if (ascii->state.compact) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200700 if (ascii->state.ascii)
701 data = ((PyASCIIObject*)text) + 1;
702 else
703 data = ((PyCompactUnicodeObject*)text) + 1;
704 }
Victor Stinner1c3069a2016-03-23 16:10:07 +0100705 else {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200706 data = ((PyUnicodeObject *)text)->data.any;
707 if (data == NULL)
708 return;
709 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200710
711 if (MAX_STRING_LENGTH < size) {
712 size = MAX_STRING_LENGTH;
713 truncated = 1;
714 }
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100715 else {
Victor Stinner024e37a2011-03-31 01:31:06 +0200716 truncated = 0;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100717 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200718
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200719 for (i=0; i < size; i++) {
Victor Stinnera336de72011-10-05 22:44:12 +0200720 if (kind != PyUnicode_WCHAR_KIND)
721 ch = PyUnicode_READ(kind, data, i);
722 else
723 ch = wstr[i];
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200724 if (' ' <= ch && ch <= 126) {
725 /* printable ASCII character */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200726 char c = (char)ch;
Victor Stinner97f86b82015-04-01 18:38:01 +0200727 _Py_write_noraise(fd, &c, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200728 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200729 else if (ch <= 0xff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200730 PUTS(fd, "\\x");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100731 _Py_DumpHexadecimal(fd, ch, 2);
Victor Stinner024e37a2011-03-31 01:31:06 +0200732 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200733 else if (ch <= 0xffff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200734 PUTS(fd, "\\u");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100735 _Py_DumpHexadecimal(fd, ch, 4);
Victor Stinner024e37a2011-03-31 01:31:06 +0200736 }
737 else {
738 PUTS(fd, "\\U");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100739 _Py_DumpHexadecimal(fd, ch, 8);
Victor Stinner024e37a2011-03-31 01:31:06 +0200740 }
741 }
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100742 if (truncated) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200743 PUTS(fd, "...");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100744 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200745}
746
747/* Write a frame into the file fd: "File "xxx", line xxx in xxx".
748
749 This function is signal safe. */
750
751static void
752dump_frame(int fd, PyFrameObject *frame)
753{
Victor Stinner8852ad42020-04-29 01:28:13 +0200754 PyCodeObject *code = PyFrame_GetCode(frame);
Victor Stinner024e37a2011-03-31 01:31:06 +0200755 PUTS(fd, " File ");
Victor Stinner8852ad42020-04-29 01:28:13 +0200756 if (code->co_filename != NULL
Victor Stinner024e37a2011-03-31 01:31:06 +0200757 && PyUnicode_Check(code->co_filename))
758 {
Victor Stinner97f86b82015-04-01 18:38:01 +0200759 PUTS(fd, "\"");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100760 _Py_DumpASCII(fd, code->co_filename);
Victor Stinner97f86b82015-04-01 18:38:01 +0200761 PUTS(fd, "\"");
Victor Stinner024e37a2011-03-31 01:31:06 +0200762 } else {
763 PUTS(fd, "???");
764 }
765
Mark Shannonfcb55c02021-04-01 16:00:31 +0100766 int lineno = PyFrame_GetLineNumber(frame);
Victor Stinner024e37a2011-03-31 01:31:06 +0200767 PUTS(fd, ", line ");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100768 if (lineno >= 0) {
Victor Stinner66f77ca2021-01-19 23:35:27 +0100769 _Py_DumpDecimal(fd, (size_t)lineno);
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100770 }
771 else {
772 PUTS(fd, "???");
773 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200774 PUTS(fd, " in ");
775
Victor Stinner8852ad42020-04-29 01:28:13 +0200776 if (code->co_name != NULL
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100777 && PyUnicode_Check(code->co_name)) {
778 _Py_DumpASCII(fd, code->co_name);
779 }
780 else {
Victor Stinner024e37a2011-03-31 01:31:06 +0200781 PUTS(fd, "???");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100782 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200783
Victor Stinner97f86b82015-04-01 18:38:01 +0200784 PUTS(fd, "\n");
Victor Stinner8852ad42020-04-29 01:28:13 +0200785 Py_DECREF(code);
Victor Stinner024e37a2011-03-31 01:31:06 +0200786}
787
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200788static void
Victor Stinner024e37a2011-03-31 01:31:06 +0200789dump_traceback(int fd, PyThreadState *tstate, int write_header)
790{
791 PyFrameObject *frame;
792 unsigned int depth;
793
Victor Stinner8fa3e172019-09-17 23:36:16 +0200794 if (write_header) {
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700795 PUTS(fd, "Stack (most recent call first):\n");
Victor Stinner8fa3e172019-09-17 23:36:16 +0200796 }
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200797
Victor Stinner70364772020-04-29 03:28:46 +0200798 frame = PyThreadState_GetFrame(tstate);
Victor Stinner8fa3e172019-09-17 23:36:16 +0200799 if (frame == NULL) {
800 PUTS(fd, "<no Python frame>\n");
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200801 return;
Victor Stinner8fa3e172019-09-17 23:36:16 +0200802 }
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200803
Victor Stinner024e37a2011-03-31 01:31:06 +0200804 depth = 0;
Victor Stinner70364772020-04-29 03:28:46 +0200805 while (1) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200806 if (MAX_FRAME_DEPTH <= depth) {
Victor Stinner70364772020-04-29 03:28:46 +0200807 Py_DECREF(frame);
Victor Stinner024e37a2011-03-31 01:31:06 +0200808 PUTS(fd, " ...\n");
809 break;
810 }
Victor Stinner70364772020-04-29 03:28:46 +0200811 if (!PyFrame_Check(frame)) {
812 Py_DECREF(frame);
Victor Stinner024e37a2011-03-31 01:31:06 +0200813 break;
Victor Stinner70364772020-04-29 03:28:46 +0200814 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200815 dump_frame(fd, frame);
Victor Stinner70364772020-04-29 03:28:46 +0200816 PyFrameObject *back = PyFrame_GetBack(frame);
817 Py_DECREF(frame);
818
819 if (back == NULL) {
820 break;
821 }
822 frame = back;
Victor Stinner024e37a2011-03-31 01:31:06 +0200823 depth++;
824 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200825}
826
Victor Stinner97f86b82015-04-01 18:38:01 +0200827/* Dump the traceback of a Python thread into fd. Use write() to write the
828 traceback and retry if write() is interrupted by a signal (failed with
829 EINTR), but don't call the Python signal handler.
830
831 The caller is responsible to call PyErr_CheckSignals() to call Python signal
832 handlers if signals were received. */
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200833void
Victor Stinner024e37a2011-03-31 01:31:06 +0200834_Py_DumpTraceback(int fd, PyThreadState *tstate)
835{
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200836 dump_traceback(fd, tstate, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200837}
838
839/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
840 is_current is true, "Thread 0xHHHH:\n" otherwise.
841
842 This function is signal safe. */
843
844static void
845write_thread_id(int fd, PyThreadState *tstate, int is_current)
846{
847 if (is_current)
848 PUTS(fd, "Current thread 0x");
849 else
850 PUTS(fd, "Thread 0x");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100851 _Py_DumpHexadecimal(fd,
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200852 tstate->thread_id,
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100853 sizeof(unsigned long) * 2);
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700854 PUTS(fd, " (most recent call first):\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200855}
856
Victor Stinner97f86b82015-04-01 18:38:01 +0200857/* Dump the traceback of all Python threads into fd. Use write() to write the
858 traceback and retry if write() is interrupted by a signal (failed with
859 EINTR), but don't call the Python signal handler.
860
861 The caller is responsible to call PyErr_CheckSignals() to call Python signal
862 handlers if signals were received. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200863const char*
864_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
Victor Stinner861d9ab2016-03-16 22:45:24 +0100865 PyThreadState *current_tstate)
Victor Stinner024e37a2011-03-31 01:31:06 +0200866{
867 PyThreadState *tstate;
868 unsigned int nthreads;
869
Victor Stinner861d9ab2016-03-16 22:45:24 +0100870 if (current_tstate == NULL) {
871 /* _Py_DumpTracebackThreads() is called from signal handlers by
872 faulthandler.
873
874 SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals
875 and are thus delivered to the thread that caused the fault. Get the
876 Python thread state of the current thread.
877
878 PyThreadState_Get() doesn't give the state of the thread that caused
Victor Stinner8fa3e172019-09-17 23:36:16 +0200879 the fault if the thread released the GIL, and so
880 _PyThreadState_GET() cannot be used. Read the thread specific
881 storage (TSS) instead: call PyGILState_GetThisThreadState(). */
Victor Stinner861d9ab2016-03-16 22:45:24 +0100882 current_tstate = PyGILState_GetThisThreadState();
883 }
884
885 if (interp == NULL) {
886 if (current_tstate == NULL) {
887 interp = _PyGILState_GetInterpreterStateUnsafe();
888 if (interp == NULL) {
889 /* We need the interpreter state to get Python threads */
890 return "unable to get the interpreter state";
891 }
892 }
893 else {
894 interp = current_tstate->interp;
895 }
896 }
Victor Stinner861d9ab2016-03-16 22:45:24 +0100897 assert(interp != NULL);
898
Victor Stinner024e37a2011-03-31 01:31:06 +0200899 /* Get the current interpreter from the current thread */
900 tstate = PyInterpreterState_ThreadHead(interp);
901 if (tstate == NULL)
902 return "unable to get the thread head state";
903
904 /* Dump the traceback of each thread */
905 tstate = PyInterpreterState_ThreadHead(interp);
906 nthreads = 0;
Steve Dower8fc89802015-04-12 00:26:27 -0400907 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner024e37a2011-03-31 01:31:06 +0200908 do
909 {
910 if (nthreads != 0)
Victor Stinner97f86b82015-04-01 18:38:01 +0200911 PUTS(fd, "\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200912 if (nthreads >= MAX_NTHREADS) {
913 PUTS(fd, "...\n");
914 break;
915 }
Victor Stinner861d9ab2016-03-16 22:45:24 +0100916 write_thread_id(fd, tstate, tstate == current_tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200917 dump_traceback(fd, tstate, 0);
918 tstate = PyThreadState_Next(tstate);
919 nthreads++;
920 } while (tstate != NULL);
Steve Dower8fc89802015-04-12 00:26:27 -0400921 _Py_END_SUPPRESS_IPH
Victor Stinner024e37a2011-03-31 01:31:06 +0200922
923 return NULL;
924}
925