traceback.c 21.8 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"
5
#include "internal/pystate.h"
Guido van Rossum's avatar
Guido van Rossum committed
6

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

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

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

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

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

30 31 32 33 34 35 36 37 38 39 40 41
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},
};

42
static PyMemberDef tb_memberlist[] = {
43 44 45 46 47
    {"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
48 49 50
};

static void
51
tb_dealloc(PyTracebackObject *tb)
Guido van Rossum's avatar
Guido van Rossum committed
52
{
53 54 55 56 57 58
    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
59 60
}

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

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

76
PyTypeObject PyTraceBack_Type = {
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 108
    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
109 110
};

111 112
static PyTracebackObject *
newtracebackobject(PyTracebackObject *next, PyFrameObject *frame)
Guido van Rossum's avatar
Guido van Rossum committed
113
{
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    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
131 132 133
}

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

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

    /* 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. */
159
    PyErr_Fetch(&exc, &val, &tb);
160 161 162

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /* get the line number lineno */
    for (i = 0; i < lineno; i++) {
        Py_XDECREF(lineobj);
        lineobj = PyFile_GetLine(fob, -1);
        if (!lineobj) {
339
            PyErr_Clear();
340 341 342 343
            err = -1;
            break;
        }
    }
344
    res = _PyObject_CallMethodId(fob, &PyId_close, NULL);
345 346 347 348
    if (res)
        Py_DECREF(res);
    else
        PyErr_Clear();
349 350 351 352 353 354 355
    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
356 357 358 359 360 361 362 363
    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) {
364
        PyObject *truncated;
Martin v. Löwis's avatar
Martin v. Löwis committed
365
        truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
366 367 368 369 370 371 372 373 374 375 376 377
        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
378
        if (indent < 10)
379 380 381 382 383 384 385 386 387 388 389 390 391 392
            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
393 394
}

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

401 402
    if (filename == NULL || name == NULL)
        return -1;
403 404 405 406 407 408
    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);
409 410
    if (err != 0)
        return err;
411 412 413 414
    /* 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
415 416 417 418
}

static int
tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
Guido van Rossum's avatar
Guido van Rossum committed
419
{
420 421
    int err = 0;
    long depth = 0;
422 423 424 425 426
    PyObject *last_file = NULL;
    int last_line = -1;
    PyObject *last_name = NULL;
    long cnt = 0;
    PyObject *line;
427 428 429 430 431 432 433
    PyTracebackObject *tb1 = tb;
    while (tb1 != NULL) {
        depth++;
        tb1 = tb1->tb_next;
    }
    while (tb != NULL && err == 0) {
        if (depth <= limit) {
434 435 436 437 438 439 440 441 442 443 444
            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) {
                        line = PyUnicode_FromFormat(
                        "  [Previous line repeated %d more times]\n", cnt-3);
                        err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
445
                        Py_DECREF(line);
446 447 448 449 450 451 452 453 454 455 456
                    }
                    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 (cnt < 3)
                err = tb_displayline(f,
                                     tb->tb_frame->f_code->co_filename,
                                     tb->tb_lineno,
                                     tb->tb_frame->f_code->co_name);
457 458 459 460 461 462
        }
        depth--;
        tb = tb->tb_next;
        if (err == 0)
            err = PyErr_CheckSignals();
    }
463 464 465 466
    if (cnt > 3) {
        line = PyUnicode_FromFormat(
        "  [Previous line repeated %d more times]\n", cnt-3);
        err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
467
        Py_DECREF(line);
468
    }
469
    return err;
Guido van Rossum's avatar
Guido van Rossum committed
470 471
}

472 473
#define PyTraceBack_LIMIT 1000

Guido van Rossum's avatar
Guido van Rossum committed
474
int
475
PyTraceBack_Print(PyObject *v, PyObject *f)
Guido van Rossum's avatar
Guido van Rossum committed
476
{
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
    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");
    if (limitv) {
        PyObject *exc_type, *exc_value, *exc_tb;

        PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
        limit = PyLong_AsLong(limitv);
        if (limit == -1 && PyErr_Occurred()) {
            if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
                limit = PyTraceBack_LIMIT;
            }
            else {
                Py_XDECREF(exc_type);
                Py_XDECREF(exc_value);
                Py_XDECREF(exc_tb);
                return 0;
            }
        }
        else if (limit <= 0) {
            limit = PyTraceBack_LIMIT;
        }
        PyErr_Restore(exc_type, exc_value, exc_tb);
    }
    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
513
}
514 515 516 517 518

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

   This function is signal safe. */

519 520
void
_Py_DumpDecimal(int fd, unsigned long value)
521
{
522 523 524 525 526 527 528 529 530
    /* 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';
531
    do {
532 533 534
        --ptr;
        assert(ptr >= buffer);
        *ptr = '0' + (value % 10);
535 536
        value /= 10;
    } while (value);
537 538

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

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

   This function is signal safe. */

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

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

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

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

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

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

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

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

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

/* 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))
    {
654
        PUTS(fd, "\"");
655
        _Py_DumpASCII(fd, code->co_filename);
656
        PUTS(fd, "\"");
657 658 659 660 661
    } 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
662
    lineno = PyCode_Addr2Line(code, frame->f_lasti);
663
    PUTS(fd, ", line ");
664 665 666 667 668 669
    if (lineno >= 0) {
        _Py_DumpDecimal(fd, (unsigned long)lineno);
    }
    else {
        PUTS(fd, "???");
    }
670 671 672
    PUTS(fd, " in ");

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

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

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

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

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

    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++;
    }
}

710 711 712 713 714 715
/* 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. */
716
void
717 718
_Py_DumpTraceback(int fd, PyThreadState *tstate)
{
719
    dump_traceback(fd, tstate, 1);
720 721 722 723 724 725 726 727 728 729 730 731 732 733
}

/* 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");
734
    _Py_DumpHexadecimal(fd,
735
                        tstate->thread_id,
736
                        sizeof(unsigned long) * 2);
737
    PUTS(fd, " (most recent call first):\n");
738 739
}

740 741 742 743 744 745
/* 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. */
746 747
const char*
_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
748
                         PyThreadState *current_tstate)
749 750 751 752
{
    PyThreadState *tstate;
    unsigned int nthreads;

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
    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;
        }
    }
    assert(interp != NULL);

782 783 784 785 786 787 788 789
    /* 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;
790
    _Py_BEGIN_SUPPRESS_IPH
791 792 793
    do
    {
        if (nthreads != 0)
794
            PUTS(fd, "\n");
795 796 797 798
        if (nthreads >= MAX_NTHREADS) {
            PUTS(fd, "...\n");
            break;
        }
799
        write_thread_id(fd, tstate, tstate == current_tstate);
800 801 802 803
        dump_traceback(fd, tstate, 0);
        tstate = PyThreadState_Next(tstate);
        nthreads++;
    } while (tstate != NULL);
804
    _Py_END_SUPPRESS_IPH
805 806 807 808

    return NULL;
}