blob: 95bef64e734bb5e0b24ce94be0925db496e0475b [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"
Eric Snow2ebc5ce2017-09-07 23:51:28 -06005#include "internal/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 *
90tb_dir(PyTracebackObject *self)
91{
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);
166 Py_TRASHCAN_SAFE_BEGIN(tb)
167 Py_XDECREF(tb->tb_next);
168 Py_XDECREF(tb->tb_frame);
169 PyObject_GC_Del(tb);
170 Py_TRASHCAN_SAFE_END(tb)
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
181static void
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);
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*/
194 0, /*tp_print*/
195 0, /*tp_getattr*/
196 0, /*tp_setattr*/
197 0, /*tp_reserved*/
198 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
Guido van Rossum3f5da241990-12-20 15:06:42 +0000229int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000230PyTraceBack_Here(PyFrameObject *frame)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000231{
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300232 PyObject *exc, *val, *tb, *newtb;
233 PyErr_Fetch(&exc, &val, &tb);
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -0800234 newtb = tb_create_raw((PyTracebackObject *)tb, frame, frame->f_lasti,
235 PyFrame_GetLineNumber(frame));
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300236 if (newtb == NULL) {
237 _PyErr_ChainExceptions(exc, val, tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 return -1;
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300239 }
240 PyErr_Restore(exc, val, newtb);
241 Py_XDECREF(tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 return 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000243}
244
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200245/* Insert a frame into the traceback for (funcname, filename, lineno). */
Serhiy Storchaka73c95f12015-06-21 15:59:46 +0300246void _PyTraceback_Add(const char *funcname, const char *filename, int lineno)
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200247{
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300248 PyObject *globals;
249 PyCodeObject *code;
250 PyFrameObject *frame;
251 PyObject *exc, *val, *tb;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200252
253 /* Save and clear the current exception. Python functions must not be
254 called with an exception set. Calling Python functions happens when
255 the codec of the filesystem encoding is implemented in pure Python. */
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300256 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200257
258 globals = PyDict_New();
259 if (!globals)
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300260 goto error;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200261 code = PyCode_NewEmpty(filename, funcname, lineno);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300262 if (!code) {
263 Py_DECREF(globals);
264 goto error;
265 }
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200266 frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300267 Py_DECREF(globals);
268 Py_DECREF(code);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200269 if (!frame)
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300270 goto error;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200271 frame->f_lineno = lineno;
272
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300273 PyErr_Restore(exc, val, tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200274 PyTraceBack_Here(frame);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300275 Py_DECREF(frame);
276 return;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200277
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300278error:
279 _PyErr_ChainExceptions(exc, val, tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200280}
281
Victor Stinner0fe25a42010-06-17 23:08:50 +0000282static PyObject *
283_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000284{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000285 Py_ssize_t i;
286 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 PyObject *v;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000288 Py_ssize_t npath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 size_t taillen;
290 PyObject *syspath;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000291 PyObject *path;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 const char* tail;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000293 PyObject *filebytes;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000294 const char* filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 Py_ssize_t len;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000296 PyObject* result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000297
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000298 filebytes = PyUnicode_EncodeFSDefault(filename);
299 if (filebytes == NULL) {
Victor Stinner0fe25a42010-06-17 23:08:50 +0000300 PyErr_Clear();
301 return NULL;
302 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000303 filepath = PyBytes_AS_STRING(filebytes);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 /* Search tail of filename in sys.path before giving up */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000306 tail = strrchr(filepath, SEP);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 if (tail == NULL)
Victor Stinner0fe25a42010-06-17 23:08:50 +0000308 tail = filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 else
310 tail++;
311 taillen = strlen(tail);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000312
Victor Stinnerbd303c12013-11-07 23:07:29 +0100313 syspath = _PySys_GetObjectId(&PyId_path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 if (syspath == NULL || !PyList_Check(syspath))
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000315 goto error;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000316 npath = PyList_Size(syspath);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 for (i = 0; i < npath; i++) {
319 v = PyList_GetItem(syspath, i);
320 if (v == NULL) {
321 PyErr_Clear();
322 break;
323 }
324 if (!PyUnicode_Check(v))
325 continue;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000326 path = PyUnicode_EncodeFSDefault(v);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000327 if (path == NULL) {
328 PyErr_Clear();
329 continue;
330 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000331 len = PyBytes_GET_SIZE(path);
332 if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) {
333 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 continue; /* Too long */
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000335 }
336 strcpy(namebuf, PyBytes_AS_STRING(path));
337 Py_DECREF(path);
Victor Stinner98ea54c2014-08-15 23:30:40 +0200338 if (strlen(namebuf) != (size_t)len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 continue; /* v contains '\0' */
340 if (len > 0 && namebuf[len-1] != SEP)
341 namebuf[len++] = SEP;
342 strcpy(namebuf+len, tail);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000343
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200344 binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb");
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000345 if (binary != NULL) {
346 result = binary;
347 goto finally;
348 }
Victor Stinner0fe25a42010-06-17 23:08:50 +0000349 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000351 goto error;
352
353error:
354 result = NULL;
355finally:
356 Py_DECREF(filebytes);
357 return result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000358}
359
Christian Heimes33fe8092008-04-13 13:53:33 +0000360int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000361_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 int err = 0;
364 int fd;
365 int i;
366 char *found_encoding;
367 char *encoding;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000368 PyObject *io;
369 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 PyObject *fob = NULL;
371 PyObject *lineobj = NULL;
Antoine Pitroub86680e2010-10-14 21:15:17 +0000372 PyObject *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 char buf[MAXPATHLEN+1];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200374 int kind;
375 void *data;
Christian Heimes679db4a2008-01-18 09:56:22 +0000376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 /* open the file */
378 if (filename == NULL)
379 return 0;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000380
381 io = PyImport_ImportModuleNoBlock("io");
382 if (io == NULL)
383 return -1;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200384 binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");
Victor Stinner0fe25a42010-06-17 23:08:50 +0000385
386 if (binary == NULL) {
Victor Stinnerceceaa02013-07-16 00:32:14 +0200387 PyErr_Clear();
388
Victor Stinner0fe25a42010-06-17 23:08:50 +0000389 binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
390 if (binary == NULL) {
391 Py_DECREF(io);
Victor Stinnerceceaa02013-07-16 00:32:14 +0200392 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000393 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 /* use the right encoding to decode the file as unicode */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000397 fd = PyObject_AsFileDescriptor(binary);
Christian Heimes8c077bc2013-07-21 01:53:10 +0200398 if (fd < 0) {
399 Py_DECREF(io);
400 Py_DECREF(binary);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700401 return 0;
Christian Heimes8c077bc2013-07-21 01:53:10 +0200402 }
Victor Stinnerfe7c5b52011-04-05 01:48:03 +0200403 found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
Victor Stinner5272fa92013-12-19 13:39:32 +0100404 if (found_encoding == NULL)
405 PyErr_Clear();
Victor Stinner0fe25a42010-06-17 23:08:50 +0000406 encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
Christian Heimes1f347292013-07-21 02:12:35 +0200407 /* Reset position */
408 if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
409 Py_DECREF(io);
410 Py_DECREF(binary);
411 PyMem_FREE(found_encoding);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700412 return 0;
Christian Heimes1f347292013-07-21 02:12:35 +0200413 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200414 fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000415 Py_DECREF(io);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 PyMem_FREE(found_encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 if (fob == NULL) {
419 PyErr_Clear();
Victor Stinner81f241a2015-03-25 02:25:25 +0100420
Victor Stinner3466bde2016-09-05 18:16:01 -0700421 res = _PyObject_CallMethodId(binary, &PyId_close, NULL);
Victor Stinner81f241a2015-03-25 02:25:25 +0100422 Py_DECREF(binary);
423 if (res)
424 Py_DECREF(res);
425 else
426 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 return 0;
428 }
Victor Stinner81f241a2015-03-25 02:25:25 +0100429 Py_DECREF(binary);
Christian Heimes33fe8092008-04-13 13:53:33 +0000430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 /* get the line number lineno */
432 for (i = 0; i < lineno; i++) {
433 Py_XDECREF(lineobj);
434 lineobj = PyFile_GetLine(fob, -1);
435 if (!lineobj) {
Victor Stinner5e78f4d2014-10-30 10:17:27 +0100436 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 err = -1;
438 break;
439 }
440 }
Victor Stinner3466bde2016-09-05 18:16:01 -0700441 res = _PyObject_CallMethodId(fob, &PyId_close, NULL);
Antoine Pitroub86680e2010-10-14 21:15:17 +0000442 if (res)
443 Py_DECREF(res);
444 else
445 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 Py_DECREF(fob);
447 if (!lineobj || !PyUnicode_Check(lineobj)) {
448 Py_XDECREF(lineobj);
449 return err;
450 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 /* remove the indentation of the line */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200453 kind = PyUnicode_KIND(lineobj);
454 data = PyUnicode_DATA(lineobj);
455 for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) {
456 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
457 if (ch != ' ' && ch != '\t' && ch != '\014')
458 break;
459 }
460 if (i) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 PyObject *truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200462 truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 if (truncated) {
464 Py_DECREF(lineobj);
465 lineobj = truncated;
466 } else {
467 PyErr_Clear();
468 }
469 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 /* Write some spaces before the line */
472 strcpy(buf, " ");
473 assert (strlen(buf) == 10);
474 while (indent > 0) {
Benjamin Peterson0f9b7d32013-07-21 13:29:37 -0700475 if (indent < 10)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 buf[indent] = '\0';
477 err = PyFile_WriteString(buf, f);
478 if (err != 0)
479 break;
480 indent -= 10;
481 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 /* finally display the line */
484 if (err == 0)
485 err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
486 Py_DECREF(lineobj);
487 if (err == 0)
488 err = PyFile_WriteString("\n", f);
489 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000490}
491
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000492static int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000493tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000494{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000495 int err;
496 PyObject *line;
Christian Heimes33fe8092008-04-13 13:53:33 +0000497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 if (filename == NULL || name == NULL)
499 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000500 line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
501 filename, lineno, name);
502 if (line == NULL)
503 return -1;
504 err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
505 Py_DECREF(line);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 if (err != 0)
507 return err;
Kristján Valur Jónssonc5963d32012-07-19 21:02:03 +0000508 /* ignore errors since we can't report them, can we? */
509 if (_Py_DisplaySourceLine(f, filename, lineno, 4))
510 PyErr_Clear();
511 return err;
Christian Heimes33fe8092008-04-13 13:53:33 +0000512}
513
Miss Islington (bot)49020172018-09-10 09:00:08 -0700514static const int TB_RECURSIVE_CUTOFF = 3; // Also hardcoded in traceback.py.
515
Christian Heimes33fe8092008-04-13 13:53:33 +0000516static int
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200517tb_print_line_repeated(PyObject *f, long cnt)
518{
Miss Islington (bot)49020172018-09-10 09:00:08 -0700519 cnt -= TB_RECURSIVE_CUTOFF;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200520 PyObject *line = PyUnicode_FromFormat(
Miss Islington (bot)49020172018-09-10 09:00:08 -0700521 (cnt > 1)
522 ? " [Previous line repeated %ld more times]\n"
523 : " [Previous line repeated %ld more time]\n",
524 cnt);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200525 if (line == NULL) {
526 return -1;
527 }
Miss Islington (bot)49020172018-09-10 09:00:08 -0700528 int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200529 Py_DECREF(line);
530 return err;
531}
532
533static int
Christian Heimes33fe8092008-04-13 13:53:33 +0000534tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
535{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 int err = 0;
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200537 Py_ssize_t depth = 0;
Nick Coghland0034232016-08-15 13:11:34 +1000538 PyObject *last_file = NULL;
539 int last_line = -1;
540 PyObject *last_name = NULL;
541 long cnt = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 PyTracebackObject *tb1 = tb;
543 while (tb1 != NULL) {
544 depth++;
545 tb1 = tb1->tb_next;
546 }
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200547 while (tb != NULL && depth > limit) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 depth--;
549 tb = tb->tb_next;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 }
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200551 while (tb != NULL && err == 0) {
Miss Islington (bot)49020172018-09-10 09:00:08 -0700552 if (last_file == NULL ||
553 tb->tb_frame->f_code->co_filename != last_file ||
554 last_line == -1 || tb->tb_lineno != last_line ||
555 last_name == NULL || tb->tb_frame->f_code->co_name != last_name) {
556 if (cnt > TB_RECURSIVE_CUTOFF) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200557 err = tb_print_line_repeated(f, cnt);
558 }
559 last_file = tb->tb_frame->f_code->co_filename;
560 last_line = tb->tb_lineno;
561 last_name = tb->tb_frame->f_code->co_name;
562 cnt = 0;
563 }
Miss Islington (bot)49020172018-09-10 09:00:08 -0700564 cnt++;
565 if (err == 0 && cnt <= TB_RECURSIVE_CUTOFF) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200566 err = tb_displayline(f,
567 tb->tb_frame->f_code->co_filename,
568 tb->tb_lineno,
569 tb->tb_frame->f_code->co_name);
570 if (err == 0) {
571 err = PyErr_CheckSignals();
572 }
573 }
574 tb = tb->tb_next;
575 }
Miss Islington (bot)49020172018-09-10 09:00:08 -0700576 if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200577 err = tb_print_line_repeated(f, cnt);
Nick Coghland0034232016-08-15 13:11:34 +1000578 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000580}
581
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000582#define PyTraceBack_LIMIT 1000
583
Guido van Rossum3f5da241990-12-20 15:06:42 +0000584int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000585PyTraceBack_Print(PyObject *v, PyObject *f)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000586{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 int err;
588 PyObject *limitv;
589 long limit = PyTraceBack_LIMIT;
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 if (v == NULL)
592 return 0;
593 if (!PyTraceBack_Check(v)) {
594 PyErr_BadInternalCall();
595 return -1;
596 }
597 limitv = PySys_GetObject("tracebacklimit");
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200598 if (limitv && PyLong_Check(limitv)) {
599 int overflow;
600 limit = PyLong_AsLongAndOverflow(limitv, &overflow);
601 if (overflow > 0) {
602 limit = LONG_MAX;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 }
604 else if (limit <= 0) {
Serhiy Storchakaedad8ee2017-11-15 17:38:52 +0200605 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 }
608 err = PyFile_WriteString("Traceback (most recent call last):\n", f);
609 if (!err)
610 err = tb_printinternal((PyTracebackObject *)v, f, limit);
611 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000612}
Victor Stinner024e37a2011-03-31 01:31:06 +0200613
614/* Reverse a string. For example, "abcd" becomes "dcba".
615
616 This function is signal safe. */
617
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100618void
619_Py_DumpDecimal(int fd, unsigned long value)
Victor Stinner024e37a2011-03-31 01:31:06 +0200620{
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100621 /* maximum number of characters required for output of %lld or %p.
622 We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits,
623 plus 1 for the null byte. 53/22 is an upper bound for log10(256). */
624 char buffer[1 + (sizeof(unsigned long)*53-1) / 22 + 1];
625 char *ptr, *end;
Victor Stinner024e37a2011-03-31 01:31:06 +0200626
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100627 end = &buffer[Py_ARRAY_LENGTH(buffer) - 1];
628 ptr = end;
629 *ptr = '\0';
Victor Stinner024e37a2011-03-31 01:31:06 +0200630 do {
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100631 --ptr;
632 assert(ptr >= buffer);
633 *ptr = '0' + (value % 10);
Victor Stinner024e37a2011-03-31 01:31:06 +0200634 value /= 10;
Victor Stinner024e37a2011-03-31 01:31:06 +0200635 } while (value);
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100636
637 _Py_write_noraise(fd, ptr, end - ptr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200638}
639
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700640/* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits,
Victor Stinner024e37a2011-03-31 01:31:06 +0200641 and write it into the file fd.
642
643 This function is signal safe. */
644
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100645void
646_Py_DumpHexadecimal(int fd, unsigned long value, Py_ssize_t width)
Victor Stinner024e37a2011-03-31 01:31:06 +0200647{
Victor Stinner013024e2016-03-16 09:43:14 +0100648 char buffer[sizeof(unsigned long) * 2 + 1], *ptr, *end;
649 const Py_ssize_t size = Py_ARRAY_LENGTH(buffer) - 1;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100650
651 if (width > size)
652 width = size;
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100653 /* it's ok if width is negative */
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100654
Victor Stinner013024e2016-03-16 09:43:14 +0100655 end = &buffer[size];
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100656 ptr = end;
657 *ptr = '\0';
Victor Stinner024e37a2011-03-31 01:31:06 +0200658 do {
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100659 --ptr;
660 assert(ptr >= buffer);
661 *ptr = Py_hexdigits[value & 15];
Victor Stinner024e37a2011-03-31 01:31:06 +0200662 value >>= 4;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100663 } while ((end - ptr) < width || value);
664
665 _Py_write_noraise(fd, ptr, end - ptr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200666}
667
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100668void
669_Py_DumpASCII(int fd, PyObject *text)
Victor Stinner024e37a2011-03-31 01:31:06 +0200670{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200671 PyASCIIObject *ascii = (PyASCIIObject *)text;
Victor Stinner024e37a2011-03-31 01:31:06 +0200672 Py_ssize_t i, size;
673 int truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200674 int kind;
Victor Stinnera336de72011-10-05 22:44:12 +0200675 void *data = NULL;
676 wchar_t *wstr = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200677 Py_UCS4 ch;
Victor Stinner024e37a2011-03-31 01:31:06 +0200678
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100679 if (!PyUnicode_Check(text))
680 return;
681
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200682 size = ascii->length;
683 kind = ascii->state.kind;
Victor Stinner1c3069a2016-03-23 16:10:07 +0100684 if (kind == PyUnicode_WCHAR_KIND) {
685 wstr = ((PyASCIIObject *)text)->wstr;
686 if (wstr == NULL)
687 return;
688 size = ((PyCompactUnicodeObject *)text)->wstr_length;
689 }
690 else if (ascii->state.compact) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200691 if (ascii->state.ascii)
692 data = ((PyASCIIObject*)text) + 1;
693 else
694 data = ((PyCompactUnicodeObject*)text) + 1;
695 }
Victor Stinner1c3069a2016-03-23 16:10:07 +0100696 else {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200697 data = ((PyUnicodeObject *)text)->data.any;
698 if (data == NULL)
699 return;
700 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200701
702 if (MAX_STRING_LENGTH < size) {
703 size = MAX_STRING_LENGTH;
704 truncated = 1;
705 }
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100706 else {
Victor Stinner024e37a2011-03-31 01:31:06 +0200707 truncated = 0;
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100708 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200709
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200710 for (i=0; i < size; i++) {
Victor Stinnera336de72011-10-05 22:44:12 +0200711 if (kind != PyUnicode_WCHAR_KIND)
712 ch = PyUnicode_READ(kind, data, i);
713 else
714 ch = wstr[i];
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200715 if (' ' <= ch && ch <= 126) {
716 /* printable ASCII character */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200717 char c = (char)ch;
Victor Stinner97f86b82015-04-01 18:38:01 +0200718 _Py_write_noraise(fd, &c, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200719 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200720 else if (ch <= 0xff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200721 PUTS(fd, "\\x");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100722 _Py_DumpHexadecimal(fd, ch, 2);
Victor Stinner024e37a2011-03-31 01:31:06 +0200723 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200724 else if (ch <= 0xffff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200725 PUTS(fd, "\\u");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100726 _Py_DumpHexadecimal(fd, ch, 4);
Victor Stinner024e37a2011-03-31 01:31:06 +0200727 }
728 else {
729 PUTS(fd, "\\U");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100730 _Py_DumpHexadecimal(fd, ch, 8);
Victor Stinner024e37a2011-03-31 01:31:06 +0200731 }
732 }
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100733 if (truncated) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200734 PUTS(fd, "...");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100735 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200736}
737
738/* Write a frame into the file fd: "File "xxx", line xxx in xxx".
739
740 This function is signal safe. */
741
742static void
743dump_frame(int fd, PyFrameObject *frame)
744{
745 PyCodeObject *code;
746 int lineno;
747
748 code = frame->f_code;
749 PUTS(fd, " File ");
750 if (code != NULL && code->co_filename != NULL
751 && PyUnicode_Check(code->co_filename))
752 {
Victor Stinner97f86b82015-04-01 18:38:01 +0200753 PUTS(fd, "\"");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100754 _Py_DumpASCII(fd, code->co_filename);
Victor Stinner97f86b82015-04-01 18:38:01 +0200755 PUTS(fd, "\"");
Victor Stinner024e37a2011-03-31 01:31:06 +0200756 } else {
757 PUTS(fd, "???");
758 }
759
760 /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200761 lineno = PyCode_Addr2Line(code, frame->f_lasti);
Victor Stinner024e37a2011-03-31 01:31:06 +0200762 PUTS(fd, ", line ");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100763 if (lineno >= 0) {
764 _Py_DumpDecimal(fd, (unsigned long)lineno);
765 }
766 else {
767 PUTS(fd, "???");
768 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200769 PUTS(fd, " in ");
770
771 if (code != NULL && code->co_name != NULL
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100772 && PyUnicode_Check(code->co_name)) {
773 _Py_DumpASCII(fd, code->co_name);
774 }
775 else {
Victor Stinner024e37a2011-03-31 01:31:06 +0200776 PUTS(fd, "???");
Victor Stinner89e7cdc2016-03-15 21:49:37 +0100777 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200778
Victor Stinner97f86b82015-04-01 18:38:01 +0200779 PUTS(fd, "\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200780}
781
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200782static void
Victor Stinner024e37a2011-03-31 01:31:06 +0200783dump_traceback(int fd, PyThreadState *tstate, int write_header)
784{
785 PyFrameObject *frame;
786 unsigned int depth;
787
Victor Stinner024e37a2011-03-31 01:31:06 +0200788 if (write_header)
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700789 PUTS(fd, "Stack (most recent call first):\n");
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200790
791 frame = _PyThreadState_GetFrame(tstate);
792 if (frame == NULL)
793 return;
794
Victor Stinner024e37a2011-03-31 01:31:06 +0200795 depth = 0;
796 while (frame != NULL) {
797 if (MAX_FRAME_DEPTH <= depth) {
798 PUTS(fd, " ...\n");
799 break;
800 }
801 if (!PyFrame_Check(frame))
802 break;
803 dump_frame(fd, frame);
804 frame = frame->f_back;
805 depth++;
806 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200807}
808
Victor Stinner97f86b82015-04-01 18:38:01 +0200809/* Dump the traceback of a Python thread into fd. Use write() to write the
810 traceback and retry if write() is interrupted by a signal (failed with
811 EINTR), but don't call the Python signal handler.
812
813 The caller is responsible to call PyErr_CheckSignals() to call Python signal
814 handlers if signals were received. */
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200815void
Victor Stinner024e37a2011-03-31 01:31:06 +0200816_Py_DumpTraceback(int fd, PyThreadState *tstate)
817{
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200818 dump_traceback(fd, tstate, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200819}
820
821/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
822 is_current is true, "Thread 0xHHHH:\n" otherwise.
823
824 This function is signal safe. */
825
826static void
827write_thread_id(int fd, PyThreadState *tstate, int is_current)
828{
829 if (is_current)
830 PUTS(fd, "Current thread 0x");
831 else
832 PUTS(fd, "Thread 0x");
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100833 _Py_DumpHexadecimal(fd,
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200834 tstate->thread_id,
Victor Stinnerbd31b7c2016-03-23 10:32:26 +0100835 sizeof(unsigned long) * 2);
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700836 PUTS(fd, " (most recent call first):\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200837}
838
Victor Stinner97f86b82015-04-01 18:38:01 +0200839/* Dump the traceback of all Python threads into fd. Use write() to write the
840 traceback and retry if write() is interrupted by a signal (failed with
841 EINTR), but don't call the Python signal handler.
842
843 The caller is responsible to call PyErr_CheckSignals() to call Python signal
844 handlers if signals were received. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200845const char*
846_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
Victor Stinner861d9ab2016-03-16 22:45:24 +0100847 PyThreadState *current_tstate)
Victor Stinner024e37a2011-03-31 01:31:06 +0200848{
849 PyThreadState *tstate;
850 unsigned int nthreads;
851
Victor Stinner861d9ab2016-03-16 22:45:24 +0100852 if (current_tstate == NULL) {
853 /* _Py_DumpTracebackThreads() is called from signal handlers by
854 faulthandler.
855
856 SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals
857 and are thus delivered to the thread that caused the fault. Get the
858 Python thread state of the current thread.
859
860 PyThreadState_Get() doesn't give the state of the thread that caused
861 the fault if the thread released the GIL, and so this function
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900862 cannot be used. Read the thread specific storage (TSS) instead: call
Victor Stinner861d9ab2016-03-16 22:45:24 +0100863 PyGILState_GetThisThreadState(). */
864 current_tstate = PyGILState_GetThisThreadState();
865 }
866
867 if (interp == NULL) {
868 if (current_tstate == NULL) {
869 interp = _PyGILState_GetInterpreterStateUnsafe();
870 if (interp == NULL) {
871 /* We need the interpreter state to get Python threads */
872 return "unable to get the interpreter state";
873 }
874 }
875 else {
876 interp = current_tstate->interp;
877 }
878 }
Victor Stinner861d9ab2016-03-16 22:45:24 +0100879 assert(interp != NULL);
880
Victor Stinner024e37a2011-03-31 01:31:06 +0200881 /* Get the current interpreter from the current thread */
882 tstate = PyInterpreterState_ThreadHead(interp);
883 if (tstate == NULL)
884 return "unable to get the thread head state";
885
886 /* Dump the traceback of each thread */
887 tstate = PyInterpreterState_ThreadHead(interp);
888 nthreads = 0;
Steve Dower8fc89802015-04-12 00:26:27 -0400889 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner024e37a2011-03-31 01:31:06 +0200890 do
891 {
892 if (nthreads != 0)
Victor Stinner97f86b82015-04-01 18:38:01 +0200893 PUTS(fd, "\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200894 if (nthreads >= MAX_NTHREADS) {
895 PUTS(fd, "...\n");
896 break;
897 }
Victor Stinner861d9ab2016-03-16 22:45:24 +0100898 write_thread_id(fd, tstate, tstate == current_tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200899 dump_traceback(fd, tstate, 0);
900 tstate = PyThreadState_Next(tstate);
901 nthreads++;
902 } while (tstate != NULL);
Steve Dower8fc89802015-04-12 00:26:27 -0400903 _Py_END_SUPPRESS_IPH
Victor Stinner024e37a2011-03-31 01:31:06 +0200904
905 return NULL;
906}
907