blob: 9e7fe3b5c61c904593b8b3d082b587fbe34b24c4 [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"
Guido van Rossum3f5da241990-12-20 15:06:42 +00007#include "frameobject.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +00008#include "structmember.h"
Guido van Rossum7169dbb1992-02-26 15:17:59 +00009#include "osdefs.h"
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
Collin Winter3eed7652007-08-14 17:53:54 +000029static PyObject *
30tb_dir(PyTracebackObject *self)
31{
32 return Py_BuildValue("[ssss]", "tb_frame", "tb_next",
33 "tb_lasti", "tb_lineno");
34}
35
36static PyMethodDef tb_methods[] = {
37 {"__dir__", (PyCFunction)tb_dir, METH_NOARGS},
38 {NULL, NULL, 0, NULL},
39};
40
Neal Norwitz8dfc4a92007-08-11 06:39:53 +000041static PyMemberDef tb_memberlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000042 {"tb_next", T_OBJECT, OFF(tb_next), READONLY},
43 {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY},
44 {"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
45 {"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
46 {NULL} /* Sentinel */
Guido van Rossum3f5da241990-12-20 15:06:42 +000047};
48
Guido van Rossum3f5da241990-12-20 15:06:42 +000049static void
Nicholas Bastina7604bf2004-03-21 18:37:23 +000050tb_dealloc(PyTracebackObject *tb)
Guido van Rossum3f5da241990-12-20 15:06:42 +000051{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052 PyObject_GC_UnTrack(tb);
53 Py_TRASHCAN_SAFE_BEGIN(tb)
54 Py_XDECREF(tb->tb_next);
55 Py_XDECREF(tb->tb_frame);
56 PyObject_GC_Del(tb);
57 Py_TRASHCAN_SAFE_END(tb)
Guido van Rossum3f5da241990-12-20 15:06:42 +000058}
59
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +000060static int
Nicholas Bastina7604bf2004-03-21 18:37:23 +000061tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +000062{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 Py_VISIT(tb->tb_next);
64 Py_VISIT(tb->tb_frame);
65 return 0;
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +000066}
67
68static void
Nicholas Bastina7604bf2004-03-21 18:37:23 +000069tb_clear(PyTracebackObject *tb)
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +000070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 Py_CLEAR(tb->tb_next);
72 Py_CLEAR(tb->tb_frame);
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +000073}
74
Tim Petersd7c36522001-10-22 19:34:09 +000075PyTypeObject PyTraceBack_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076 PyVarObject_HEAD_INIT(&PyType_Type, 0)
77 "traceback",
78 sizeof(PyTracebackObject),
79 0,
80 (destructor)tb_dealloc, /*tp_dealloc*/
81 0, /*tp_print*/
82 0, /*tp_getattr*/
83 0, /*tp_setattr*/
84 0, /*tp_reserved*/
85 0, /*tp_repr*/
86 0, /*tp_as_number*/
87 0, /*tp_as_sequence*/
88 0, /*tp_as_mapping*/
89 0, /* tp_hash */
90 0, /* tp_call */
91 0, /* tp_str */
92 PyObject_GenericGetAttr, /* tp_getattro */
93 0, /* tp_setattro */
94 0, /* tp_as_buffer */
95 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
96 0, /* tp_doc */
97 (traverseproc)tb_traverse, /* tp_traverse */
98 (inquiry)tb_clear, /* tp_clear */
99 0, /* tp_richcompare */
100 0, /* tp_weaklistoffset */
101 0, /* tp_iter */
102 0, /* tp_iternext */
103 tb_methods, /* tp_methods */
104 tb_memberlist, /* tp_members */
105 0, /* tp_getset */
106 0, /* tp_base */
107 0, /* tp_dict */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000108};
109
Nicholas Bastina7604bf2004-03-21 18:37:23 +0000110static PyTracebackObject *
111newtracebackobject(PyTracebackObject *next, PyFrameObject *frame)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 PyTracebackObject *tb;
114 if ((next != NULL && !PyTraceBack_Check(next)) ||
115 frame == NULL || !PyFrame_Check(frame)) {
116 PyErr_BadInternalCall();
117 return NULL;
118 }
119 tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
120 if (tb != NULL) {
121 Py_XINCREF(next);
122 tb->tb_next = next;
123 Py_XINCREF(frame);
124 tb->tb_frame = frame;
125 tb->tb_lasti = frame->f_lasti;
126 tb->tb_lineno = PyFrame_GetLineNumber(frame);
127 PyObject_GC_Track(tb);
128 }
129 return tb;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000130}
131
Guido van Rossum3f5da241990-12-20 15:06:42 +0000132int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000133PyTraceBack_Here(PyFrameObject *frame)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000134{
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300135 PyObject *exc, *val, *tb, *newtb;
136 PyErr_Fetch(&exc, &val, &tb);
137 newtb = (PyObject *)newtracebackobject((PyTracebackObject *)tb, frame);
138 if (newtb == NULL) {
139 _PyErr_ChainExceptions(exc, val, tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 return -1;
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300141 }
142 PyErr_Restore(exc, val, newtb);
143 Py_XDECREF(tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 return 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000145}
146
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200147/* Insert a frame into the traceback for (funcname, filename, lineno). */
Serhiy Storchaka73c95f12015-06-21 15:59:46 +0300148void _PyTraceback_Add(const char *funcname, const char *filename, int lineno)
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200149{
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300150 PyObject *globals;
151 PyCodeObject *code;
152 PyFrameObject *frame;
153 PyObject *exc, *val, *tb;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200154
155 /* Save and clear the current exception. Python functions must not be
156 called with an exception set. Calling Python functions happens when
157 the codec of the filesystem encoding is implemented in pure Python. */
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300158 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200159
160 globals = PyDict_New();
161 if (!globals)
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300162 goto error;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200163 code = PyCode_NewEmpty(filename, funcname, lineno);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300164 if (!code) {
165 Py_DECREF(globals);
166 goto error;
167 }
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200168 frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300169 Py_DECREF(globals);
170 Py_DECREF(code);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200171 if (!frame)
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300172 goto error;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200173 frame->f_lineno = lineno;
174
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300175 PyErr_Restore(exc, val, tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200176 PyTraceBack_Here(frame);
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300177 Py_DECREF(frame);
178 return;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200179
Serhiy Storchaka04eb7772016-10-18 13:23:18 +0300180error:
181 _PyErr_ChainExceptions(exc, val, tb);
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200182}
183
Victor Stinner0fe25a42010-06-17 23:08:50 +0000184static PyObject *
185_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000186{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000187 Py_ssize_t i;
188 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 PyObject *v;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000190 Py_ssize_t npath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 size_t taillen;
192 PyObject *syspath;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000193 PyObject *path;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 const char* tail;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000195 PyObject *filebytes;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000196 const char* filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 Py_ssize_t len;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000198 PyObject* result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000199
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000200 filebytes = PyUnicode_EncodeFSDefault(filename);
201 if (filebytes == NULL) {
Victor Stinner0fe25a42010-06-17 23:08:50 +0000202 PyErr_Clear();
203 return NULL;
204 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000205 filepath = PyBytes_AS_STRING(filebytes);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 /* Search tail of filename in sys.path before giving up */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000208 tail = strrchr(filepath, SEP);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 if (tail == NULL)
Victor Stinner0fe25a42010-06-17 23:08:50 +0000210 tail = filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 else
212 tail++;
213 taillen = strlen(tail);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000214
Victor Stinnerbd303c12013-11-07 23:07:29 +0100215 syspath = _PySys_GetObjectId(&PyId_path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 if (syspath == NULL || !PyList_Check(syspath))
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000217 goto error;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000218 npath = PyList_Size(syspath);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 for (i = 0; i < npath; i++) {
221 v = PyList_GetItem(syspath, i);
222 if (v == NULL) {
223 PyErr_Clear();
224 break;
225 }
226 if (!PyUnicode_Check(v))
227 continue;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000228 path = PyUnicode_EncodeFSDefault(v);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000229 if (path == NULL) {
230 PyErr_Clear();
231 continue;
232 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000233 len = PyBytes_GET_SIZE(path);
234 if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) {
235 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000236 continue; /* Too long */
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000237 }
238 strcpy(namebuf, PyBytes_AS_STRING(path));
239 Py_DECREF(path);
Victor Stinner98ea54c2014-08-15 23:30:40 +0200240 if (strlen(namebuf) != (size_t)len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 continue; /* v contains '\0' */
242 if (len > 0 && namebuf[len-1] != SEP)
243 namebuf[len++] = SEP;
244 strcpy(namebuf+len, tail);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000245
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200246 binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb");
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000247 if (binary != NULL) {
248 result = binary;
249 goto finally;
250 }
Victor Stinner0fe25a42010-06-17 23:08:50 +0000251 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000253 goto error;
254
255error:
256 result = NULL;
257finally:
258 Py_DECREF(filebytes);
259 return result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000260}
261
Christian Heimes33fe8092008-04-13 13:53:33 +0000262int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000263_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 int err = 0;
266 int fd;
267 int i;
268 char *found_encoding;
269 char *encoding;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000270 PyObject *io;
271 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 PyObject *fob = NULL;
273 PyObject *lineobj = NULL;
Antoine Pitroub86680e2010-10-14 21:15:17 +0000274 PyObject *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 char buf[MAXPATHLEN+1];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200276 int kind;
277 void *data;
Christian Heimes679db4a2008-01-18 09:56:22 +0000278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 /* open the file */
280 if (filename == NULL)
281 return 0;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000282
283 io = PyImport_ImportModuleNoBlock("io");
284 if (io == NULL)
285 return -1;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200286 binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");
Victor Stinner0fe25a42010-06-17 23:08:50 +0000287
288 if (binary == NULL) {
Victor Stinnerceceaa02013-07-16 00:32:14 +0200289 PyErr_Clear();
290
Victor Stinner0fe25a42010-06-17 23:08:50 +0000291 binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
292 if (binary == NULL) {
293 Py_DECREF(io);
Victor Stinnerceceaa02013-07-16 00:32:14 +0200294 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000295 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 /* use the right encoding to decode the file as unicode */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000299 fd = PyObject_AsFileDescriptor(binary);
Christian Heimes8c077bc2013-07-21 01:53:10 +0200300 if (fd < 0) {
301 Py_DECREF(io);
302 Py_DECREF(binary);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700303 return 0;
Christian Heimes8c077bc2013-07-21 01:53:10 +0200304 }
Victor Stinnerfe7c5b52011-04-05 01:48:03 +0200305 found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
Victor Stinner5272fa92013-12-19 13:39:32 +0100306 if (found_encoding == NULL)
307 PyErr_Clear();
Victor Stinner0fe25a42010-06-17 23:08:50 +0000308 encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
Christian Heimes1f347292013-07-21 02:12:35 +0200309 /* Reset position */
310 if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
311 Py_DECREF(io);
312 Py_DECREF(binary);
313 PyMem_FREE(found_encoding);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700314 return 0;
Christian Heimes1f347292013-07-21 02:12:35 +0200315 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200316 fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000317 Py_DECREF(io);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 PyMem_FREE(found_encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 if (fob == NULL) {
321 PyErr_Clear();
Victor Stinner81f241a2015-03-25 02:25:25 +0100322
323 res = _PyObject_CallMethodId(binary, &PyId_close, "");
324 Py_DECREF(binary);
325 if (res)
326 Py_DECREF(res);
327 else
328 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 return 0;
330 }
Victor Stinner81f241a2015-03-25 02:25:25 +0100331 Py_DECREF(binary);
Christian Heimes33fe8092008-04-13 13:53:33 +0000332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000333 /* get the line number lineno */
334 for (i = 0; i < lineno; i++) {
335 Py_XDECREF(lineobj);
336 lineobj = PyFile_GetLine(fob, -1);
337 if (!lineobj) {
Victor Stinner5e78f4d2014-10-30 10:17:27 +0100338 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 err = -1;
340 break;
341 }
342 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200343 res = _PyObject_CallMethodId(fob, &PyId_close, "");
Antoine Pitroub86680e2010-10-14 21:15:17 +0000344 if (res)
345 Py_DECREF(res);
346 else
347 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 Py_DECREF(fob);
349 if (!lineobj || !PyUnicode_Check(lineobj)) {
350 Py_XDECREF(lineobj);
351 return err;
352 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 /* remove the indentation of the line */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200355 kind = PyUnicode_KIND(lineobj);
356 data = PyUnicode_DATA(lineobj);
357 for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) {
358 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
359 if (ch != ' ' && ch != '\t' && ch != '\014')
360 break;
361 }
362 if (i) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 PyObject *truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200364 truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 if (truncated) {
366 Py_DECREF(lineobj);
367 lineobj = truncated;
368 } else {
369 PyErr_Clear();
370 }
371 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 /* Write some spaces before the line */
374 strcpy(buf, " ");
375 assert (strlen(buf) == 10);
376 while (indent > 0) {
Benjamin Peterson0f9b7d32013-07-21 13:29:37 -0700377 if (indent < 10)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 buf[indent] = '\0';
379 err = PyFile_WriteString(buf, f);
380 if (err != 0)
381 break;
382 indent -= 10;
383 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 /* finally display the line */
386 if (err == 0)
387 err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
388 Py_DECREF(lineobj);
389 if (err == 0)
390 err = PyFile_WriteString("\n", f);
391 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000392}
393
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000394static int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000395tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000396{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000397 int err;
398 PyObject *line;
Christian Heimes33fe8092008-04-13 13:53:33 +0000399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 if (filename == NULL || name == NULL)
401 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000402 line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
403 filename, lineno, name);
404 if (line == NULL)
405 return -1;
406 err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
407 Py_DECREF(line);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 if (err != 0)
409 return err;
Kristján Valur Jónssonc5963d32012-07-19 21:02:03 +0000410 /* ignore errors since we can't report them, can we? */
411 if (_Py_DisplaySourceLine(f, filename, lineno, 4))
412 PyErr_Clear();
413 return err;
Christian Heimes33fe8092008-04-13 13:53:33 +0000414}
415
416static int
417tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 int err = 0;
420 long depth = 0;
421 PyTracebackObject *tb1 = tb;
422 while (tb1 != NULL) {
423 depth++;
424 tb1 = tb1->tb_next;
425 }
426 while (tb != NULL && err == 0) {
427 if (depth <= limit) {
428 err = tb_displayline(f,
Victor Stinner0fe25a42010-06-17 23:08:50 +0000429 tb->tb_frame->f_code->co_filename,
430 tb->tb_lineno,
431 tb->tb_frame->f_code->co_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 }
433 depth--;
434 tb = tb->tb_next;
435 if (err == 0)
436 err = PyErr_CheckSignals();
437 }
438 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000439}
440
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000441#define PyTraceBack_LIMIT 1000
442
Guido van Rossum3f5da241990-12-20 15:06:42 +0000443int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000444PyTraceBack_Print(PyObject *v, PyObject *f)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 int err;
447 PyObject *limitv;
448 long limit = PyTraceBack_LIMIT;
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 if (v == NULL)
451 return 0;
452 if (!PyTraceBack_Check(v)) {
453 PyErr_BadInternalCall();
454 return -1;
455 }
456 limitv = PySys_GetObject("tracebacklimit");
457 if (limitv) {
458 PyObject *exc_type, *exc_value, *exc_tb;
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
461 limit = PyLong_AsLong(limitv);
462 if (limit == -1 && PyErr_Occurred()) {
463 if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
464 limit = PyTraceBack_LIMIT;
465 }
466 else {
467 Py_XDECREF(exc_type);
468 Py_XDECREF(exc_value);
469 Py_XDECREF(exc_tb);
470 return 0;
471 }
472 }
473 else if (limit <= 0) {
474 limit = PyTraceBack_LIMIT;
475 }
476 PyErr_Restore(exc_type, exc_value, exc_tb);
477 }
478 err = PyFile_WriteString("Traceback (most recent call last):\n", f);
479 if (!err)
480 err = tb_printinternal((PyTracebackObject *)v, f, limit);
481 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000482}
Victor Stinner024e37a2011-03-31 01:31:06 +0200483
484/* Reverse a string. For example, "abcd" becomes "dcba".
485
486 This function is signal safe. */
487
488static void
489reverse_string(char *text, const size_t len)
490{
491 char tmp;
492 size_t i, j;
493 if (len == 0)
494 return;
495 for (i=0, j=len-1; i < j; i++, j--) {
496 tmp = text[i];
497 text[i] = text[j];
498 text[j] = tmp;
499 }
500}
501
502/* Format an integer in range [0; 999999] to decimal,
503 and write it into the file fd.
504
505 This function is signal safe. */
506
507static void
508dump_decimal(int fd, int value)
509{
510 char buffer[7];
511 int len;
512 if (value < 0 || 999999 < value)
513 return;
514 len = 0;
515 do {
516 buffer[len] = '0' + (value % 10);
517 value /= 10;
518 len++;
519 } while (value);
520 reverse_string(buffer, len);
Victor Stinner97f86b82015-04-01 18:38:01 +0200521 _Py_write_noraise(fd, buffer, len);
Victor Stinner024e37a2011-03-31 01:31:06 +0200522}
523
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700524/* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits,
Victor Stinner024e37a2011-03-31 01:31:06 +0200525 and write it into the file fd.
526
527 This function is signal safe. */
528
529static void
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700530dump_hexadecimal(int fd, unsigned long value, int width)
Victor Stinner024e37a2011-03-31 01:31:06 +0200531{
Victor Stinner024e37a2011-03-31 01:31:06 +0200532 int len;
533 char buffer[sizeof(unsigned long) * 2 + 1];
534 len = 0;
535 do {
Victor Stinnerf5cff562011-10-14 02:13:11 +0200536 buffer[len] = Py_hexdigits[value & 15];
Victor Stinner024e37a2011-03-31 01:31:06 +0200537 value >>= 4;
538 len++;
539 } while (len < width || value);
540 reverse_string(buffer, len);
Victor Stinner97f86b82015-04-01 18:38:01 +0200541 _Py_write_noraise(fd, buffer, len);
Victor Stinner024e37a2011-03-31 01:31:06 +0200542}
543
544/* Write an unicode object into the file fd using ascii+backslashreplace.
545
546 This function is signal safe. */
547
548static void
549dump_ascii(int fd, PyObject *text)
550{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200551 PyASCIIObject *ascii = (PyASCIIObject *)text;
Victor Stinner024e37a2011-03-31 01:31:06 +0200552 Py_ssize_t i, size;
553 int truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200554 int kind;
Victor Stinnera336de72011-10-05 22:44:12 +0200555 void *data = NULL;
556 wchar_t *wstr = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200557 Py_UCS4 ch;
Victor Stinner024e37a2011-03-31 01:31:06 +0200558
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200559 size = ascii->length;
560 kind = ascii->state.kind;
561 if (ascii->state.compact) {
562 if (ascii->state.ascii)
563 data = ((PyASCIIObject*)text) + 1;
564 else
565 data = ((PyCompactUnicodeObject*)text) + 1;
566 }
Victor Stinnera336de72011-10-05 22:44:12 +0200567 else if (kind != PyUnicode_WCHAR_KIND) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200568 data = ((PyUnicodeObject *)text)->data.any;
569 if (data == NULL)
570 return;
571 }
Victor Stinnera336de72011-10-05 22:44:12 +0200572 else {
573 wstr = ((PyASCIIObject *)text)->wstr;
574 if (wstr == NULL)
575 return;
576 size = ((PyCompactUnicodeObject *)text)->wstr_length;
577 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200578
579 if (MAX_STRING_LENGTH < size) {
580 size = MAX_STRING_LENGTH;
581 truncated = 1;
582 }
583 else
584 truncated = 0;
585
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200586 for (i=0; i < size; i++) {
Victor Stinnera336de72011-10-05 22:44:12 +0200587 if (kind != PyUnicode_WCHAR_KIND)
588 ch = PyUnicode_READ(kind, data, i);
589 else
590 ch = wstr[i];
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200591 if (' ' <= ch && ch <= 126) {
592 /* printable ASCII character */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200593 char c = (char)ch;
Victor Stinner97f86b82015-04-01 18:38:01 +0200594 _Py_write_noraise(fd, &c, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200595 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200596 else if (ch <= 0xff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200597 PUTS(fd, "\\x");
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700598 dump_hexadecimal(fd, ch, 2);
Victor Stinner024e37a2011-03-31 01:31:06 +0200599 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200600 else if (ch <= 0xffff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200601 PUTS(fd, "\\u");
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700602 dump_hexadecimal(fd, ch, 4);
Victor Stinner024e37a2011-03-31 01:31:06 +0200603 }
604 else {
605 PUTS(fd, "\\U");
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700606 dump_hexadecimal(fd, ch, 8);
Victor Stinner024e37a2011-03-31 01:31:06 +0200607 }
608 }
609 if (truncated)
610 PUTS(fd, "...");
611}
612
613/* Write a frame into the file fd: "File "xxx", line xxx in xxx".
614
615 This function is signal safe. */
616
617static void
618dump_frame(int fd, PyFrameObject *frame)
619{
620 PyCodeObject *code;
621 int lineno;
622
623 code = frame->f_code;
624 PUTS(fd, " File ");
625 if (code != NULL && code->co_filename != NULL
626 && PyUnicode_Check(code->co_filename))
627 {
Victor Stinner97f86b82015-04-01 18:38:01 +0200628 PUTS(fd, "\"");
Victor Stinner024e37a2011-03-31 01:31:06 +0200629 dump_ascii(fd, code->co_filename);
Victor Stinner97f86b82015-04-01 18:38:01 +0200630 PUTS(fd, "\"");
Victor Stinner024e37a2011-03-31 01:31:06 +0200631 } else {
632 PUTS(fd, "???");
633 }
634
635 /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200636 lineno = PyCode_Addr2Line(code, frame->f_lasti);
Victor Stinner024e37a2011-03-31 01:31:06 +0200637 PUTS(fd, ", line ");
638 dump_decimal(fd, lineno);
639 PUTS(fd, " in ");
640
641 if (code != NULL && code->co_name != NULL
642 && PyUnicode_Check(code->co_name))
643 dump_ascii(fd, code->co_name);
644 else
645 PUTS(fd, "???");
646
Victor Stinner97f86b82015-04-01 18:38:01 +0200647 PUTS(fd, "\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200648}
649
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200650static void
Victor Stinner024e37a2011-03-31 01:31:06 +0200651dump_traceback(int fd, PyThreadState *tstate, int write_header)
652{
653 PyFrameObject *frame;
654 unsigned int depth;
655
Victor Stinner024e37a2011-03-31 01:31:06 +0200656 if (write_header)
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700657 PUTS(fd, "Stack (most recent call first):\n");
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200658
659 frame = _PyThreadState_GetFrame(tstate);
660 if (frame == NULL)
661 return;
662
Victor Stinner024e37a2011-03-31 01:31:06 +0200663 depth = 0;
664 while (frame != NULL) {
665 if (MAX_FRAME_DEPTH <= depth) {
666 PUTS(fd, " ...\n");
667 break;
668 }
669 if (!PyFrame_Check(frame))
670 break;
671 dump_frame(fd, frame);
672 frame = frame->f_back;
673 depth++;
674 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200675}
676
Victor Stinner97f86b82015-04-01 18:38:01 +0200677/* Dump the traceback of a Python thread into fd. Use write() to write the
678 traceback and retry if write() is interrupted by a signal (failed with
679 EINTR), but don't call the Python signal handler.
680
681 The caller is responsible to call PyErr_CheckSignals() to call Python signal
682 handlers if signals were received. */
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200683void
Victor Stinner024e37a2011-03-31 01:31:06 +0200684_Py_DumpTraceback(int fd, PyThreadState *tstate)
685{
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200686 dump_traceback(fd, tstate, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200687}
688
689/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
690 is_current is true, "Thread 0xHHHH:\n" otherwise.
691
692 This function is signal safe. */
693
694static void
695write_thread_id(int fd, PyThreadState *tstate, int is_current)
696{
697 if (is_current)
698 PUTS(fd, "Current thread 0x");
699 else
700 PUTS(fd, "Thread 0x");
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200701 dump_hexadecimal(fd, (unsigned long)tstate->thread_id, sizeof(unsigned long)*2);
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700702 PUTS(fd, " (most recent call first):\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200703}
704
Victor Stinner97f86b82015-04-01 18:38:01 +0200705/* Dump the traceback of all Python threads into fd. Use write() to write the
706 traceback and retry if write() is interrupted by a signal (failed with
707 EINTR), but don't call the Python signal handler.
708
709 The caller is responsible to call PyErr_CheckSignals() to call Python signal
710 handlers if signals were received. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200711const char*
712_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
713 PyThreadState *current_thread)
714{
715 PyThreadState *tstate;
716 unsigned int nthreads;
717
718 /* Get the current interpreter from the current thread */
719 tstate = PyInterpreterState_ThreadHead(interp);
720 if (tstate == NULL)
721 return "unable to get the thread head state";
722
723 /* Dump the traceback of each thread */
724 tstate = PyInterpreterState_ThreadHead(interp);
725 nthreads = 0;
Steve Dower8fc89802015-04-12 00:26:27 -0400726 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner024e37a2011-03-31 01:31:06 +0200727 do
728 {
729 if (nthreads != 0)
Victor Stinner97f86b82015-04-01 18:38:01 +0200730 PUTS(fd, "\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200731 if (nthreads >= MAX_NTHREADS) {
732 PUTS(fd, "...\n");
733 break;
734 }
735 write_thread_id(fd, tstate, tstate == current_thread);
736 dump_traceback(fd, tstate, 0);
737 tstate = PyThreadState_Next(tstate);
738 nthreads++;
739 } while (tstate != NULL);
Steve Dower8fc89802015-04-12 00:26:27 -0400740 _Py_END_SUPPRESS_IPH
Victor Stinner024e37a2011-03-31 01:31:06 +0200741
742 return NULL;
743}
744