traceback.c 21.9 KB
Newer Older
1

Guido van Rossum's avatar
Guido van Rossum committed
2 3
/* Traceback implementation */

Guido van Rossum's avatar
Guido van Rossum committed
4
#include "Python.h"
Guido van Rossum's avatar
Guido van Rossum committed
5

Jeremy Hylton's avatar
Jeremy Hylton committed
6
#include "code.h"
Guido van Rossum's avatar
Guido van Rossum committed
7 8
#include "frameobject.h"
#include "structmember.h"
9
#include "osdefs.h"
10 11 12
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
Guido van Rossum's avatar
Guido van Rossum committed
13

14
#define OFF(x) offsetof(PyTracebackObject, x)
Guido van Rossum's avatar
Guido van Rossum committed
15

16
#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str))
17
#define MAX_STRING_LENGTH 500
18 19 20
#define MAX_FRAME_DEPTH 100
#define MAX_NTHREADS 100

21 22
/* Function from Parser/tokenizer.c */
extern char * PyTokenizer_FindEncodingFilename(int, PyObject *);
23

24 25 26 27 28
_Py_IDENTIFIER(TextIOWrapper);
_Py_IDENTIFIER(close);
_Py_IDENTIFIER(open);
_Py_IDENTIFIER(path);

29 30 31 32 33 34 35 36 37 38 39 40
static PyObject *
tb_dir(PyTracebackObject *self)
{
    return Py_BuildValue("[ssss]", "tb_frame", "tb_next",
                                   "tb_lasti", "tb_lineno");
}

static PyMethodDef tb_methods[] = {
   {"__dir__", (PyCFunction)tb_dir, METH_NOARGS},
   {NULL, NULL, 0, NULL},
};

41
static PyMemberDef tb_memberlist[] = {
42 43 44 45 46
    {"tb_next",         T_OBJECT,       OFF(tb_next),   READONLY},
    {"tb_frame",        T_OBJECT,       OFF(tb_frame),  READONLY},
    {"tb_lasti",        T_INT,          OFF(tb_lasti),  READONLY},
    {"tb_lineno",       T_INT,          OFF(tb_lineno), READONLY},
    {NULL}      /* Sentinel */
Guido van Rossum's avatar
Guido van Rossum committed
47 48 49
};

static void
50
tb_dealloc(PyTracebackObject *tb)
Guido van Rossum's avatar
Guido van Rossum committed
51
{
52 53 54 55 56 57
    PyObject_GC_UnTrack(tb);
    Py_TRASHCAN_SAFE_BEGIN(tb)
    Py_XDECREF(tb->tb_next);
    Py_XDECREF(tb->tb_frame);
    PyObject_GC_Del(tb);
    Py_TRASHCAN_SAFE_END(tb)
Guido van Rossum's avatar
Guido van Rossum committed
58 59
}

60
static int
61
tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
62
{
63 64 65
    Py_VISIT(tb->tb_next);
    Py_VISIT(tb->tb_frame);
    return 0;
66 67 68
}

static void
69
tb_clear(PyTracebackObject *tb)
70
{
71 72
    Py_CLEAR(tb->tb_next);
    Py_CLEAR(tb->tb_frame);
73 74
}

75
PyTypeObject PyTraceBack_Type = {
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "traceback",
    sizeof(PyTracebackObject),
    0,
    (destructor)tb_dealloc, /*tp_dealloc*/
    0,                  /*tp_print*/
    0,    /*tp_getattr*/
    0,                  /*tp_setattr*/
    0,                  /*tp_reserved*/
    0,                  /*tp_repr*/
    0,                  /*tp_as_number*/
    0,                  /*tp_as_sequence*/
    0,                  /*tp_as_mapping*/
    0,                  /* tp_hash */
    0,                  /* tp_call */
    0,                  /* tp_str */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    0,                  /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
    0,                                          /* tp_doc */
    (traverseproc)tb_traverse,                  /* tp_traverse */
    (inquiry)tb_clear,                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    tb_methods,         /* tp_methods */
    tb_memberlist,      /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
Guido van Rossum's avatar
Guido van Rossum committed
108 109
};

110 111
static PyTracebackObject *
newtracebackobject(PyTracebackObject *next, PyFrameObject *frame)
Guido van Rossum's avatar
Guido van Rossum committed
112
{
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
    PyTracebackObject *tb;
    if ((next != NULL && !PyTraceBack_Check(next)) ||
                    frame == NULL || !PyFrame_Check(frame)) {
        PyErr_BadInternalCall();
        return NULL;
    }
    tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
    if (tb != NULL) {
        Py_XINCREF(next);
        tb->tb_next = next;
        Py_XINCREF(frame);
        tb->tb_frame = frame;
        tb->tb_lasti = frame->f_lasti;
        tb->tb_lineno = PyFrame_GetLineNumber(frame);
        PyObject_GC_Track(tb);
    }
    return tb;
Guido van Rossum's avatar
Guido van Rossum committed
130 131 132
}

int
133
PyTraceBack_Here(PyFrameObject *frame)
Guido van Rossum's avatar
Guido van Rossum committed
134
{
135 136 137 138 139
    PyObject *exc, *val, *tb, *newtb;
    PyErr_Fetch(&exc, &val, &tb);
    newtb = (PyObject *)newtracebackobject((PyTracebackObject *)tb, frame);
    if (newtb == NULL) {
        _PyErr_ChainExceptions(exc, val, tb);
140
        return -1;
141 142 143
    }
    PyErr_Restore(exc, val, newtb);
    Py_XDECREF(tb);
144
    return 0;
Guido van Rossum's avatar
Guido van Rossum committed
145 146
}

147
/* Insert a frame into the traceback for (funcname, filename, lineno). */
148
void _PyTraceback_Add(const char *funcname, const char *filename, int lineno)
149
{
150 151 152 153
    PyObject *globals;
    PyCodeObject *code;
    PyFrameObject *frame;
    PyObject *exc, *val, *tb;
154 155 156 157

    /* Save and clear the current exception. Python functions must not be
       called with an exception set. Calling Python functions happens when
       the codec of the filesystem encoding is implemented in pure Python. */
158
    PyErr_Fetch(&exc, &val, &tb);
159 160 161

    globals = PyDict_New();
    if (!globals)
162
        goto error;
163
    code = PyCode_NewEmpty(filename, funcname, lineno);
164 165 166 167
    if (!code) {
        Py_DECREF(globals);
        goto error;
    }
168
    frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL);
169 170
    Py_DECREF(globals);
    Py_DECREF(code);
171
    if (!frame)
172
        goto error;
173 174
    frame->f_lineno = lineno;

175
    PyErr_Restore(exc, val, tb);
176
    PyTraceBack_Here(frame);
177 178
    Py_DECREF(frame);
    return;
179

180 181
error:
    _PyErr_ChainExceptions(exc, val, tb);
182 183
}

184 185
static PyObject *
_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
186
{
187 188
    Py_ssize_t i;
    PyObject *binary;
189
    PyObject *v;
190
    Py_ssize_t npath;
191 192
    size_t taillen;
    PyObject *syspath;
193
    PyObject *path;
194
    const char* tail;
195
    PyObject *filebytes;
196
    const char* filepath;
197
    Py_ssize_t len;
198
    PyObject* result;
199

200 201
    filebytes = PyUnicode_EncodeFSDefault(filename);
    if (filebytes == NULL) {
202 203 204
        PyErr_Clear();
        return NULL;
    }
205
    filepath = PyBytes_AS_STRING(filebytes);
206

207
    /* Search tail of filename in sys.path before giving up */
208
    tail = strrchr(filepath, SEP);
209
    if (tail == NULL)
210
        tail = filepath;
211 212 213 214
    else
        tail++;
    taillen = strlen(tail);

215
    syspath = _PySys_GetObjectId(&PyId_path);
216
    if (syspath == NULL || !PyList_Check(syspath))
217
        goto error;
218
    npath = PyList_Size(syspath);
219 220 221 222 223 224 225 226 227

    for (i = 0; i < npath; i++) {
        v = PyList_GetItem(syspath, i);
        if (v == NULL) {
            PyErr_Clear();
            break;
        }
        if (!PyUnicode_Check(v))
            continue;
228
        path = PyUnicode_EncodeFSDefault(v);
229 230 231 232
        if (path == NULL) {
            PyErr_Clear();
            continue;
        }
233 234 235
        len = PyBytes_GET_SIZE(path);
        if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) {
            Py_DECREF(path);
236
            continue; /* Too long */
237 238 239
        }
        strcpy(namebuf, PyBytes_AS_STRING(path));
        Py_DECREF(path);
240
        if (strlen(namebuf) != (size_t)len)
241 242 243 244
            continue; /* v contains '\0' */
        if (len > 0 && namebuf[len-1] != SEP)
            namebuf[len++] = SEP;
        strcpy(namebuf+len, tail);
245

246
        binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb");
247 248 249 250
        if (binary != NULL) {
            result = binary;
            goto finally;
        }
251
        PyErr_Clear();
252
    }
253 254 255 256 257 258 259
    goto error;

error:
    result = NULL;
finally:
    Py_DECREF(filebytes);
    return result;
260 261
}

Christian Heimes's avatar
Christian Heimes committed
262
int
263
_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
Guido van Rossum's avatar
Guido van Rossum committed
264
{
265 266 267 268 269
    int err = 0;
    int fd;
    int i;
    char *found_encoding;
    char *encoding;
270 271
    PyObject *io;
    PyObject *binary;
272 273
    PyObject *fob = NULL;
    PyObject *lineobj = NULL;
274
    PyObject *res;
275
    char buf[MAXPATHLEN+1];
Martin v. Löwis's avatar
Martin v. Löwis committed
276 277
    int kind;
    void *data;
278 279 280 281

    /* open the file */
    if (filename == NULL)
        return 0;
282 283 284 285

    io = PyImport_ImportModuleNoBlock("io");
    if (io == NULL)
        return -1;
286
    binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");
287 288

    if (binary == NULL) {
289 290
        PyErr_Clear();

291 292 293
        binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
        if (binary == NULL) {
            Py_DECREF(io);
294
            return -1;
295
        }
296 297 298
    }

    /* use the right encoding to decode the file as unicode */
299
    fd = PyObject_AsFileDescriptor(binary);
300 301 302
    if (fd < 0) {
        Py_DECREF(io);
        Py_DECREF(binary);
303
        return 0;
304
    }
305
    found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
306 307
    if (found_encoding == NULL)
        PyErr_Clear();
308
    encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
309 310 311 312 313
    /* Reset position */
    if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
        Py_DECREF(io);
        Py_DECREF(binary);
        PyMem_FREE(found_encoding);
314
        return 0;
315
    }
316
    fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
317
    Py_DECREF(io);
318
    PyMem_FREE(found_encoding);
319

320 321
    if (fob == NULL) {
        PyErr_Clear();
322

323
        res = _PyObject_CallMethodId(binary, &PyId_close, NULL);
324 325 326 327 328
        Py_DECREF(binary);
        if (res)
            Py_DECREF(res);
        else
            PyErr_Clear();
329 330
        return 0;
    }
331
    Py_DECREF(binary);
332 333 334 335 336 337

    /* get the line number lineno */
    for (i = 0; i < lineno; i++) {
        Py_XDECREF(lineobj);
        lineobj = PyFile_GetLine(fob, -1);
        if (!lineobj) {
338
            PyErr_Clear();
339 340 341 342
            err = -1;
            break;
        }
    }
343
    res = _PyObject_CallMethodId(fob, &PyId_close, NULL);
344 345 346 347
    if (res)
        Py_DECREF(res);
    else
        PyErr_Clear();
348 349 350 351 352 353 354
    Py_DECREF(fob);
    if (!lineobj || !PyUnicode_Check(lineobj)) {
        Py_XDECREF(lineobj);
        return err;
    }

    /* remove the indentation of the line */
Martin v. Löwis's avatar
Martin v. Löwis committed
355 356 357 358 359 360 361 362
    kind = PyUnicode_KIND(lineobj);
    data = PyUnicode_DATA(lineobj);
    for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) {
        Py_UCS4 ch = PyUnicode_READ(kind, data, i);
        if (ch != ' ' && ch != '\t' && ch != '\014')
            break;
    }
    if (i) {
363
        PyObject *truncated;
Martin v. Löwis's avatar
Martin v. Löwis committed
364
        truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
365 366 367 368 369 370 371 372 373 374 375 376
        if (truncated) {
            Py_DECREF(lineobj);
            lineobj = truncated;
        } else {
            PyErr_Clear();
        }
    }

    /* Write some spaces before the line */
    strcpy(buf, "          ");
    assert (strlen(buf) == 10);
    while (indent > 0) {
Benjamin Peterson's avatar
Benjamin Peterson committed
377
        if (indent < 10)
378 379 380 381 382 383 384 385 386 387 388 389 390 391
            buf[indent] = '\0';
        err = PyFile_WriteString(buf, f);
        if (err != 0)
            break;
        indent -= 10;
    }

    /* finally display the line */
    if (err == 0)
        err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
    Py_DECREF(lineobj);
    if  (err == 0)
        err = PyFile_WriteString("\n", f);
    return err;
Guido van Rossum's avatar
Guido van Rossum committed
392 393
}

394
static int
395
tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
Christian Heimes's avatar
Christian Heimes committed
396
{
397 398
    int err;
    PyObject *line;
Christian Heimes's avatar
Christian Heimes committed
399

400 401
    if (filename == NULL || name == NULL)
        return -1;
402 403 404 405 406 407
    line = PyUnicode_FromFormat("  File \"%U\", line %d, in %U\n",
                                filename, lineno, name);
    if (line == NULL)
        return -1;
    err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
    Py_DECREF(line);
408 409
    if (err != 0)
        return err;
410 411 412 413
    /* ignore errors since we can't report them, can we? */
    if (_Py_DisplaySourceLine(f, filename, lineno, 4))
        PyErr_Clear();
    return err;
Christian Heimes's avatar
Christian Heimes committed
414 415
}

416 417 418 419 420 421 422 423 424 425 426 427 428 429
static int
tb_print_line_repeated(PyObject *f, long cnt)
{
    int err;
    PyObject *line = PyUnicode_FromFormat(
            "  [Previous line repeated %ld more times]\n", cnt-3);
    if (line == NULL) {
        return -1;
    }
    err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
    Py_DECREF(line);
    return err;
}

Christian Heimes's avatar
Christian Heimes committed
430 431
static int
tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
Guido van Rossum's avatar
Guido van Rossum committed
432
{
433
    int err = 0;
434
    Py_ssize_t depth = 0;
435 436 437 438
    PyObject *last_file = NULL;
    int last_line = -1;
    PyObject *last_name = NULL;
    long cnt = 0;
439 440 441 442 443
    PyTracebackObject *tb1 = tb;
    while (tb1 != NULL) {
        depth++;
        tb1 = tb1->tb_next;
    }
444 445 446 447
    while (tb != NULL && depth > limit) {
        depth--;
        tb = tb->tb_next;
    }
448
    while (tb != NULL && err == 0) {
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
        if (last_file != NULL &&
            tb->tb_frame->f_code->co_filename == last_file &&
            last_line != -1 && tb->tb_lineno == last_line &&
            last_name != NULL && tb->tb_frame->f_code->co_name == last_name)
        {
            cnt++;
        }
        else {
            if (cnt > 3) {
                err = tb_print_line_repeated(f, cnt);
            }
            last_file = tb->tb_frame->f_code->co_filename;
            last_line = tb->tb_lineno;
            last_name = tb->tb_frame->f_code->co_name;
            cnt = 0;
        }
        if (err == 0 && cnt < 3) {
            err = tb_displayline(f,
                                 tb->tb_frame->f_code->co_filename,
                                 tb->tb_lineno,
                                 tb->tb_frame->f_code->co_name);
            if (err == 0) {
                err = PyErr_CheckSignals();
            }
473 474 475
        }
        tb = tb->tb_next;
    }
476 477
    if (err == 0 && cnt > 3) {
        err = tb_print_line_repeated(f, cnt);
478
    }
479
    return err;
Guido van Rossum's avatar
Guido van Rossum committed
480 481
}

482 483
#define PyTraceBack_LIMIT 1000

Guido van Rossum's avatar
Guido van Rossum committed
484
int
485
PyTraceBack_Print(PyObject *v, PyObject *f)
Guido van Rossum's avatar
Guido van Rossum committed
486
{
487 488 489 490 491 492 493 494 495 496 497
    int err;
    PyObject *limitv;
    long limit = PyTraceBack_LIMIT;

    if (v == NULL)
        return 0;
    if (!PyTraceBack_Check(v)) {
        PyErr_BadInternalCall();
        return -1;
    }
    limitv = PySys_GetObject("tracebacklimit");
498 499 500 501 502
    if (limitv && PyLong_Check(limitv)) {
        int overflow;
        limit = PyLong_AsLongAndOverflow(limitv, &overflow);
        if (overflow > 0) {
            limit = LONG_MAX;
503 504
        }
        else if (limit <= 0) {
505
            return 0;
506 507 508 509 510 511
        }
    }
    err = PyFile_WriteString("Traceback (most recent call last):\n", f);
    if (!err)
        err = tb_printinternal((PyTracebackObject *)v, f, limit);
    return err;
Guido van Rossum's avatar
Guido van Rossum committed
512
}
513 514 515 516 517

/* Reverse a string. For example, "abcd" becomes "dcba".

   This function is signal safe. */

518 519
void
_Py_DumpDecimal(int fd, unsigned long value)
520
{
521 522 523 524 525 526 527 528 529
    /* maximum number of characters required for output of %lld or %p.
       We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits,
       plus 1 for the null byte.  53/22 is an upper bound for log10(256). */
    char buffer[1 + (sizeof(unsigned long)*53-1) / 22 + 1];
    char *ptr, *end;

    end = &buffer[Py_ARRAY_LENGTH(buffer) - 1];
    ptr = end;
    *ptr = '\0';
530
    do {
531 532 533
        --ptr;
        assert(ptr >= buffer);
        *ptr = '0' + (value % 10);
534 535
        value /= 10;
    } while (value);
536 537

    _Py_write_noraise(fd, ptr, end - ptr);
538 539
}

540
/* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits,
541 542 543 544
   and write it into the file fd.

   This function is signal safe. */

545 546
void
_Py_DumpHexadecimal(int fd, unsigned long value, Py_ssize_t width)
547
{
548 549
    char buffer[sizeof(unsigned long) * 2 + 1], *ptr, *end;
    const Py_ssize_t size = Py_ARRAY_LENGTH(buffer) - 1;
550 551 552

    if (width > size)
        width = size;
553
    /* it's ok if width is negative */
554

555
    end = &buffer[size];
556 557
    ptr = end;
    *ptr = '\0';
558
    do {
559 560 561
        --ptr;
        assert(ptr >= buffer);
        *ptr = Py_hexdigits[value & 15];
562
        value >>= 4;
563
    } while ((end - ptr) < width || value);
564

565 566
    _Py_write_noraise(fd, ptr, end - ptr);
}
567

568 569
void
_Py_DumpASCII(int fd, PyObject *text)
570
{
Martin v. Löwis's avatar
Martin v. Löwis committed
571
    PyASCIIObject *ascii = (PyASCIIObject *)text;
572 573
    Py_ssize_t i, size;
    int truncated;
Martin v. Löwis's avatar
Martin v. Löwis committed
574
    int kind;
575 576
    void *data = NULL;
    wchar_t *wstr = NULL;
Martin v. Löwis's avatar
Martin v. Löwis committed
577 578
    Py_UCS4 ch;

579 580 581
    if (!PyUnicode_Check(text))
        return;

Martin v. Löwis's avatar
Martin v. Löwis committed
582 583
    size = ascii->length;
    kind = ascii->state.kind;
584 585 586 587 588 589 590
    if (kind == PyUnicode_WCHAR_KIND) {
        wstr = ((PyASCIIObject *)text)->wstr;
        if (wstr == NULL)
            return;
        size = ((PyCompactUnicodeObject *)text)->wstr_length;
    }
    else if (ascii->state.compact) {
Martin v. Löwis's avatar
Martin v. Löwis committed
591 592 593 594 595
        if (ascii->state.ascii)
            data = ((PyASCIIObject*)text) + 1;
        else
            data = ((PyCompactUnicodeObject*)text) + 1;
    }
596
    else {
Martin v. Löwis's avatar
Martin v. Löwis committed
597 598 599 600
        data = ((PyUnicodeObject *)text)->data.any;
        if (data == NULL)
            return;
    }
601 602 603 604 605

    if (MAX_STRING_LENGTH < size) {
        size = MAX_STRING_LENGTH;
        truncated = 1;
    }
606
    else {
607
        truncated = 0;
608
    }
609

Martin v. Löwis's avatar
Martin v. Löwis committed
610
    for (i=0; i < size; i++) {
611 612 613 614
        if (kind != PyUnicode_WCHAR_KIND)
            ch = PyUnicode_READ(kind, data, i);
        else
            ch = wstr[i];
615 616
        if (' ' <= ch && ch <= 126) {
            /* printable ASCII character */
Martin v. Löwis's avatar
Martin v. Löwis committed
617
            char c = (char)ch;
618
            _Py_write_noraise(fd, &c, 1);
619
        }
620
        else if (ch <= 0xff) {
621
            PUTS(fd, "\\x");
622
            _Py_DumpHexadecimal(fd, ch, 2);
623
        }
624
        else if (ch <= 0xffff) {
625
            PUTS(fd, "\\u");
626
            _Py_DumpHexadecimal(fd, ch, 4);
627 628 629
        }
        else {
            PUTS(fd, "\\U");
630
            _Py_DumpHexadecimal(fd, ch, 8);
631 632
        }
    }
633
    if (truncated) {
634
        PUTS(fd, "...");
635
    }
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
}

/* Write a frame into the file fd: "File "xxx", line xxx in xxx".

   This function is signal safe. */

static void
dump_frame(int fd, PyFrameObject *frame)
{
    PyCodeObject *code;
    int lineno;

    code = frame->f_code;
    PUTS(fd, "  File ");
    if (code != NULL && code->co_filename != NULL
        && PyUnicode_Check(code->co_filename))
    {
653
        PUTS(fd, "\"");
654
        _Py_DumpASCII(fd, code->co_filename);
655
        PUTS(fd, "\"");
656 657 658 659 660
    } else {
        PUTS(fd, "???");
    }

    /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
Martin v. Löwis's avatar
Martin v. Löwis committed
661
    lineno = PyCode_Addr2Line(code, frame->f_lasti);
662
    PUTS(fd, ", line ");
663 664 665 666 667 668
    if (lineno >= 0) {
        _Py_DumpDecimal(fd, (unsigned long)lineno);
    }
    else {
        PUTS(fd, "???");
    }
669 670 671
    PUTS(fd, " in ");

    if (code != NULL && code->co_name != NULL
672 673 674 675
       && PyUnicode_Check(code->co_name)) {
        _Py_DumpASCII(fd, code->co_name);
    }
    else {
676
        PUTS(fd, "???");
677
    }
678

679
    PUTS(fd, "\n");
680 681
}

682
static void
683 684 685 686 687
dump_traceback(int fd, PyThreadState *tstate, int write_header)
{
    PyFrameObject *frame;
    unsigned int depth;

688
    if (write_header)
689
        PUTS(fd, "Stack (most recent call first):\n");
690

691 692
    frame = _PyThreadState_GetFrame(tstate);
    if (frame == NULL)
693
        return;
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708

    depth = 0;
    while (frame != NULL) {
        if (MAX_FRAME_DEPTH <= depth) {
            PUTS(fd, "  ...\n");
            break;
        }
        if (!PyFrame_Check(frame))
            break;
        dump_frame(fd, frame);
        frame = frame->f_back;
        depth++;
    }
}

709 710 711 712 713 714
/* Dump the traceback of a Python thread into fd. Use write() to write the
   traceback and retry if write() is interrupted by a signal (failed with
   EINTR), but don't call the Python signal handler.

   The caller is responsible to call PyErr_CheckSignals() to call Python signal
   handlers if signals were received. */
715
void
716 717
_Py_DumpTraceback(int fd, PyThreadState *tstate)
{
718
    dump_traceback(fd, tstate, 1);
719 720 721 722 723 724 725 726 727 728 729 730 731 732
}

/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
   is_current is true, "Thread 0xHHHH:\n" otherwise.

   This function is signal safe. */

static void
write_thread_id(int fd, PyThreadState *tstate, int is_current)
{
    if (is_current)
        PUTS(fd, "Current thread 0x");
    else
        PUTS(fd, "Thread 0x");
733 734 735
    _Py_DumpHexadecimal(fd,
                        (unsigned long)tstate->thread_id,
                        sizeof(unsigned long) * 2);
736
    PUTS(fd, " (most recent call first):\n");
737 738
}

739 740 741 742 743 744
/* Dump the traceback of all Python threads into fd. Use write() to write the
   traceback and retry if write() is interrupted by a signal (failed with
   EINTR), but don't call the Python signal handler.

   The caller is responsible to call PyErr_CheckSignals() to call Python signal
   handlers if signals were received. */
745 746
const char*
_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
747
                         PyThreadState *current_tstate)
748 749 750 751
{
    PyThreadState *tstate;
    unsigned int nthreads;

752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
#ifdef WITH_THREAD
    if (current_tstate == NULL) {
        /* _Py_DumpTracebackThreads() is called from signal handlers by
           faulthandler.

           SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals
           and are thus delivered to the thread that caused the fault. Get the
           Python thread state of the current thread.

           PyThreadState_Get() doesn't give the state of the thread that caused
           the fault if the thread released the GIL, and so this function
           cannot be used. Read the thread local storage (TLS) instead: call
           PyGILState_GetThisThreadState(). */
        current_tstate = PyGILState_GetThisThreadState();
    }

    if (interp == NULL) {
        if (current_tstate == NULL) {
            interp = _PyGILState_GetInterpreterStateUnsafe();
            if (interp == NULL) {
                /* We need the interpreter state to get Python threads */
                return "unable to get the interpreter state";
            }
        }
        else {
            interp = current_tstate->interp;
        }
    }
#else
    if (current_tstate == NULL) {
        /* Call _PyThreadState_UncheckedGet() instead of PyThreadState_Get()
           to not fail with a fatal error if the thread state is NULL. */
784
        current_tstate = _PyThreadState_UncheckedGet();
785 786 787 788 789 790 791 792 793 794 795 796
    }

    if (interp == NULL) {
        if (current_tstate == NULL) {
            /* We need the interpreter state to get Python threads */
            return "unable to get the interpreter state";
        }
        interp = current_tstate->interp;
    }
#endif
    assert(interp != NULL);

797 798 799 800 801 802 803 804
    /* Get the current interpreter from the current thread */
    tstate = PyInterpreterState_ThreadHead(interp);
    if (tstate == NULL)
        return "unable to get the thread head state";

    /* Dump the traceback of each thread */
    tstate = PyInterpreterState_ThreadHead(interp);
    nthreads = 0;
805
    _Py_BEGIN_SUPPRESS_IPH
806 807 808
    do
    {
        if (nthreads != 0)
809
            PUTS(fd, "\n");
810 811 812 813
        if (nthreads >= MAX_NTHREADS) {
            PUTS(fd, "...\n");
            break;
        }
814
        write_thread_id(fd, tstate, tstate == current_tstate);
815 816 817 818
        dump_traceback(fd, tstate, 0);
        tstate = PyThreadState_Next(tstate);
        nthreads++;
    } while (tstate != NULL);
819
    _Py_END_SUPPRESS_IPH
820 821 822 823

    return NULL;
}