blob: 18bd0bf7341ffa17ae3e8b91d8664bcac7a2f610 [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"
Victor Stinner621cebe2018-11-12 16:53:38 +01005#include "pycore_pystate.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +00006
Jeremy Hylton3e0055f2005-10-20 19:59:25 +00007#include "code.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +00008#include "frameobject.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +00009#include "structmember.h"
Guido van Rossum7169dbb1992-02-26 15:17:59 +000010#include "osdefs.h"
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[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY},
152 {"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*/
195 0, /*tp_print*/
196 0, /*tp_getattr*/
197 0, /*tp_setattr*/
198 0, /*tp_reserved*/
199 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
Guido van Rossum3f5da241990-12-20 15:06:42 +0000230int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000231PyTraceBack_Here(PyFrameObject *frame)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000232{
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300233 PyObject *exc, *val, *tb, *newtb;
234 PyErr_Fetch(&exc, &val, &tb);
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -0800235 newtb = tb_create_raw((PyTracebackObject *)tb, frame, frame->f_lasti,
236 PyFrame_GetLineNumber(frame));
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300237 if (newtb == NULL) {
238 _PyErr_ChainExceptions(exc, val, tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 return -1;
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300240 }
241 PyErr_Restore(exc, val, newtb);
242 Py_XDECREF(tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 return 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000244}
245
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200246/* Insert a frame into the traceback for (funcname, filename, lineno). */
Serhiy Storchaka73c95f12015-06-21 15:59:46 +0300247void _PyTraceback_Add(const char *funcname, const char *filename, int lineno)
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200248{
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300249 PyObject *globals;
250 PyCodeObject *code;
251 PyFrameObject *frame;
252 PyObject *exc, *val, *tb;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200253
254 /* Save and clear the current exception. Python functions must not be
255 called with an exception set. Calling Python functions happens when
256 the codec of the filesystem encoding is implemented in pure Python. */
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300257 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200258
259 globals = PyDict_New();
260 if (!globals)
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300261 goto error;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200262 code = PyCode_NewEmpty(filename, funcname, lineno);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300263 if (!code) {
264 Py_DECREF(globals);
265 goto error;
266 }
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200267 frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300268 Py_DECREF(globals);
269 Py_DECREF(code);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200270 if (!frame)
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300271 goto error;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200272 frame->f_lineno = lineno;
273
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300274 PyErr_Restore(exc, val, tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200275 PyTraceBack_Here(frame);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300276 Py_DECREF(frame);
277 return;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200278
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300279error:
280 _PyErr_ChainExceptions(exc, val, tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200281}
282
Victor Stinner0fe25a42010-06-17 23:08:50 +0000283static PyObject *
284_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000285{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000286 Py_ssize_t i;
287 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 PyObject *v;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000289 Py_ssize_t npath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 size_t taillen;
291 PyObject *syspath;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000292 PyObject *path;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 const char* tail;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000294 PyObject *filebytes;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000295 const char* filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 Py_ssize_t len;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000297 PyObject* result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000298
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000299 filebytes = PyUnicode_EncodeFSDefault(filename);
300 if (filebytes == NULL) {
Victor Stinner0fe25a42010-06-17 23:08:50 +0000301 PyErr_Clear();
302 return NULL;
303 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000304 filepath = PyBytes_AS_STRING(filebytes);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 /* Search tail of filename in sys.path before giving up */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000307 tail = strrchr(filepath, SEP);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 if (tail == NULL)
Victor Stinner0fe25a42010-06-17 23:08:50 +0000309 tail = filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 else
311 tail++;
312 taillen = strlen(tail);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000313
Victor Stinnerbd303c12013-11-07 23:07:29 +0100314 syspath = _PySys_GetObjectId(&PyId_path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 if (syspath == NULL || !PyList_Check(syspath))
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000316 goto error;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000317 npath = PyList_Size(syspath);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 for (i = 0; i < npath; i++) {
320 v = PyList_GetItem(syspath, i);
321 if (v == NULL) {
322 PyErr_Clear();
323 break;
324 }
325 if (!PyUnicode_Check(v))
326 continue;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000327 path = PyUnicode_EncodeFSDefault(v);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000328 if (path == NULL) {
329 PyErr_Clear();
330 continue;
331 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000332 len = PyBytes_GET_SIZE(path);
333 if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) {
334 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 continue; /* Too long */
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000336 }
337 strcpy(namebuf, PyBytes_AS_STRING(path));
338 Py_DECREF(path);
Victor Stinner98ea54c2014-08-15 23:30:40 +0200339 if (strlen(namebuf) != (size_t)len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 continue; /* v contains '\0' */
341 if (len > 0 && namebuf[len-1] != SEP)
342 namebuf[len++] = SEP;
343 strcpy(namebuf+len, tail);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000344
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200345 binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb");
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000346 if (binary != NULL) {
347 result = binary;
348 goto finally;
349 }
Victor Stinner0fe25a42010-06-17 23:08:50 +0000350 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000352 goto error;
353
354error:
355 result = NULL;
356finally:
357 Py_DECREF(filebytes);
358 return result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000359}
360
Christian Heimes33fe8092008-04-13 13:53:33 +0000361int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000362_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 int err = 0;
365 int fd;
366 int i;
367 char *found_encoding;
368 char *encoding;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000369 PyObject *io;
370 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 PyObject *fob = NULL;
372 PyObject *lineobj = NULL;
Antoine Pitroub86680e2010-10-14 21:15:17 +0000373 PyObject *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 char buf[MAXPATHLEN+1];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200375 int kind;
376 void *data;
Christian Heimes679db4a2008-01-18 09:56:22 +0000377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 /* open the file */
379 if (filename == NULL)
380 return 0;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000381
382 io = PyImport_ImportModuleNoBlock("io");
383 if (io == NULL)
384 return -1;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200385 binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");
Victor Stinner0fe25a42010-06-17 23:08:50 +0000386
387 if (binary == NULL) {
Victor Stinnerceceaa02013-07-16 00:32:14 +0200388 PyErr_Clear();
389
Victor Stinner0fe25a42010-06-17 23:08:50 +0000390 binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
391 if (binary == NULL) {
392 Py_DECREF(io);
Victor Stinnerceceaa02013-07-16 00:32:14 +0200393 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000394 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 /* use the right encoding to decode the file as unicode */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000398 fd = PyObject_AsFileDescriptor(binary);
Christian Heimes8c077bc2013-07-21 01:53:10 +0200399 if (fd < 0) {
400 Py_DECREF(io);
401 Py_DECREF(binary);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700402 return 0;
Christian Heimes8c077bc2013-07-21 01:53:10 +0200403 }
Victor Stinnerfe7c5b52011-04-05 01:48:03 +0200404 found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
Victor Stinner5272fa92013-12-19 13:39:32 +0100405 if (found_encoding == NULL)
406 PyErr_Clear();
Victor Stinner0fe25a42010-06-17 23:08:50 +0000407 encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
Christian Heimes1f347292013-07-21 02:12:35 +0200408 /* Reset position */
409 if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
410 Py_DECREF(io);
411 Py_DECREF(binary);
412 PyMem_FREE(found_encoding);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700413 return 0;
Christian Heimes1f347292013-07-21 02:12:35 +0200414 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200415 fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000416 Py_DECREF(io);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 PyMem_FREE(found_encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 if (fob == NULL) {
420 PyErr_Clear();
Victor Stinner81f241a2015-03-25 02:25:25 +0100421
Victor Stinner3466bde2016-09-05 18:16:01 -0700422 res = _PyObject_CallMethodId(binary, &PyId_close, NULL);
Victor Stinner81f241a2015-03-25 02:25:25 +0100423 Py_DECREF(binary);
424 if (res)
425 Py_DECREF(res);
426 else
427 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 return 0;
429 }
Victor Stinner81f241a2015-03-25 02:25:25 +0100430 Py_DECREF(binary);
Christian Heimes33fe8092008-04-13 13:53:33 +0000431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 /* get the line number lineno */
433 for (i = 0; i < lineno; i++) {
434 Py_XDECREF(lineobj);
435 lineobj = PyFile_GetLine(fob, -1);
436 if (!lineobj) {
Victor Stinner5e78f4d2014-10-30 10:17:27 +0100437 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 err = -1;
439 break;
440 }
441 }
Victor Stinner3466bde2016-09-05 18:16:01 -0700442 res = _PyObject_CallMethodId(fob, &PyId_close, NULL);
Antoine Pitroub86680e2010-10-14 21:15:17 +0000443 if (res)
444 Py_DECREF(res);
445 else
446 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 Py_DECREF(fob);
448 if (!lineobj || !PyUnicode_Check(lineobj)) {
449 Py_XDECREF(lineobj);
450 return err;
451 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 /* remove the indentation of the line */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200454 kind = PyUnicode_KIND(lineobj);
455 data = PyUnicode_DATA(lineobj);
456 for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) {
457 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
458 if (ch != ' ' && ch != '\t' && ch != '\014')
459 break;
460 }
461 if (i) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 PyObject *truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200463 truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 if (truncated) {
465 Py_DECREF(lineobj);
466 lineobj = truncated;
467 } else {
468 PyErr_Clear();
469 }
470 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 /* Write some spaces before the line */
473 strcpy(buf, " ");
474 assert (strlen(buf) == 10);
475 while (indent > 0) {
Benjamin Peterson0f9b7d32013-07-21 13:29:37 -0700476 if (indent < 10)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 buf[indent] = '\0';
478 err = PyFile_WriteString(buf, f);
479 if (err != 0)
480 break;
481 indent -= 10;
482 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 /* finally display the line */
485 if (err == 0)
486 err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
487 Py_DECREF(lineobj);
488 if (err == 0)
489 err = PyFile_WriteString("\n", f);
490 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000491}
492
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000493static int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000494tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000495{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000496 int err;
497 PyObject *line;
Christian Heimes33fe8092008-04-13 13:53:33 +0000498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 if (filename == NULL || name == NULL)
500 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000501 line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
502 filename, lineno, name);
503 if (line == NULL)
504 return -1;
505 err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
506 Py_DECREF(line);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 if (err != 0)
508 return err;
Kristján Valur Jónssonc5963d32012-07-19 21:02:03 +0000509 /* ignore errors since we can't report them, can we? */
510 if (_Py_DisplaySourceLine(f, filename, lineno, 4))
511 PyErr_Clear();
512 return err;
Christian Heimes33fe8092008-04-13 13:53:33 +0000513}
514
Benjamin Petersond5458692018-09-10 08:43:10 -0700515static const int TB_RECURSIVE_CUTOFF = 3; // Also hardcoded in traceback.py.
516
Christian Heimes33fe8092008-04-13 13:53:33 +0000517static int
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200518tb_print_line_repeated(PyObject *f, long cnt)
519{
Benjamin Petersond5458692018-09-10 08:43:10 -0700520 cnt -= TB_RECURSIVE_CUTOFF;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200521 PyObject *line = PyUnicode_FromFormat(
Benjamin Petersond5458692018-09-10 08:43:10 -0700522 (cnt > 1)
523 ? " [Previous line repeated %ld more times]\n"
524 : " [Previous line repeated %ld more time]\n",
525 cnt);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200526 if (line == NULL) {
527 return -1;
528 }
Benjamin Petersond5458692018-09-10 08:43:10 -0700529 int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200530 Py_DECREF(line);
531 return err;
532}
533
534static int
Christian Heimes33fe8092008-04-13 13:53:33 +0000535tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
536{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 int err = 0;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200538 Py_ssize_t depth = 0;
Nick Coghland0034232016-08-15 13:11:34 +1000539 PyObject *last_file = NULL;
540 int last_line = -1;
541 PyObject *last_name = NULL;
542 long cnt = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 PyTracebackObject *tb1 = tb;
544 while (tb1 != NULL) {
545 depth++;
546 tb1 = tb1->tb_next;
547 }
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200548 while (tb != NULL && depth > limit) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 depth--;
550 tb = tb->tb_next;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 }
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200552 while (tb != NULL && err == 0) {
Benjamin Petersond5458692018-09-10 08:43:10 -0700553 if (last_file == NULL ||
554 tb->tb_frame->f_code->co_filename != last_file ||
555 last_line == -1 || tb->tb_lineno != last_line ||
556 last_name == NULL || tb->tb_frame->f_code->co_name != last_name) {
557 if (cnt > TB_RECURSIVE_CUTOFF) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200558 err = tb_print_line_repeated(f, cnt);
559 }
560 last_file = tb->tb_frame->f_code->co_filename;
561 last_line = tb->tb_lineno;
562 last_name = tb->tb_frame->f_code->co_name;
563 cnt = 0;
564 }
Benjamin Petersond5458692018-09-10 08:43:10 -0700565 cnt++;
566 if (err == 0 && cnt <= TB_RECURSIVE_CUTOFF) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200567 err = tb_displayline(f,
568 tb->tb_frame->f_code->co_filename,
569 tb->tb_lineno,
570 tb->tb_frame->f_code->co_name);
571 if (err == 0) {
572 err = PyErr_CheckSignals();
573 }
574 }
575 tb = tb->tb_next;
576 }
Benjamin Petersond5458692018-09-10 08:43:10 -0700577 if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200578 err = tb_print_line_repeated(f, cnt);
Nick Coghland0034232016-08-15 13:11:34 +1000579 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000581}
582
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000583#define PyTraceBack_LIMIT 1000
584
Guido van Rossum3f5da241990-12-20 15:06:42 +0000585int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000586PyTraceBack_Print(PyObject *v, PyObject *f)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000587{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 int err;
589 PyObject *limitv;
590 long limit = PyTraceBack_LIMIT;
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 if (v == NULL)
593 return 0;
594 if (!PyTraceBack_Check(v)) {
595 PyErr_BadInternalCall();
596 return -1;
597 }
598 limitv = PySys_GetObject("tracebacklimit");
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200599 if (limitv && PyLong_Check(limitv)) {
600 int overflow;
601 limit = PyLong_AsLongAndOverflow(limitv, &overflow);
602 if (overflow > 0) {
603 limit = LONG_MAX;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 }
605 else if (limit <= 0) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200606 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 }
609 err = PyFile_WriteString("Traceback (most recent call last):\n", f);
610 if (!err)
611 err = tb_printinternal((PyTracebackObject *)v, f, limit);
612 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000613}
Victor Stinner024e37a2011-03-31 01:31:06 +0200614
615/* Reverse a string. For example, "abcd" becomes "dcba".
616
617 This function is signal safe. */
618
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100619void
620_Py_DumpDecimal(int fd, unsigned long value)
Victor Stinner024e37a2011-03-31 01:31:06 +0200621{
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100622 /* maximum number of characters required for output of %lld or %p.
623 We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits,
624 plus 1 for the null byte. 53/22 is an upper bound for log10(256). */
625 char buffer[1 + (sizeof(unsigned long)*53-1) / 22 + 1];
626 char *ptr, *end;
Victor Stinner024e37a2011-03-31 01:31:06 +0200627
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100628 end = &buffer[Py_ARRAY_LENGTH(buffer) - 1];
629 ptr = end;
630 *ptr = '\0';
Victor Stinner024e37a2011-03-31 01:31:06 +0200631 do {
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100632 --ptr;
633 assert(ptr >= buffer);
634 *ptr = '0' + (value % 10);
Victor Stinner024e37a2011-03-31 01:31:06 +0200635 value /= 10;
Victor Stinner024e37a2011-03-31 01:31:06 +0200636 } while (value);
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100637
638 _Py_write_noraise(fd, ptr, end - ptr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200639}
640
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700641/* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits,
Victor Stinner024e37a2011-03-31 01:31:06 +0200642 and write it into the file fd.
643
644 This function is signal safe. */
645
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100646void
647_Py_DumpHexadecimal(int fd, unsigned long value, Py_ssize_t width)
Victor Stinner024e37a2011-03-31 01:31:06 +0200648{
Victor Stinner013024e2016-03-16 09:43:14 +0100649 char buffer[sizeof(unsigned long) * 2 + 1], *ptr, *end;
650 const Py_ssize_t size = Py_ARRAY_LENGTH(buffer) - 1;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100651
652 if (width > size)
653 width = size;
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100654 /* it's ok if width is negative */
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100655
Victor Stinner013024e2016-03-16 09:43:14 +0100656 end = &buffer[size];
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100657 ptr = end;
658 *ptr = '\0';
Victor Stinner024e37a2011-03-31 01:31:06 +0200659 do {
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100660 --ptr;
661 assert(ptr >= buffer);
662 *ptr = Py_hexdigits[value & 15];
Victor Stinner024e37a2011-03-31 01:31:06 +0200663 value >>= 4;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100664 } while ((end - ptr) < width || value);
665
666 _Py_write_noraise(fd, ptr, end - ptr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200667}
668
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100669void
670_Py_DumpASCII(int fd, PyObject *text)
Victor Stinner024e37a2011-03-31 01:31:06 +0200671{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200672 PyASCIIObject *ascii = (PyASCIIObject *)text;
Victor Stinner024e37a2011-03-31 01:31:06 +0200673 Py_ssize_t i, size;
674 int truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200675 int kind;
Victor Stinnera336de72011-10-05 22:44:12 +0200676 void *data = NULL;
677 wchar_t *wstr = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200678 Py_UCS4 ch;
Victor Stinner024e37a2011-03-31 01:31:06 +0200679
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100680 if (!PyUnicode_Check(text))
681 return;
682
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200683 size = ascii->length;
684 kind = ascii->state.kind;
Victor Stinner1c3069a2016-03-23 16:10:07 +0100685 if (kind == PyUnicode_WCHAR_KIND) {
686 wstr = ((PyASCIIObject *)text)->wstr;
687 if (wstr == NULL)
688 return;
689 size = ((PyCompactUnicodeObject *)text)->wstr_length;
690 }
691 else if (ascii->state.compact) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200692 if (ascii->state.ascii)
693 data = ((PyASCIIObject*)text) + 1;
694 else
695 data = ((PyCompactUnicodeObject*)text) + 1;
696 }
Victor Stinner1c3069a2016-03-23 16:10:07 +0100697 else {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200698 data = ((PyUnicodeObject *)text)->data.any;
699 if (data == NULL)
700 return;
701 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200702
703 if (MAX_STRING_LENGTH < size) {
704 size = MAX_STRING_LENGTH;
705 truncated = 1;
706 }
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100707 else {
Victor Stinner024e37a2011-03-31 01:31:06 +0200708 truncated = 0;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100709 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200710
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200711 for (i=0; i < size; i++) {
Victor Stinnera336de72011-10-05 22:44:12 +0200712 if (kind != PyUnicode_WCHAR_KIND)
713 ch = PyUnicode_READ(kind, data, i);
714 else
715 ch = wstr[i];
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200716 if (' ' <= ch && ch <= 126) {
717 /* printable ASCII character */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200718 char c = (char)ch;
Victor Stinner97f86b82015-04-01 18:38:01 +0200719 _Py_write_noraise(fd, &c, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200720 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200721 else if (ch <= 0xff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200722 PUTS(fd, "\\x");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100723 _Py_DumpHexadecimal(fd, ch, 2);
Victor Stinner024e37a2011-03-31 01:31:06 +0200724 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200725 else if (ch <= 0xffff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200726 PUTS(fd, "\\u");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100727 _Py_DumpHexadecimal(fd, ch, 4);
Victor Stinner024e37a2011-03-31 01:31:06 +0200728 }
729 else {
730 PUTS(fd, "\\U");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100731 _Py_DumpHexadecimal(fd, ch, 8);
Victor Stinner024e37a2011-03-31 01:31:06 +0200732 }
733 }
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100734 if (truncated) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200735 PUTS(fd, "...");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100736 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200737}
738
739/* Write a frame into the file fd: "File "xxx", line xxx in xxx".
740
741 This function is signal safe. */
742
743static void
744dump_frame(int fd, PyFrameObject *frame)
745{
746 PyCodeObject *code;
747 int lineno;
748
749 code = frame->f_code;
750 PUTS(fd, " File ");
751 if (code != NULL && code->co_filename != NULL
752 && PyUnicode_Check(code->co_filename))
753 {
Victor Stinner97f86b82015-04-01 18:38:01 +0200754 PUTS(fd, "\"");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100755 _Py_DumpASCII(fd, code->co_filename);
Victor Stinner97f86b82015-04-01 18:38:01 +0200756 PUTS(fd, "\"");
Victor Stinner024e37a2011-03-31 01:31:06 +0200757 } else {
758 PUTS(fd, "???");
759 }
760
761 /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200762 lineno = PyCode_Addr2Line(code, frame->f_lasti);
Victor Stinner024e37a2011-03-31 01:31:06 +0200763 PUTS(fd, ", line ");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100764 if (lineno >= 0) {
765 _Py_DumpDecimal(fd, (unsigned long)lineno);
766 }
767 else {
768 PUTS(fd, "???");
769 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200770 PUTS(fd, " in ");
771
772 if (code != NULL && code->co_name != NULL
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100773 && PyUnicode_Check(code->co_name)) {
774 _Py_DumpASCII(fd, code->co_name);
775 }
776 else {
Victor Stinner024e37a2011-03-31 01:31:06 +0200777 PUTS(fd, "???");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100778 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200779
Victor Stinner97f86b82015-04-01 18:38:01 +0200780 PUTS(fd, "\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200781}
782
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200783static void
Victor Stinner024e37a2011-03-31 01:31:06 +0200784dump_traceback(int fd, PyThreadState *tstate, int write_header)
785{
786 PyFrameObject *frame;
787 unsigned int depth;
788
Victor Stinner024e37a2011-03-31 01:31:06 +0200789 if (write_header)
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700790 PUTS(fd, "Stack (most recent call first):\n");
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200791
792 frame = _PyThreadState_GetFrame(tstate);
793 if (frame == NULL)
794 return;
795
Victor Stinner024e37a2011-03-31 01:31:06 +0200796 depth = 0;
797 while (frame != NULL) {
798 if (MAX_FRAME_DEPTH <= depth) {
799 PUTS(fd, " ...\n");
800 break;
801 }
802 if (!PyFrame_Check(frame))
803 break;
804 dump_frame(fd, frame);
805 frame = frame->f_back;
806 depth++;
807 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200808}
809
Victor Stinner97f86b82015-04-01 18:38:01 +0200810/* Dump the traceback of a Python thread into fd. Use write() to write the
811 traceback and retry if write() is interrupted by a signal (failed with
812 EINTR), but don't call the Python signal handler.
813
814 The caller is responsible to call PyErr_CheckSignals() to call Python signal
815 handlers if signals were received. */
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200816void
Victor Stinner024e37a2011-03-31 01:31:06 +0200817_Py_DumpTraceback(int fd, PyThreadState *tstate)
818{
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200819 dump_traceback(fd, tstate, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200820}
821
822/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
823 is_current is true, "Thread 0xHHHH:\n" otherwise.
824
825 This function is signal safe. */
826
827static void
828write_thread_id(int fd, PyThreadState *tstate, int is_current)
829{
830 if (is_current)
831 PUTS(fd, "Current thread 0x");
832 else
833 PUTS(fd, "Thread 0x");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100834 _Py_DumpHexadecimal(fd,
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200835 tstate->thread_id,
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100836 sizeof(unsigned long) * 2);
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700837 PUTS(fd, " (most recent call first):\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200838}
839
Victor Stinner97f86b82015-04-01 18:38:01 +0200840/* Dump the traceback of all Python threads into fd. Use write() to write the
841 traceback and retry if write() is interrupted by a signal (failed with
842 EINTR), but don't call the Python signal handler.
843
844 The caller is responsible to call PyErr_CheckSignals() to call Python signal
845 handlers if signals were received. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200846const char*
847_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
Victor Stinner861d9ab2016-03-16 22:45:24 +0100848 PyThreadState *current_tstate)
Victor Stinner024e37a2011-03-31 01:31:06 +0200849{
850 PyThreadState *tstate;
851 unsigned int nthreads;
852
Victor Stinner861d9ab2016-03-16 22:45:24 +0100853 if (current_tstate == NULL) {
854 /* _Py_DumpTracebackThreads() is called from signal handlers by
855 faulthandler.
856
857 SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals
858 and are thus delivered to the thread that caused the fault. Get the
859 Python thread state of the current thread.
860
861 PyThreadState_Get() doesn't give the state of the thread that caused
862 the fault if the thread released the GIL, and so this function
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900863 cannot be used. Read the thread specific storage (TSS) instead: call
Victor Stinner861d9ab2016-03-16 22:45:24 +0100864 PyGILState_GetThisThreadState(). */
865 current_tstate = PyGILState_GetThisThreadState();
866 }
867
868 if (interp == NULL) {
869 if (current_tstate == NULL) {
870 interp = _PyGILState_GetInterpreterStateUnsafe();
871 if (interp == NULL) {
872 /* We need the interpreter state to get Python threads */
873 return "unable to get the interpreter state";
874 }
875 }
876 else {
877 interp = current_tstate->interp;
878 }
879 }
Victor Stinner861d9ab2016-03-16 22:45:24 +0100880 assert(interp != NULL);
881
Victor Stinner024e37a2011-03-31 01:31:06 +0200882 /* Get the current interpreter from the current thread */
883 tstate = PyInterpreterState_ThreadHead(interp);
884 if (tstate == NULL)
885 return "unable to get the thread head state";
886
887 /* Dump the traceback of each thread */
888 tstate = PyInterpreterState_ThreadHead(interp);
889 nthreads = 0;
Steve Dower8fc89802015-04-12 00:26:27 -0400890 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner024e37a2011-03-31 01:31:06 +0200891 do
892 {
893 if (nthreads != 0)
Victor Stinner97f86b82015-04-01 18:38:01 +0200894 PUTS(fd, "\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200895 if (nthreads >= MAX_NTHREADS) {
896 PUTS(fd, "...\n");
897 break;
898 }
Victor Stinner861d9ab2016-03-16 22:45:24 +0100899 write_thread_id(fd, tstate, tstate == current_tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200900 dump_traceback(fd, tstate, 0);
901 tstate = PyThreadState_Next(tstate);
902 nthreads++;
903 } while (tstate != NULL);
Steve Dower8fc89802015-04-12 00:26:27 -0400904 _Py_END_SUPPRESS_IPH
Victor Stinner024e37a2011-03-31 01:31:06 +0200905
906 return NULL;
907}
908