blob: 01e947315a89e33b4162cb5b1547ef8c82db5901 [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
Collin Winter3eed7652007-08-14 17:53:54 +000024static PyObject *
25tb_dir(PyTracebackObject *self)
26{
27 return Py_BuildValue("[ssss]", "tb_frame", "tb_next",
28 "tb_lasti", "tb_lineno");
29}
30
31static PyMethodDef tb_methods[] = {
32 {"__dir__", (PyCFunction)tb_dir, METH_NOARGS},
33 {NULL, NULL, 0, NULL},
34};
35
Neal Norwitz8dfc4a92007-08-11 06:39:53 +000036static PyMemberDef tb_memberlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037 {"tb_next", T_OBJECT, OFF(tb_next), READONLY},
38 {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY},
39 {"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
40 {"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
41 {NULL} /* Sentinel */
Guido van Rossum3f5da241990-12-20 15:06:42 +000042};
43
Guido van Rossum3f5da241990-12-20 15:06:42 +000044static void
Nicholas Bastina7604bf2004-03-21 18:37:23 +000045tb_dealloc(PyTracebackObject *tb)
Guido van Rossum3f5da241990-12-20 15:06:42 +000046{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000047 PyObject_GC_UnTrack(tb);
48 Py_TRASHCAN_SAFE_BEGIN(tb)
49 Py_XDECREF(tb->tb_next);
50 Py_XDECREF(tb->tb_frame);
51 PyObject_GC_Del(tb);
52 Py_TRASHCAN_SAFE_END(tb)
Guido van Rossum3f5da241990-12-20 15:06:42 +000053}
54
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +000055static int
Nicholas Bastina7604bf2004-03-21 18:37:23 +000056tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +000057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058 Py_VISIT(tb->tb_next);
59 Py_VISIT(tb->tb_frame);
60 return 0;
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +000061}
62
63static void
Nicholas Bastina7604bf2004-03-21 18:37:23 +000064tb_clear(PyTracebackObject *tb)
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +000065{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 Py_CLEAR(tb->tb_next);
67 Py_CLEAR(tb->tb_frame);
Jeremy Hyltonfd14d8e2001-10-22 22:17:41 +000068}
69
Tim Petersd7c36522001-10-22 19:34:09 +000070PyTypeObject PyTraceBack_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 PyVarObject_HEAD_INIT(&PyType_Type, 0)
72 "traceback",
73 sizeof(PyTracebackObject),
74 0,
75 (destructor)tb_dealloc, /*tp_dealloc*/
76 0, /*tp_print*/
77 0, /*tp_getattr*/
78 0, /*tp_setattr*/
79 0, /*tp_reserved*/
80 0, /*tp_repr*/
81 0, /*tp_as_number*/
82 0, /*tp_as_sequence*/
83 0, /*tp_as_mapping*/
84 0, /* tp_hash */
85 0, /* tp_call */
86 0, /* tp_str */
87 PyObject_GenericGetAttr, /* tp_getattro */
88 0, /* tp_setattro */
89 0, /* tp_as_buffer */
90 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
91 0, /* tp_doc */
92 (traverseproc)tb_traverse, /* tp_traverse */
93 (inquiry)tb_clear, /* tp_clear */
94 0, /* tp_richcompare */
95 0, /* tp_weaklistoffset */
96 0, /* tp_iter */
97 0, /* tp_iternext */
98 tb_methods, /* tp_methods */
99 tb_memberlist, /* tp_members */
100 0, /* tp_getset */
101 0, /* tp_base */
102 0, /* tp_dict */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000103};
104
Nicholas Bastina7604bf2004-03-21 18:37:23 +0000105static PyTracebackObject *
106newtracebackobject(PyTracebackObject *next, PyFrameObject *frame)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000107{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000108 PyTracebackObject *tb;
109 if ((next != NULL && !PyTraceBack_Check(next)) ||
110 frame == NULL || !PyFrame_Check(frame)) {
111 PyErr_BadInternalCall();
112 return NULL;
113 }
114 tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
115 if (tb != NULL) {
116 Py_XINCREF(next);
117 tb->tb_next = next;
118 Py_XINCREF(frame);
119 tb->tb_frame = frame;
120 tb->tb_lasti = frame->f_lasti;
121 tb->tb_lineno = PyFrame_GetLineNumber(frame);
122 PyObject_GC_Track(tb);
123 }
124 return tb;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000125}
126
Guido van Rossum3f5da241990-12-20 15:06:42 +0000127int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000128PyTraceBack_Here(PyFrameObject *frame)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 PyThreadState *tstate = PyThreadState_GET();
131 PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback;
132 PyTracebackObject *tb = newtracebackobject(oldtb, frame);
133 if (tb == NULL)
134 return -1;
135 tstate->curexc_traceback = (PyObject *)tb;
136 Py_XDECREF(oldtb);
137 return 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000138}
139
Victor Stinner0fe25a42010-06-17 23:08:50 +0000140static PyObject *
141_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000142{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000143 Py_ssize_t i;
144 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 PyObject *v;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000146 Py_ssize_t npath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 size_t taillen;
148 PyObject *syspath;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000149 PyObject *path;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 const char* tail;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000151 PyObject *filebytes;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000152 const char* filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 Py_ssize_t len;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000154 PyObject* result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200155 _Py_IDENTIFIER(open);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000156
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000157 filebytes = PyUnicode_EncodeFSDefault(filename);
158 if (filebytes == NULL) {
Victor Stinner0fe25a42010-06-17 23:08:50 +0000159 PyErr_Clear();
160 return NULL;
161 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000162 filepath = PyBytes_AS_STRING(filebytes);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 /* Search tail of filename in sys.path before giving up */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000165 tail = strrchr(filepath, SEP);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 if (tail == NULL)
Victor Stinner0fe25a42010-06-17 23:08:50 +0000167 tail = filepath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 else
169 tail++;
170 taillen = strlen(tail);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 syspath = PySys_GetObject("path");
173 if (syspath == NULL || !PyList_Check(syspath))
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000174 goto error;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000175 npath = PyList_Size(syspath);
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 for (i = 0; i < npath; i++) {
178 v = PyList_GetItem(syspath, i);
179 if (v == NULL) {
180 PyErr_Clear();
181 break;
182 }
183 if (!PyUnicode_Check(v))
184 continue;
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000185 path = PyUnicode_EncodeFSDefault(v);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000186 if (path == NULL) {
187 PyErr_Clear();
188 continue;
189 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000190 len = PyBytes_GET_SIZE(path);
191 if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) {
192 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 continue; /* Too long */
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000194 }
195 strcpy(namebuf, PyBytes_AS_STRING(path));
196 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 if (strlen(namebuf) != len)
198 continue; /* v contains '\0' */
199 if (len > 0 && namebuf[len-1] != SEP)
200 namebuf[len++] = SEP;
201 strcpy(namebuf+len, tail);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000202
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200203 binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb");
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000204 if (binary != NULL) {
205 result = binary;
206 goto finally;
207 }
Victor Stinner0fe25a42010-06-17 23:08:50 +0000208 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 }
Victor Stinner4c7c8c32010-10-16 13:14:10 +0000210 goto error;
211
212error:
213 result = NULL;
214finally:
215 Py_DECREF(filebytes);
216 return result;
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000217}
218
Christian Heimes33fe8092008-04-13 13:53:33 +0000219int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000220_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000221{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 int err = 0;
223 int fd;
224 int i;
225 char *found_encoding;
226 char *encoding;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000227 PyObject *io;
228 PyObject *binary;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 PyObject *fob = NULL;
230 PyObject *lineobj = NULL;
Antoine Pitroub86680e2010-10-14 21:15:17 +0000231 PyObject *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 char buf[MAXPATHLEN+1];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200233 int kind;
234 void *data;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200235 _Py_IDENTIFIER(close);
236 _Py_IDENTIFIER(open);
237 _Py_IDENTIFIER(TextIOWrapper);
Christian Heimes679db4a2008-01-18 09:56:22 +0000238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 /* open the file */
240 if (filename == NULL)
241 return 0;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000242
243 io = PyImport_ImportModuleNoBlock("io");
244 if (io == NULL)
245 return -1;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200246 binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");
Victor Stinner0fe25a42010-06-17 23:08:50 +0000247
248 if (binary == NULL) {
Victor Stinnerceceaa02013-07-16 00:32:14 +0200249 PyErr_Clear();
250
Victor Stinner0fe25a42010-06-17 23:08:50 +0000251 binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
252 if (binary == NULL) {
253 Py_DECREF(io);
Victor Stinnerceceaa02013-07-16 00:32:14 +0200254 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000255 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 /* use the right encoding to decode the file as unicode */
Victor Stinner0fe25a42010-06-17 23:08:50 +0000259 fd = PyObject_AsFileDescriptor(binary);
Christian Heimes8c077bc2013-07-21 01:53:10 +0200260 if (fd < 0) {
261 Py_DECREF(io);
262 Py_DECREF(binary);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700263 return 0;
Christian Heimes8c077bc2013-07-21 01:53:10 +0200264 }
Victor Stinnerfe7c5b52011-04-05 01:48:03 +0200265 found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000266 encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
Christian Heimes1f347292013-07-21 02:12:35 +0200267 /* Reset position */
268 if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
269 Py_DECREF(io);
270 Py_DECREF(binary);
271 PyMem_FREE(found_encoding);
Benjamin Peterson04b01dc2013-07-21 13:26:13 -0700272 return 0;
Christian Heimes1f347292013-07-21 02:12:35 +0200273 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200274 fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000275 Py_DECREF(io);
276 Py_DECREF(binary);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 PyMem_FREE(found_encoding);
Victor Stinner0fe25a42010-06-17 23:08:50 +0000278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 if (fob == NULL) {
280 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 return 0;
282 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 /* get the line number lineno */
285 for (i = 0; i < lineno; i++) {
286 Py_XDECREF(lineobj);
287 lineobj = PyFile_GetLine(fob, -1);
288 if (!lineobj) {
289 err = -1;
290 break;
291 }
292 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200293 res = _PyObject_CallMethodId(fob, &PyId_close, "");
Antoine Pitroub86680e2010-10-14 21:15:17 +0000294 if (res)
295 Py_DECREF(res);
296 else
297 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 Py_DECREF(fob);
299 if (!lineobj || !PyUnicode_Check(lineobj)) {
300 Py_XDECREF(lineobj);
301 return err;
302 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 /* remove the indentation of the line */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200305 kind = PyUnicode_KIND(lineobj);
306 data = PyUnicode_DATA(lineobj);
307 for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) {
308 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
309 if (ch != ' ' && ch != '\t' && ch != '\014')
310 break;
311 }
312 if (i) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 PyObject *truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200314 truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 if (truncated) {
316 Py_DECREF(lineobj);
317 lineobj = truncated;
318 } else {
319 PyErr_Clear();
320 }
321 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 /* Write some spaces before the line */
324 strcpy(buf, " ");
325 assert (strlen(buf) == 10);
326 while (indent > 0) {
Benjamin Peterson0f9b7d32013-07-21 13:29:37 -0700327 if (indent < 10)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 buf[indent] = '\0';
329 err = PyFile_WriteString(buf, f);
330 if (err != 0)
331 break;
332 indent -= 10;
333 }
Amaury Forgeot d'Arccf8016a2008-10-09 23:37:48 +0000334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 /* finally display the line */
336 if (err == 0)
337 err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
338 Py_DECREF(lineobj);
339 if (err == 0)
340 err = PyFile_WriteString("\n", f);
341 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000342}
343
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000344static int
Victor Stinner0fe25a42010-06-17 23:08:50 +0000345tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000346{
Victor Stinner0fe25a42010-06-17 23:08:50 +0000347 int err;
348 PyObject *line;
Christian Heimes33fe8092008-04-13 13:53:33 +0000349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 if (filename == NULL || name == NULL)
351 return -1;
Victor Stinner0fe25a42010-06-17 23:08:50 +0000352 line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
353 filename, lineno, name);
354 if (line == NULL)
355 return -1;
356 err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
357 Py_DECREF(line);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 if (err != 0)
359 return err;
Kristján Valur Jónssonc5963d32012-07-19 21:02:03 +0000360 /* ignore errors since we can't report them, can we? */
361 if (_Py_DisplaySourceLine(f, filename, lineno, 4))
362 PyErr_Clear();
363 return err;
Christian Heimes33fe8092008-04-13 13:53:33 +0000364}
365
366static int
367tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 int err = 0;
370 long depth = 0;
371 PyTracebackObject *tb1 = tb;
372 while (tb1 != NULL) {
373 depth++;
374 tb1 = tb1->tb_next;
375 }
376 while (tb != NULL && err == 0) {
377 if (depth <= limit) {
378 err = tb_displayline(f,
Victor Stinner0fe25a42010-06-17 23:08:50 +0000379 tb->tb_frame->f_code->co_filename,
380 tb->tb_lineno,
381 tb->tb_frame->f_code->co_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 }
383 depth--;
384 tb = tb->tb_next;
385 if (err == 0)
386 err = PyErr_CheckSignals();
387 }
388 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000389}
390
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000391#define PyTraceBack_LIMIT 1000
392
Guido van Rossum3f5da241990-12-20 15:06:42 +0000393int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000394PyTraceBack_Print(PyObject *v, PyObject *f)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000395{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 int err;
397 PyObject *limitv;
398 long limit = PyTraceBack_LIMIT;
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 if (v == NULL)
401 return 0;
402 if (!PyTraceBack_Check(v)) {
403 PyErr_BadInternalCall();
404 return -1;
405 }
406 limitv = PySys_GetObject("tracebacklimit");
407 if (limitv) {
408 PyObject *exc_type, *exc_value, *exc_tb;
Christian Heimes0fbab7f2007-12-04 21:55:18 +0000409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
411 limit = PyLong_AsLong(limitv);
412 if (limit == -1 && PyErr_Occurred()) {
413 if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
414 limit = PyTraceBack_LIMIT;
415 }
416 else {
417 Py_XDECREF(exc_type);
418 Py_XDECREF(exc_value);
419 Py_XDECREF(exc_tb);
420 return 0;
421 }
422 }
423 else if (limit <= 0) {
424 limit = PyTraceBack_LIMIT;
425 }
426 PyErr_Restore(exc_type, exc_value, exc_tb);
427 }
428 err = PyFile_WriteString("Traceback (most recent call last):\n", f);
429 if (!err)
430 err = tb_printinternal((PyTracebackObject *)v, f, limit);
431 return err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000432}
Victor Stinner024e37a2011-03-31 01:31:06 +0200433
434/* Reverse a string. For example, "abcd" becomes "dcba".
435
436 This function is signal safe. */
437
438static void
439reverse_string(char *text, const size_t len)
440{
441 char tmp;
442 size_t i, j;
443 if (len == 0)
444 return;
445 for (i=0, j=len-1; i < j; i++, j--) {
446 tmp = text[i];
447 text[i] = text[j];
448 text[j] = tmp;
449 }
450}
451
452/* Format an integer in range [0; 999999] to decimal,
453 and write it into the file fd.
454
455 This function is signal safe. */
456
457static void
458dump_decimal(int fd, int value)
459{
460 char buffer[7];
461 int len;
462 if (value < 0 || 999999 < value)
463 return;
464 len = 0;
465 do {
466 buffer[len] = '0' + (value % 10);
467 value /= 10;
468 len++;
469 } while (value);
470 reverse_string(buffer, len);
471 write(fd, buffer, len);
472}
473
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700474/* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits,
Victor Stinner024e37a2011-03-31 01:31:06 +0200475 and write it into the file fd.
476
477 This function is signal safe. */
478
479static void
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700480dump_hexadecimal(int fd, unsigned long value, int width)
Victor Stinner024e37a2011-03-31 01:31:06 +0200481{
Victor Stinner024e37a2011-03-31 01:31:06 +0200482 int len;
483 char buffer[sizeof(unsigned long) * 2 + 1];
484 len = 0;
485 do {
Victor Stinnerf5cff562011-10-14 02:13:11 +0200486 buffer[len] = Py_hexdigits[value & 15];
Victor Stinner024e37a2011-03-31 01:31:06 +0200487 value >>= 4;
488 len++;
489 } while (len < width || value);
490 reverse_string(buffer, len);
491 write(fd, buffer, len);
492}
493
494/* Write an unicode object into the file fd using ascii+backslashreplace.
495
496 This function is signal safe. */
497
498static void
499dump_ascii(int fd, PyObject *text)
500{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200501 PyASCIIObject *ascii = (PyASCIIObject *)text;
Victor Stinner024e37a2011-03-31 01:31:06 +0200502 Py_ssize_t i, size;
503 int truncated;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200504 int kind;
Victor Stinnera336de72011-10-05 22:44:12 +0200505 void *data = NULL;
506 wchar_t *wstr = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200507 Py_UCS4 ch;
Victor Stinner024e37a2011-03-31 01:31:06 +0200508
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200509 size = ascii->length;
510 kind = ascii->state.kind;
511 if (ascii->state.compact) {
512 if (ascii->state.ascii)
513 data = ((PyASCIIObject*)text) + 1;
514 else
515 data = ((PyCompactUnicodeObject*)text) + 1;
516 }
Victor Stinnera336de72011-10-05 22:44:12 +0200517 else if (kind != PyUnicode_WCHAR_KIND) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200518 data = ((PyUnicodeObject *)text)->data.any;
519 if (data == NULL)
520 return;
521 }
Victor Stinnera336de72011-10-05 22:44:12 +0200522 else {
523 wstr = ((PyASCIIObject *)text)->wstr;
524 if (wstr == NULL)
525 return;
526 size = ((PyCompactUnicodeObject *)text)->wstr_length;
527 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200528
529 if (MAX_STRING_LENGTH < size) {
530 size = MAX_STRING_LENGTH;
531 truncated = 1;
532 }
533 else
534 truncated = 0;
535
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200536 for (i=0; i < size; i++) {
Victor Stinnera336de72011-10-05 22:44:12 +0200537 if (kind != PyUnicode_WCHAR_KIND)
538 ch = PyUnicode_READ(kind, data, i);
539 else
540 ch = wstr[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200541 if (ch < 128) {
542 char c = (char)ch;
Victor Stinner024e37a2011-03-31 01:31:06 +0200543 write(fd, &c, 1);
544 }
Victor Stinner63ab8752011-11-22 03:31:20 +0100545 else if (ch < 0xff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200546 PUTS(fd, "\\x");
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700547 dump_hexadecimal(fd, ch, 2);
Victor Stinner024e37a2011-03-31 01:31:06 +0200548 }
Victor Stinner63ab8752011-11-22 03:31:20 +0100549 else if (ch < 0xffff) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200550 PUTS(fd, "\\u");
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700551 dump_hexadecimal(fd, ch, 4);
Victor Stinner024e37a2011-03-31 01:31:06 +0200552 }
553 else {
554 PUTS(fd, "\\U");
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700555 dump_hexadecimal(fd, ch, 8);
Victor Stinner024e37a2011-03-31 01:31:06 +0200556 }
557 }
558 if (truncated)
559 PUTS(fd, "...");
560}
561
562/* Write a frame into the file fd: "File "xxx", line xxx in xxx".
563
564 This function is signal safe. */
565
566static void
567dump_frame(int fd, PyFrameObject *frame)
568{
569 PyCodeObject *code;
570 int lineno;
571
572 code = frame->f_code;
573 PUTS(fd, " File ");
574 if (code != NULL && code->co_filename != NULL
575 && PyUnicode_Check(code->co_filename))
576 {
577 write(fd, "\"", 1);
578 dump_ascii(fd, code->co_filename);
579 write(fd, "\"", 1);
580 } else {
581 PUTS(fd, "???");
582 }
583
584 /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200585 lineno = PyCode_Addr2Line(code, frame->f_lasti);
Victor Stinner024e37a2011-03-31 01:31:06 +0200586 PUTS(fd, ", line ");
587 dump_decimal(fd, lineno);
588 PUTS(fd, " in ");
589
590 if (code != NULL && code->co_name != NULL
591 && PyUnicode_Check(code->co_name))
592 dump_ascii(fd, code->co_name);
593 else
594 PUTS(fd, "???");
595
596 write(fd, "\n", 1);
597}
598
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200599static void
Victor Stinner024e37a2011-03-31 01:31:06 +0200600dump_traceback(int fd, PyThreadState *tstate, int write_header)
601{
602 PyFrameObject *frame;
603 unsigned int depth;
604
Victor Stinner024e37a2011-03-31 01:31:06 +0200605 if (write_header)
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700606 PUTS(fd, "Stack (most recent call first):\n");
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200607
608 frame = _PyThreadState_GetFrame(tstate);
609 if (frame == NULL)
610 return;
611
Victor Stinner024e37a2011-03-31 01:31:06 +0200612 depth = 0;
613 while (frame != NULL) {
614 if (MAX_FRAME_DEPTH <= depth) {
615 PUTS(fd, " ...\n");
616 break;
617 }
618 if (!PyFrame_Check(frame))
619 break;
620 dump_frame(fd, frame);
621 frame = frame->f_back;
622 depth++;
623 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200624}
625
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200626void
Victor Stinner024e37a2011-03-31 01:31:06 +0200627_Py_DumpTraceback(int fd, PyThreadState *tstate)
628{
Victor Stinnerfcb88c42011-04-01 15:34:01 +0200629 dump_traceback(fd, tstate, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200630}
631
632/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
633 is_current is true, "Thread 0xHHHH:\n" otherwise.
634
635 This function is signal safe. */
636
637static void
638write_thread_id(int fd, PyThreadState *tstate, int is_current)
639{
640 if (is_current)
641 PUTS(fd, "Current thread 0x");
642 else
643 PUTS(fd, "Thread 0x");
Guido van Rossum7be5d7d2013-10-20 18:21:02 -0700644 dump_hexadecimal(fd, (unsigned long)tstate->thread_id, sizeof(long)*2);
645 PUTS(fd, " (most recent call first):\n");
Victor Stinner024e37a2011-03-31 01:31:06 +0200646}
647
648const char*
649_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
650 PyThreadState *current_thread)
651{
652 PyThreadState *tstate;
653 unsigned int nthreads;
654
655 /* Get the current interpreter from the current thread */
656 tstate = PyInterpreterState_ThreadHead(interp);
657 if (tstate == NULL)
658 return "unable to get the thread head state";
659
660 /* Dump the traceback of each thread */
661 tstate = PyInterpreterState_ThreadHead(interp);
662 nthreads = 0;
663 do
664 {
665 if (nthreads != 0)
666 write(fd, "\n", 1);
667 if (nthreads >= MAX_NTHREADS) {
668 PUTS(fd, "...\n");
669 break;
670 }
671 write_thread_id(fd, tstate, tstate == current_thread);
672 dump_traceback(fd, tstate, 0);
673 tstate = PyThreadState_Next(tstate);
674 nthreads++;
675 } while (tstate != NULL);
676
677 return NULL;
678}
679