blob: 4316f66f5714a3ca5af3e3ae0e46c3939a89b7e5 [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 Stinner84bb1cf2013-05-17 00:12:04 +020016#define PUTS(fd, str) write(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{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 PyThreadState *tstate = PyThreadState_GET();
136 PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback;
137 PyTracebackObject *tb = newtracebackobject(oldtb, frame);
138 if (tb == NULL)
139 return -1;
140 tstate->curexc_traceback = (PyObject *)tb;
141 Py_XDECREF(oldtb);
142 return 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000143}
144
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200145/* Insert a frame into the traceback for (funcname, filename, lineno). */
146void _PyTraceback_Add(char *funcname, char *filename, int lineno)
147{
148 PyObject *globals = NULL;
149 PyCodeObject *code = NULL;
150 PyFrameObject *frame = NULL;
151 PyObject *exception, *value, *tb;
152
153 /* Save and clear the current exception. Python functions must not be
154 called with an exception set. Calling Python functions happens when
155 the codec of the filesystem encoding is implemented in pure Python. */
156 PyErr_Fetch(&exception, &value, &tb);
157
158 globals = PyDict_New();
159 if (!globals)
160 goto done;
161 code = PyCode_NewEmpty(filename, funcname, lineno);
162 if (!code)
163 goto done;
164 frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL);
165 if (!frame)
166 goto done;
167 frame->f_lineno = lineno;
168
169 PyErr_Restore(exception, value, tb);
170 PyTraceBack_Here(frame);
171
172done:
173 Py_XDECREF(globals);
174 Py_XDECREF(code);
175 Py_XDECREF(frame);
176}
177
Victor Stinner0fe25a42010-06-17 23:08:50 +0000178static PyObject *
179_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000180{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000181 Py_ssize_t i;
182 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000183 PyObject *v;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000184 Py_ssize_t npath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 size_t taillen;
186 PyObject *syspath;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000187 PyObject *path;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 const char* tail;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000189 PyObject *filebytes;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000190 const char* filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 Py_ssize_t len;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000192 PyObject* result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000193
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000194 filebytes = PyUnicode_EncodeFSDefault(filename);
195 if (filebytes == NULL) {
Victor Stinner0fe25a42010-06-17 23:08:50 +0000196 PyErr_Clear();
197 return NULL;
198 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000199 filepath = PyBytes_AS_STRING(filebytes);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 /* Search tail of filename in sys.path before giving up */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000202 tail = strrchr(filepath, SEP);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 if (tail == NULL)
Victor Stinner0fe25a42010-06-17 23:08:50 +0000204 tail = filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 else
206 tail++;
207 taillen = strlen(tail);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000208
Victor Stinnerbd303c12013-11-07 23:07:29 +0100209 syspath = _PySys_GetObjectId(&PyId_path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 if (syspath == NULL || !PyList_Check(syspath))
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000211 goto error;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000212 npath = PyList_Size(syspath);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 for (i = 0; i < npath; i++) {
215 v = PyList_GetItem(syspath, i);
216 if (v == NULL) {
217 PyErr_Clear();
218 break;
219 }
220 if (!PyUnicode_Check(v))
221 continue;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000222 path = PyUnicode_EncodeFSDefault(v);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000223 if (path == NULL) {
224 PyErr_Clear();
225 continue;
226 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000227 len = PyBytes_GET_SIZE(path);
228 if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) {
229 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 continue; /* Too long */
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000231 }
232 strcpy(namebuf, PyBytes_AS_STRING(path));
233 Py_DECREF(path);
Victor Stinner98ea54c2014-08-15 23:30:40 +0200234 if (strlen(namebuf) != (size_t)len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 continue; /* v contains '\0' */
236 if (len > 0 && namebuf[len-1] != SEP)
237 namebuf[len++] = SEP;
238 strcpy(namebuf+len, tail);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000239
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200240 binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb");
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000241 if (binary != NULL) {
242 result = binary;
243 goto finally;
244 }
Victor Stinner0fe25a42010-06-17 23:08:50 +0000245 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000247 goto error;
248
249error:
250 result = NULL;
251finally:
252 Py_DECREF(filebytes);
253 return result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000254}
255
Christian Heimes33fe8092008-04-13 13:53:33 +0000256int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000257_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 int err = 0;
260 int fd;
261 int i;
262 char *found_encoding;
263 char *encoding;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000264 PyObject *io;
265 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 PyObject *fob = NULL;
267 PyObject *lineobj = NULL;
Antoine Pitroub86680e2010-10-14 21:15:17 +0000268 PyObject *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 char buf[MAXPATHLEN+1];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200270 int kind;
271 void *data;
Christian Heimes679db4a2008-01-18 09:56:22 +0000272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 /* open the file */
274 if (filename == NULL)
275 return 0;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000276
277 io = PyImport_ImportModuleNoBlock("io");
278 if (io == NULL)
279 return -1;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200280 binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");
Victor Stinner0fe25a42010-06-17 23:08:50 +0000281
282 if (binary == NULL) {
Victor Stinnerceceaa02013-07-16 00:32:14 +0200283 PyErr_Clear();
284
Victor Stinner0fe25a42010-06-17 23:08:50 +0000285 binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
286 if (binary == NULL) {
287 Py_DECREF(io);
Victor Stinnerceceaa02013-07-16 00:32:14 +0200288 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000289 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 /* use the right encoding to decode the file as unicode */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000293 fd = PyObject_AsFileDescriptor(binary);
Christian Heimes8c077bc2013-07-21 01:53:10 +0200294 if (fd < 0) {
295 Py_DECREF(io);
296 Py_DECREF(binary);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700297 return 0;
Christian Heimes8c077bc2013-07-21 01:53:10 +0200298 }
Victor Stinnerfe7c5b52011-04-05 01:48:03 +0200299 found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
Victor Stinner5272fa92013-12-19 13:39:32 +0100300 if (found_encoding == NULL)
301 PyErr_Clear();
Victor Stinner0fe25a42010-06-17 23:08:50 +0000302 encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
Christian Heimes1f347292013-07-21 02:12:35 +0200303 /* Reset position */
304 if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
305 Py_DECREF(io);
306 Py_DECREF(binary);
307 PyMem_FREE(found_encoding);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700308 return 0;
Christian Heimes1f347292013-07-21 02:12:35 +0200309 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200310 fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000311 Py_DECREF(io);
312 Py_DECREF(binary);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 PyMem_FREE(found_encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 if (fob == NULL) {
316 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 return 0;
318 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 /* get the line number lineno */
321 for (i = 0; i < lineno; i++) {
322 Py_XDECREF(lineobj);
323 lineobj = PyFile_GetLine(fob, -1);
324 if (!lineobj) {
325 err = -1;
326 break;
327 }
328 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200329 res = _PyObject_CallMethodId(fob, &PyId_close, "");
Antoine Pitroub86680e2010-10-14 21:15:17 +0000330 if (res)
331 Py_DECREF(res);
332 else
333 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 Py_DECREF(fob);
335 if (!lineobj || !PyUnicode_Check(lineobj)) {
336 Py_XDECREF(lineobj);
337 return err;
338 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 /* remove the indentation of the line */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200341 kind = PyUnicode_KIND(lineobj);
342 data = PyUnicode_DATA(lineobj);
343 for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) {
344 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
345 if (ch != ' ' && ch != '\t' && ch != '\014')
346 break;
347 }
348 if (i) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 PyObject *truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200350 truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 if (truncated) {
352 Py_DECREF(lineobj);
353 lineobj = truncated;
354 } else {
355 PyErr_Clear();
356 }
357 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 /* Write some spaces before the line */
360 strcpy(buf, " ");
361 assert (strlen(buf) == 10);
362 while (indent > 0) {
Benjamin Peterson0f9b7d32013-07-21 13:29:37 -0700363 if (indent < 10)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 buf[indent] = '\0';
365 err = PyFile_WriteString(buf, f);
366 if (err != 0)
367 break;
368 indent -= 10;
369 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 /* finally display the line */
372 if (err == 0)
373 err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
374 Py_DECREF(lineobj);
375 if (err == 0)
376 err = PyFile_WriteString("\n", f);
377 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000378}
379
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000380static int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000381tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000382{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000383 int err;
384 PyObject *line;
Christian Heimes33fe8092008-04-13 13:53:33 +0000385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 if (filename == NULL || name == NULL)
387 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000388 line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
389 filename, lineno, name);
390 if (line == NULL)
391 return -1;
392 err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
393 Py_DECREF(line);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 if (err != 0)
395 return err;
Kristján Valur Jónssonc5963d32012-07-19 21:02:03 +0000396 /* ignore errors since we can't report them, can we? */
397 if (_Py_DisplaySourceLine(f, filename, lineno, 4))
398 PyErr_Clear();
399 return err;
Christian Heimes33fe8092008-04-13 13:53:33 +0000400}
401
402static int
403tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 int err = 0;
406 long depth = 0;
407 PyTracebackObject *tb1 = tb;
408 while (tb1 != NULL) {
409 depth++;
410 tb1 = tb1->tb_next;
411 }
412 while (tb != NULL && err == 0) {
413 if (depth <= limit) {
414 err = tb_displayline(f,
Victor Stinner0fe25a42010-06-17 23:08:50 +0000415 tb->tb_frame->f_code->co_filename,
416 tb->tb_lineno,
417 tb->tb_frame->f_code->co_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 }
419 depth--;
420 tb = tb->tb_next;
421 if (err == 0)
422 err = PyErr_CheckSignals();
423 }
424 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000425}
426
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000427#define PyTraceBack_LIMIT 1000
428
Guido van Rossum3f5da241990-12-20 15:06:42 +0000429int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000430PyTraceBack_Print(PyObject *v, PyObject *f)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 int err;
433 PyObject *limitv;
434 long limit = PyTraceBack_LIMIT;
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 if (v == NULL)
437 return 0;
438 if (!PyTraceBack_Check(v)) {
439 PyErr_BadInternalCall();
440 return -1;
441 }
442 limitv = PySys_GetObject("tracebacklimit");
443 if (limitv) {
444 PyObject *exc_type, *exc_value, *exc_tb;
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
447 limit = PyLong_AsLong(limitv);
448 if (limit == -1 && PyErr_Occurred()) {
449 if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
450 limit = PyTraceBack_LIMIT;
451 }
452 else {
453 Py_XDECREF(exc_type);
454 Py_XDECREF(exc_value);
455 Py_XDECREF(exc_tb);
456 return 0;
457 }
458 }
459 else if (limit <= 0) {
460 limit = PyTraceBack_LIMIT;
461 }
462 PyErr_Restore(exc_type, exc_value, exc_tb);
463 }
464 err = PyFile_WriteString("Traceback (most recent call last):\n", f);
465 if (!err)
466 err = tb_printinternal((PyTracebackObject *)v, f, limit);
467 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000468}
Victor Stinner024e37a2011-03-31 01:31:06 +0200469
470/* Reverse a string. For example, "abcd" becomes "dcba".
471
472 This function is signal safe. */
473
474static void
475reverse_string(char *text, const size_t len)
476{
477 char tmp;
478 size_t i, j;
479 if (len == 0)
480 return;
481 for (i=0, j=len-1; i < j; i++, j--) {
482 tmp = text[i];
483 text[i] = text[j];
484 text[j] = tmp;
485 }
486}
487
488/* Format an integer in range [0; 999999] to decimal,
489 and write it into the file fd.
490
491 This function is signal safe. */
492
493static void
494dump_decimal(int fd, int value)
495{
496 char buffer[7];
497 int len;
498 if (value < 0 || 999999 < value)
499 return;
500 len = 0;
501 do {
502 buffer[len] = '0' + (value % 10);
503 value /= 10;
504 len++;
505 } while (value);
506 reverse_string(buffer, len);
507 write(fd, buffer, len);
508}
509
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700510/* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits,
Victor Stinner024e37a2011-03-31 01:31:06 +0200511 and write it into the file fd.
512
513 This function is signal safe. */
514
515static void
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700516dump_hexadecimal(int fd, unsigned long value, int width)
Victor Stinner024e37a2011-03-31 01:31:06 +0200517{
Victor Stinner024e37a2011-03-31 01:31:06 +0200518 int len;
519 char buffer[sizeof(unsigned long) * 2 + 1];
520 len = 0;
521 do {
Victor Stinnerf5cff562011-10-14 02:13:11 +0200522 buffer[len] = Py_hexdigits[value & 15];
Victor Stinner024e37a2011-03-31 01:31:06 +0200523 value >>= 4;
524 len++;
525 } while (len < width || value);
526 reverse_string(buffer, len);
527 write(fd, buffer, len);
528}
529
530/* Write an unicode object into the file fd using ascii+backslashreplace.
531
532 This function is signal safe. */
533
534static void
535dump_ascii(int fd, PyObject *text)
536{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200537 PyASCIIObject *ascii = (PyASCIIObject *)text;
Victor Stinner024e37a2011-03-31 01:31:06 +0200538 Py_ssize_t i, size;
539 int truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200540 int kind;
Victor Stinnera336de72011-10-05 22:44:12 +0200541 void *data = NULL;
542 wchar_t *wstr = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200543 Py_UCS4 ch;
Victor Stinner024e37a2011-03-31 01:31:06 +0200544
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200545 size = ascii->length;
546 kind = ascii->state.kind;
547 if (ascii->state.compact) {
548 if (ascii->state.ascii)
549 data = ((PyASCIIObject*)text) + 1;
550 else
551 data = ((PyCompactUnicodeObject*)text) + 1;
552 }
Victor Stinnera336de72011-10-05 22:44:12 +0200553 else if (kind != PyUnicode_WCHAR_KIND) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200554 data = ((PyUnicodeObject *)text)->data.any;
555 if (data == NULL)
556 return;
557 }
Victor Stinnera336de72011-10-05 22:44:12 +0200558 else {
559 wstr = ((PyASCIIObject *)text)->wstr;
560 if (wstr == NULL)
561 return;
562 size = ((PyCompactUnicodeObject *)text)->wstr_length;
563 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200564
565 if (MAX_STRING_LENGTH < size) {
566 size = MAX_STRING_LENGTH;
567 truncated = 1;
568 }
569 else
570 truncated = 0;
571
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200572 for (i=0; i < size; i++) {
Victor Stinnera336de72011-10-05 22:44:12 +0200573 if (kind != PyUnicode_WCHAR_KIND)
574 ch = PyUnicode_READ(kind, data, i);
575 else
576 ch = wstr[i];
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200577 if (' ' <= ch && ch <= 126) {
578 /* printable ASCII character */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200579 char c = (char)ch;
Victor Stinner024e37a2011-03-31 01:31:06 +0200580 write(fd, &c, 1);
581 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200582 else if (ch <= 0xff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200583 PUTS(fd, "\\x");
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700584 dump_hexadecimal(fd, ch, 2);
Victor Stinner024e37a2011-03-31 01:31:06 +0200585 }
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200586 else if (ch <= 0xffff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200587 PUTS(fd, "\\u");
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700588 dump_hexadecimal(fd, ch, 4);
Victor Stinner024e37a2011-03-31 01:31:06 +0200589 }
590 else {
591 PUTS(fd, "\\U");
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700592 dump_hexadecimal(fd, ch, 8);
Victor Stinner024e37a2011-03-31 01:31:06 +0200593 }
594 }
595 if (truncated)
596 PUTS(fd, "...");
597}
598
599/* Write a frame into the file fd: "File "xxx", line xxx in xxx".
600
601 This function is signal safe. */
602
603static void
604dump_frame(int fd, PyFrameObject *frame)
605{
606 PyCodeObject *code;
607 int lineno;
608
609 code = frame->f_code;
610 PUTS(fd, " File ");
611 if (code != NULL && code->co_filename != NULL
612 && PyUnicode_Check(code->co_filename))
613 {
614 write(fd, "\"", 1);
615 dump_ascii(fd, code->co_filename);
616 write(fd, "\"", 1);
617 } else {
618 PUTS(fd, "???");
619 }
620
621 /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200622 lineno = PyCode_Addr2Line(code, frame->f_lasti);
Victor Stinner024e37a2011-03-31 01:31:06 +0200623 PUTS(fd, ", line ");
624 dump_decimal(fd, lineno);
625 PUTS(fd, " in ");
626
627 if (code != NULL && code->co_name != NULL
628 && PyUnicode_Check(code->co_name))
629 dump_ascii(fd, code->co_name);
630 else
631 PUTS(fd, "???");
632
633 write(fd, "\n", 1);
634}
635
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200636static void
Victor Stinner024e37a2011-03-31 01:31:06 +0200637dump_traceback(int fd, PyThreadState *tstate, int write_header)
638{
639 PyFrameObject *frame;
640 unsigned int depth;
641
Victor Stinner024e37a2011-03-31 01:31:06 +0200642 if (write_header)
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700643 PUTS(fd, "Stack (most recent call first):\n");
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200644
645 frame = _PyThreadState_GetFrame(tstate);
646 if (frame == NULL)
647 return;
648
Victor Stinner024e37a2011-03-31 01:31:06 +0200649 depth = 0;
650 while (frame != NULL) {
651 if (MAX_FRAME_DEPTH <= depth) {
652 PUTS(fd, " ...\n");
653 break;
654 }
655 if (!PyFrame_Check(frame))
656 break;
657 dump_frame(fd, frame);
658 frame = frame->f_back;
659 depth++;
660 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200661}
662
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200663void
Victor Stinner024e37a2011-03-31 01:31:06 +0200664_Py_DumpTraceback(int fd, PyThreadState *tstate)
665{
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200666 dump_traceback(fd, tstate, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200667}
668
669/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
670 is_current is true, "Thread 0xHHHH:\n" otherwise.
671
672 This function is signal safe. */
673
674static void
675write_thread_id(int fd, PyThreadState *tstate, int is_current)
676{
677 if (is_current)
678 PUTS(fd, "Current thread 0x");
679 else
680 PUTS(fd, "Thread 0x");
Victor Stinnerb86f08f2014-10-03 14:18:09 +0200681 dump_hexadecimal(fd, (unsigned long)tstate->thread_id, sizeof(unsigned long)*2);
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700682 PUTS(fd, " (most recent call first):\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200683}
684
685const char*
686_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
687 PyThreadState *current_thread)
688{
689 PyThreadState *tstate;
690 unsigned int nthreads;
691
692 /* Get the current interpreter from the current thread */
693 tstate = PyInterpreterState_ThreadHead(interp);
694 if (tstate == NULL)
695 return "unable to get the thread head state";
696
697 /* Dump the traceback of each thread */
698 tstate = PyInterpreterState_ThreadHead(interp);
699 nthreads = 0;
700 do
701 {
702 if (nthreads != 0)
703 write(fd, "\n", 1);
704 if (nthreads >= MAX_NTHREADS) {
705 PUTS(fd, "...\n");
706 break;
707 }
708 write_thread_id(fd, tstate, tstate == current_thread);
709 dump_traceback(fd, tstate, 0);
710 tstate = PyThreadState_Next(tstate);
711 nthreads++;
712 } while (tstate != NULL);
713
714 return NULL;
715}
716