traceback.c 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451
  1. /* Traceback implementation */
  2. #include "Python.h"
  3. #include "pycore_ast.h" // asdl_seq_*
  4. #include "pycore_call.h" // _PyObject_CallMethodFormat()
  5. #include "pycore_compile.h" // _PyAST_Optimize
  6. #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH
  7. #include "pycore_frame.h" // _PyFrame_GetCode()
  8. #include "pycore_interp.h" // PyInterpreterState.gc
  9. #include "pycore_parser.h" // _PyParser_ASTFromString
  10. #include "pycore_pyarena.h" // _PyArena_Free()
  11. #include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
  12. #include "pycore_pystate.h" // _PyThreadState_GET()
  13. #include "pycore_traceback.h" // EXCEPTION_TB_HEADER
  14. #include "../Parser/pegen.h" // _PyPegen_byte_offset_to_character_offset()
  15. #include "frameobject.h" // PyFrame_New()
  16. #include "structmember.h" // PyMemberDef
  17. #include "osdefs.h" // SEP
  18. #ifdef HAVE_FCNTL_H
  19. # include <fcntl.h>
  20. #endif
  21. #define OFF(x) offsetof(PyTracebackObject, x)
  22. #define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str))
  23. #define MAX_STRING_LENGTH 500
  24. #define MAX_FRAME_DEPTH 100
  25. #define MAX_NTHREADS 100
  26. /* Function from Parser/tokenizer.c */
  27. extern char* _PyTokenizer_FindEncodingFilename(int, PyObject *);
  28. /*[clinic input]
  29. class TracebackType "PyTracebackObject *" "&PyTraceback_Type"
  30. [clinic start generated code]*/
  31. /*[clinic end generated code: output=da39a3ee5e6b4b0d input=928fa06c10151120]*/
  32. #include "clinic/traceback.c.h"
  33. static PyObject *
  34. tb_create_raw(PyTracebackObject *next, PyFrameObject *frame, int lasti,
  35. int lineno)
  36. {
  37. PyTracebackObject *tb;
  38. if ((next != NULL && !PyTraceBack_Check(next)) ||
  39. frame == NULL || !PyFrame_Check(frame)) {
  40. PyErr_BadInternalCall();
  41. return NULL;
  42. }
  43. tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
  44. if (tb != NULL) {
  45. tb->tb_next = (PyTracebackObject*)Py_XNewRef(next);
  46. tb->tb_frame = (PyFrameObject*)Py_XNewRef(frame);
  47. tb->tb_lasti = lasti;
  48. tb->tb_lineno = lineno;
  49. PyObject_GC_Track(tb);
  50. }
  51. return (PyObject *)tb;
  52. }
  53. /*[clinic input]
  54. @classmethod
  55. TracebackType.__new__ as tb_new
  56. tb_next: object
  57. tb_frame: object(type='PyFrameObject *', subclass_of='&PyFrame_Type')
  58. tb_lasti: int
  59. tb_lineno: int
  60. Create a new traceback object.
  61. [clinic start generated code]*/
  62. static PyObject *
  63. tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame,
  64. int tb_lasti, int tb_lineno)
  65. /*[clinic end generated code: output=fa077debd72d861a input=01cbe8ec8783fca7]*/
  66. {
  67. if (tb_next == Py_None) {
  68. tb_next = NULL;
  69. } else if (!PyTraceBack_Check(tb_next)) {
  70. return PyErr_Format(PyExc_TypeError,
  71. "expected traceback object or None, got '%s'",
  72. Py_TYPE(tb_next)->tp_name);
  73. }
  74. return tb_create_raw((PyTracebackObject *)tb_next, tb_frame, tb_lasti,
  75. tb_lineno);
  76. }
  77. static PyObject *
  78. tb_dir(PyTracebackObject *self, PyObject *Py_UNUSED(ignored))
  79. {
  80. return Py_BuildValue("[ssss]", "tb_frame", "tb_next",
  81. "tb_lasti", "tb_lineno");
  82. }
  83. static PyObject *
  84. tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_))
  85. {
  86. PyObject* ret = (PyObject*)self->tb_next;
  87. if (!ret) {
  88. ret = Py_None;
  89. }
  90. return Py_NewRef(ret);
  91. }
  92. static int
  93. tb_get_lineno(PyTracebackObject* tb) {
  94. PyFrameObject* frame = tb->tb_frame;
  95. assert(frame != NULL);
  96. PyCodeObject *code = PyFrame_GetCode(frame);
  97. int lineno = PyCode_Addr2Line(code, tb->tb_lasti);
  98. Py_DECREF(code);
  99. return lineno;
  100. }
  101. static PyObject *
  102. tb_lineno_get(PyTracebackObject *self, void *Py_UNUSED(_))
  103. {
  104. int lineno = self->tb_lineno;
  105. if (lineno == -1) {
  106. lineno = tb_get_lineno(self);
  107. if (lineno < 0) {
  108. Py_RETURN_NONE;
  109. }
  110. }
  111. return PyLong_FromLong(lineno);
  112. }
  113. static int
  114. tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_))
  115. {
  116. if (!new_next) {
  117. PyErr_Format(PyExc_TypeError, "can't delete tb_next attribute");
  118. return -1;
  119. }
  120. /* We accept None or a traceback object, and map None -> NULL (inverse of
  121. tb_next_get) */
  122. if (new_next == Py_None) {
  123. new_next = NULL;
  124. } else if (!PyTraceBack_Check(new_next)) {
  125. PyErr_Format(PyExc_TypeError,
  126. "expected traceback object, got '%s'",
  127. Py_TYPE(new_next)->tp_name);
  128. return -1;
  129. }
  130. /* Check for loops */
  131. PyTracebackObject *cursor = (PyTracebackObject *)new_next;
  132. while (cursor) {
  133. if (cursor == self) {
  134. PyErr_Format(PyExc_ValueError, "traceback loop detected");
  135. return -1;
  136. }
  137. cursor = cursor->tb_next;
  138. }
  139. Py_XSETREF(self->tb_next, (PyTracebackObject *)Py_XNewRef(new_next));
  140. return 0;
  141. }
  142. static PyMethodDef tb_methods[] = {
  143. {"__dir__", _PyCFunction_CAST(tb_dir), METH_NOARGS},
  144. {NULL, NULL, 0, NULL},
  145. };
  146. static PyMemberDef tb_memberlist[] = {
  147. {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|PY_AUDIT_READ},
  148. {"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
  149. {NULL} /* Sentinel */
  150. };
  151. static PyGetSetDef tb_getsetters[] = {
  152. {"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL},
  153. {"tb_lineno", (getter)tb_lineno_get, NULL, NULL, NULL},
  154. {NULL} /* Sentinel */
  155. };
  156. static void
  157. tb_dealloc(PyTracebackObject *tb)
  158. {
  159. PyObject_GC_UnTrack(tb);
  160. Py_TRASHCAN_BEGIN(tb, tb_dealloc)
  161. Py_XDECREF(tb->tb_next);
  162. Py_XDECREF(tb->tb_frame);
  163. PyObject_GC_Del(tb);
  164. Py_TRASHCAN_END
  165. }
  166. static int
  167. tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
  168. {
  169. Py_VISIT(tb->tb_next);
  170. Py_VISIT(tb->tb_frame);
  171. return 0;
  172. }
  173. static int
  174. tb_clear(PyTracebackObject *tb)
  175. {
  176. Py_CLEAR(tb->tb_next);
  177. Py_CLEAR(tb->tb_frame);
  178. return 0;
  179. }
  180. PyTypeObject PyTraceBack_Type = {
  181. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  182. "traceback",
  183. sizeof(PyTracebackObject),
  184. 0,
  185. (destructor)tb_dealloc, /*tp_dealloc*/
  186. 0, /*tp_vectorcall_offset*/
  187. 0, /*tp_getattr*/
  188. 0, /*tp_setattr*/
  189. 0, /*tp_as_async*/
  190. 0, /*tp_repr*/
  191. 0, /*tp_as_number*/
  192. 0, /*tp_as_sequence*/
  193. 0, /*tp_as_mapping*/
  194. 0, /* tp_hash */
  195. 0, /* tp_call */
  196. 0, /* tp_str */
  197. PyObject_GenericGetAttr, /* tp_getattro */
  198. 0, /* tp_setattro */
  199. 0, /* tp_as_buffer */
  200. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
  201. tb_new__doc__, /* tp_doc */
  202. (traverseproc)tb_traverse, /* tp_traverse */
  203. (inquiry)tb_clear, /* tp_clear */
  204. 0, /* tp_richcompare */
  205. 0, /* tp_weaklistoffset */
  206. 0, /* tp_iter */
  207. 0, /* tp_iternext */
  208. tb_methods, /* tp_methods */
  209. tb_memberlist, /* tp_members */
  210. tb_getsetters, /* tp_getset */
  211. 0, /* tp_base */
  212. 0, /* tp_dict */
  213. 0, /* tp_descr_get */
  214. 0, /* tp_descr_set */
  215. 0, /* tp_dictoffset */
  216. 0, /* tp_init */
  217. 0, /* tp_alloc */
  218. tb_new, /* tp_new */
  219. };
  220. PyObject*
  221. _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
  222. {
  223. assert(tb_next == NULL || PyTraceBack_Check(tb_next));
  224. assert(frame != NULL);
  225. int addr = _PyInterpreterFrame_LASTI(frame->f_frame) * sizeof(_Py_CODEUNIT);
  226. return tb_create_raw((PyTracebackObject *)tb_next, frame, addr, -1);
  227. }
  228. int
  229. PyTraceBack_Here(PyFrameObject *frame)
  230. {
  231. PyObject *exc = PyErr_GetRaisedException();
  232. assert(PyExceptionInstance_Check(exc));
  233. PyObject *tb = PyException_GetTraceback(exc);
  234. PyObject *newtb = _PyTraceBack_FromFrame(tb, frame);
  235. Py_XDECREF(tb);
  236. if (newtb == NULL) {
  237. _PyErr_ChainExceptions1(exc);
  238. return -1;
  239. }
  240. PyException_SetTraceback(exc, newtb);
  241. Py_XDECREF(newtb);
  242. PyErr_SetRaisedException(exc);
  243. return 0;
  244. }
  245. /* Insert a frame into the traceback for (funcname, filename, lineno). */
  246. void _PyTraceback_Add(const char *funcname, const char *filename, int lineno)
  247. {
  248. PyObject *globals;
  249. PyCodeObject *code;
  250. PyFrameObject *frame;
  251. PyThreadState *tstate = _PyThreadState_GET();
  252. /* Save and clear the current exception. Python functions must not be
  253. called with an exception set. Calling Python functions happens when
  254. the codec of the filesystem encoding is implemented in pure Python. */
  255. PyObject *exc = _PyErr_GetRaisedException(tstate);
  256. globals = PyDict_New();
  257. if (!globals)
  258. goto error;
  259. code = PyCode_NewEmpty(filename, funcname, lineno);
  260. if (!code) {
  261. Py_DECREF(globals);
  262. goto error;
  263. }
  264. frame = PyFrame_New(tstate, code, globals, NULL);
  265. Py_DECREF(globals);
  266. Py_DECREF(code);
  267. if (!frame)
  268. goto error;
  269. frame->f_lineno = lineno;
  270. _PyErr_SetRaisedException(tstate, exc);
  271. PyTraceBack_Here(frame);
  272. Py_DECREF(frame);
  273. return;
  274. error:
  275. _PyErr_ChainExceptions1(exc);
  276. }
  277. static PyObject *
  278. _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
  279. {
  280. Py_ssize_t i;
  281. PyObject *binary;
  282. PyObject *v;
  283. Py_ssize_t npath;
  284. size_t taillen;
  285. PyObject *syspath;
  286. PyObject *path;
  287. const char* tail;
  288. PyObject *filebytes;
  289. const char* filepath;
  290. Py_ssize_t len;
  291. PyObject* result;
  292. PyObject *open = NULL;
  293. filebytes = PyUnicode_EncodeFSDefault(filename);
  294. if (filebytes == NULL) {
  295. PyErr_Clear();
  296. return NULL;
  297. }
  298. filepath = PyBytes_AS_STRING(filebytes);
  299. /* Search tail of filename in sys.path before giving up */
  300. tail = strrchr(filepath, SEP);
  301. if (tail == NULL)
  302. tail = filepath;
  303. else
  304. tail++;
  305. taillen = strlen(tail);
  306. PyThreadState *tstate = _PyThreadState_GET();
  307. syspath = _PySys_GetAttr(tstate, &_Py_ID(path));
  308. if (syspath == NULL || !PyList_Check(syspath))
  309. goto error;
  310. npath = PyList_Size(syspath);
  311. open = PyObject_GetAttr(io, &_Py_ID(open));
  312. for (i = 0; i < npath; i++) {
  313. v = PyList_GetItem(syspath, i);
  314. if (v == NULL) {
  315. PyErr_Clear();
  316. break;
  317. }
  318. if (!PyUnicode_Check(v))
  319. continue;
  320. path = PyUnicode_EncodeFSDefault(v);
  321. if (path == NULL) {
  322. PyErr_Clear();
  323. continue;
  324. }
  325. len = PyBytes_GET_SIZE(path);
  326. if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) {
  327. Py_DECREF(path);
  328. continue; /* Too long */
  329. }
  330. strcpy(namebuf, PyBytes_AS_STRING(path));
  331. Py_DECREF(path);
  332. if (strlen(namebuf) != (size_t)len)
  333. continue; /* v contains '\0' */
  334. if (len > 0 && namebuf[len-1] != SEP)
  335. namebuf[len++] = SEP;
  336. strcpy(namebuf+len, tail);
  337. binary = _PyObject_CallMethodFormat(tstate, open, "ss", namebuf, "rb");
  338. if (binary != NULL) {
  339. result = binary;
  340. goto finally;
  341. }
  342. PyErr_Clear();
  343. }
  344. goto error;
  345. error:
  346. result = NULL;
  347. finally:
  348. Py_XDECREF(open);
  349. Py_DECREF(filebytes);
  350. return result;
  351. }
  352. /* Writes indent spaces. Returns 0 on success and non-zero on failure.
  353. */
  354. int
  355. _Py_WriteIndent(int indent, PyObject *f)
  356. {
  357. char buf[11] = " ";
  358. assert(strlen(buf) == 10);
  359. while (indent > 0) {
  360. if (indent < 10) {
  361. buf[indent] = '\0';
  362. }
  363. if (PyFile_WriteString(buf, f) < 0) {
  364. return -1;
  365. }
  366. indent -= 10;
  367. }
  368. return 0;
  369. }
  370. /* Writes indent spaces, followed by the margin if it is not `\0`.
  371. Returns 0 on success and non-zero on failure.
  372. */
  373. int
  374. _Py_WriteIndentedMargin(int indent, const char *margin, PyObject *f)
  375. {
  376. if (_Py_WriteIndent(indent, f) < 0) {
  377. return -1;
  378. }
  379. if (margin) {
  380. if (PyFile_WriteString(margin, f) < 0) {
  381. return -1;
  382. }
  383. }
  384. return 0;
  385. }
  386. static int
  387. display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int indent,
  388. int margin_indent, const char *margin,
  389. int *truncation, PyObject **line)
  390. {
  391. int fd;
  392. int i;
  393. char *found_encoding;
  394. const char *encoding;
  395. PyObject *io;
  396. PyObject *binary;
  397. PyObject *fob = NULL;
  398. PyObject *lineobj = NULL;
  399. PyObject *res;
  400. char buf[MAXPATHLEN+1];
  401. int kind;
  402. const void *data;
  403. /* open the file */
  404. if (filename == NULL)
  405. return 0;
  406. /* Do not attempt to open things like <string> or <stdin> */
  407. assert(PyUnicode_Check(filename));
  408. if (PyUnicode_READ_CHAR(filename, 0) == '<') {
  409. Py_ssize_t len = PyUnicode_GET_LENGTH(filename);
  410. if (len > 0 && PyUnicode_READ_CHAR(filename, len - 1) == '>') {
  411. return 0;
  412. }
  413. }
  414. io = PyImport_ImportModule("io");
  415. if (io == NULL) {
  416. return -1;
  417. }
  418. binary = _PyObject_CallMethod(io, &_Py_ID(open), "Os", filename, "rb");
  419. if (binary == NULL) {
  420. PyErr_Clear();
  421. binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
  422. if (binary == NULL) {
  423. Py_DECREF(io);
  424. return -1;
  425. }
  426. }
  427. /* use the right encoding to decode the file as unicode */
  428. fd = PyObject_AsFileDescriptor(binary);
  429. if (fd < 0) {
  430. Py_DECREF(io);
  431. Py_DECREF(binary);
  432. return 0;
  433. }
  434. found_encoding = _PyTokenizer_FindEncodingFilename(fd, filename);
  435. if (found_encoding == NULL)
  436. PyErr_Clear();
  437. encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
  438. /* Reset position */
  439. if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
  440. Py_DECREF(io);
  441. Py_DECREF(binary);
  442. PyMem_Free(found_encoding);
  443. return 0;
  444. }
  445. fob = _PyObject_CallMethod(io, &_Py_ID(TextIOWrapper),
  446. "Os", binary, encoding);
  447. Py_DECREF(io);
  448. PyMem_Free(found_encoding);
  449. if (fob == NULL) {
  450. PyErr_Clear();
  451. res = PyObject_CallMethodNoArgs(binary, &_Py_ID(close));
  452. Py_DECREF(binary);
  453. if (res)
  454. Py_DECREF(res);
  455. else
  456. PyErr_Clear();
  457. return 0;
  458. }
  459. Py_DECREF(binary);
  460. /* get the line number lineno */
  461. for (i = 0; i < lineno; i++) {
  462. Py_XDECREF(lineobj);
  463. lineobj = PyFile_GetLine(fob, -1);
  464. if (!lineobj) {
  465. PyErr_Clear();
  466. break;
  467. }
  468. }
  469. res = PyObject_CallMethodNoArgs(fob, &_Py_ID(close));
  470. if (res) {
  471. Py_DECREF(res);
  472. }
  473. else {
  474. PyErr_Clear();
  475. }
  476. Py_DECREF(fob);
  477. if (!lineobj || !PyUnicode_Check(lineobj)) {
  478. Py_XDECREF(lineobj);
  479. return -1;
  480. }
  481. if (line) {
  482. *line = Py_NewRef(lineobj);
  483. }
  484. /* remove the indentation of the line */
  485. kind = PyUnicode_KIND(lineobj);
  486. data = PyUnicode_DATA(lineobj);
  487. for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) {
  488. Py_UCS4 ch = PyUnicode_READ(kind, data, i);
  489. if (ch != ' ' && ch != '\t' && ch != '\014')
  490. break;
  491. }
  492. if (i) {
  493. PyObject *truncated;
  494. truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
  495. if (truncated) {
  496. Py_SETREF(lineobj, truncated);
  497. } else {
  498. PyErr_Clear();
  499. }
  500. }
  501. if (truncation != NULL) {
  502. *truncation = i - indent;
  503. }
  504. if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) {
  505. goto error;
  506. }
  507. /* Write some spaces before the line */
  508. if (_Py_WriteIndent(indent, f) < 0) {
  509. goto error;
  510. }
  511. /* finally display the line */
  512. if (PyFile_WriteObject(lineobj, f, Py_PRINT_RAW) < 0) {
  513. goto error;
  514. }
  515. if (PyFile_WriteString("\n", f) < 0) {
  516. goto error;
  517. }
  518. Py_DECREF(lineobj);
  519. return 0;
  520. error:
  521. Py_DECREF(lineobj);
  522. return -1;
  523. }
  524. int
  525. _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent,
  526. int *truncation, PyObject **line)
  527. {
  528. return display_source_line_with_margin(f, filename, lineno, indent, 0,
  529. NULL, truncation, line);
  530. }
  531. /* AST based Traceback Specialization
  532. *
  533. * When displaying a new traceback line, for certain syntactical constructs
  534. * (e.g a subscript, an arithmetic operation) we try to create a representation
  535. * that separates the primary source of error from the rest.
  536. *
  537. * Example specialization of BinOp nodes:
  538. * Traceback (most recent call last):
  539. * File "/home/isidentical/cpython/cpython/t.py", line 10, in <module>
  540. * add_values(1, 2, 'x', 3, 4)
  541. * File "/home/isidentical/cpython/cpython/t.py", line 2, in add_values
  542. * return a + b + c + d + e
  543. * ~~~~~~^~~
  544. * TypeError: 'NoneType' object is not subscriptable
  545. */
  546. #define IS_WHITESPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\f'))
  547. static int
  548. extract_anchors_from_expr(const char *segment_str, expr_ty expr, Py_ssize_t *left_anchor, Py_ssize_t *right_anchor,
  549. char** primary_error_char, char** secondary_error_char)
  550. {
  551. switch (expr->kind) {
  552. case BinOp_kind: {
  553. expr_ty left = expr->v.BinOp.left;
  554. expr_ty right = expr->v.BinOp.right;
  555. for (int i = left->end_col_offset; i < right->col_offset; i++) {
  556. if (IS_WHITESPACE(segment_str[i])) {
  557. continue;
  558. }
  559. *left_anchor = i;
  560. *right_anchor = i + 1;
  561. // Check whether if this a two-character operator (e.g //)
  562. if (i + 1 < right->col_offset && !IS_WHITESPACE(segment_str[i + 1])) {
  563. ++*right_anchor;
  564. }
  565. // Keep going if the current char is not ')'
  566. if (i+1 < right->col_offset && (segment_str[i] == ')')) {
  567. continue;
  568. }
  569. // Set the error characters
  570. *primary_error_char = "~";
  571. *secondary_error_char = "^";
  572. break;
  573. }
  574. return 1;
  575. }
  576. case Subscript_kind: {
  577. *left_anchor = expr->v.Subscript.value->end_col_offset;
  578. *right_anchor = expr->v.Subscript.slice->end_col_offset + 1;
  579. Py_ssize_t str_len = strlen(segment_str);
  580. // Move right_anchor and left_anchor forward to the first non-whitespace character that is not ']' and '['
  581. while (*left_anchor < str_len && (IS_WHITESPACE(segment_str[*left_anchor]) || segment_str[*left_anchor] != '[')) {
  582. ++*left_anchor;
  583. }
  584. while (*right_anchor < str_len && (IS_WHITESPACE(segment_str[*right_anchor]) || segment_str[*right_anchor] != ']')) {
  585. ++*right_anchor;
  586. }
  587. if (*right_anchor < str_len){
  588. *right_anchor += 1;
  589. }
  590. // Set the error characters
  591. *primary_error_char = "~";
  592. *secondary_error_char = "^";
  593. return 1;
  594. }
  595. default:
  596. return 0;
  597. }
  598. }
  599. static int
  600. extract_anchors_from_stmt(const char *segment_str, stmt_ty statement, Py_ssize_t *left_anchor, Py_ssize_t *right_anchor,
  601. char** primary_error_char, char** secondary_error_char)
  602. {
  603. switch (statement->kind) {
  604. case Expr_kind: {
  605. return extract_anchors_from_expr(segment_str, statement->v.Expr.value, left_anchor, right_anchor,
  606. primary_error_char, secondary_error_char);
  607. }
  608. default:
  609. return 0;
  610. }
  611. }
  612. static int
  613. extract_anchors_from_line(PyObject *filename, PyObject *line,
  614. Py_ssize_t start_offset, Py_ssize_t end_offset,
  615. Py_ssize_t *left_anchor, Py_ssize_t *right_anchor,
  616. char** primary_error_char, char** secondary_error_char)
  617. {
  618. int res = -1;
  619. PyArena *arena = NULL;
  620. PyObject *segment = PyUnicode_Substring(line, start_offset, end_offset);
  621. if (!segment) {
  622. goto done;
  623. }
  624. const char *segment_str = PyUnicode_AsUTF8(segment);
  625. if (!segment_str) {
  626. goto done;
  627. }
  628. arena = _PyArena_New();
  629. if (!arena) {
  630. goto done;
  631. }
  632. PyCompilerFlags flags = _PyCompilerFlags_INIT;
  633. _PyASTOptimizeState state;
  634. state.optimize = _Py_GetConfig()->optimization_level;
  635. state.ff_features = 0;
  636. mod_ty module = _PyParser_ASTFromString(segment_str, filename, Py_file_input,
  637. &flags, arena);
  638. if (!module) {
  639. goto done;
  640. }
  641. if (!_PyAST_Optimize(module, arena, &state)) {
  642. goto done;
  643. }
  644. assert(module->kind == Module_kind);
  645. if (asdl_seq_LEN(module->v.Module.body) == 1) {
  646. stmt_ty statement = asdl_seq_GET(module->v.Module.body, 0);
  647. res = extract_anchors_from_stmt(segment_str, statement, left_anchor, right_anchor,
  648. primary_error_char, secondary_error_char);
  649. } else {
  650. res = 0;
  651. }
  652. done:
  653. if (res > 0) {
  654. // Normalize the AST offsets to byte offsets and adjust them with the
  655. // start of the actual line (instead of the source code segment).
  656. assert(segment != NULL);
  657. assert(*left_anchor >= 0);
  658. assert(*right_anchor >= 0);
  659. *left_anchor = _PyPegen_byte_offset_to_character_offset(segment, *left_anchor) + start_offset;
  660. *right_anchor = _PyPegen_byte_offset_to_character_offset(segment, *right_anchor) + start_offset;
  661. }
  662. Py_XDECREF(segment);
  663. if (arena) {
  664. _PyArena_Free(arena);
  665. }
  666. return res;
  667. }
  668. #define _TRACEBACK_SOURCE_LINE_INDENT 4
  669. static inline int
  670. ignore_source_errors(void) {
  671. if (PyErr_Occurred()) {
  672. if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) {
  673. return -1;
  674. }
  675. PyErr_Clear();
  676. }
  677. return 0;
  678. }
  679. static inline int
  680. print_error_location_carets(PyObject *f, int offset, Py_ssize_t start_offset, Py_ssize_t end_offset,
  681. Py_ssize_t right_start_offset, Py_ssize_t left_end_offset,
  682. const char *primary, const char *secondary) {
  683. int special_chars = (left_end_offset != -1 || right_start_offset != -1);
  684. const char *str;
  685. while (++offset <= end_offset) {
  686. if (offset <= start_offset) {
  687. str = " ";
  688. } else if (special_chars && left_end_offset < offset && offset <= right_start_offset) {
  689. str = secondary;
  690. } else {
  691. str = primary;
  692. }
  693. if (PyFile_WriteString(str, f) < 0) {
  694. return -1;
  695. }
  696. }
  697. if (PyFile_WriteString("\n", f) < 0) {
  698. return -1;
  699. }
  700. return 0;
  701. }
  702. static int
  703. tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int lineno,
  704. PyFrameObject *frame, PyObject *name, int margin_indent, const char *margin)
  705. {
  706. if (filename == NULL || name == NULL) {
  707. return -1;
  708. }
  709. if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) {
  710. return -1;
  711. }
  712. PyObject *line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
  713. filename, lineno, name);
  714. if (line == NULL) {
  715. return -1;
  716. }
  717. int res = PyFile_WriteObject(line, f, Py_PRINT_RAW);
  718. Py_DECREF(line);
  719. if (res < 0) {
  720. return -1;
  721. }
  722. int err = 0;
  723. int truncation = _TRACEBACK_SOURCE_LINE_INDENT;
  724. PyObject* source_line = NULL;
  725. int rc = display_source_line_with_margin(
  726. f, filename, lineno, _TRACEBACK_SOURCE_LINE_INDENT,
  727. margin_indent, margin, &truncation, &source_line);
  728. if (rc != 0 || !source_line) {
  729. /* ignore errors since we can't report them, can we? */
  730. err = ignore_source_errors();
  731. goto done;
  732. }
  733. int code_offset = tb->tb_lasti;
  734. PyCodeObject* code = frame->f_frame->f_code;
  735. const Py_ssize_t source_line_len = PyUnicode_GET_LENGTH(source_line);
  736. int start_line;
  737. int end_line;
  738. int start_col_byte_offset;
  739. int end_col_byte_offset;
  740. if (!PyCode_Addr2Location(code, code_offset, &start_line, &start_col_byte_offset,
  741. &end_line, &end_col_byte_offset)) {
  742. goto done;
  743. }
  744. if (start_line < 0 || end_line < 0
  745. || start_col_byte_offset < 0
  746. || end_col_byte_offset < 0)
  747. {
  748. goto done;
  749. }
  750. // When displaying errors, we will use the following generic structure:
  751. //
  752. // ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE
  753. // ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^~~~~~~~~~~~~~~~~~~~
  754. // | |-> left_end_offset | |-> end_offset
  755. // |-> start_offset |-> right_start_offset
  756. //
  757. // In general we will only have (start_offset, end_offset) but we can gather more information
  758. // by analyzing the AST of the text between *start_offset* and *end_offset*. If this succeeds
  759. // we could get *left_end_offset* and *right_start_offset* and some selection of characters for
  760. // the different ranges (primary_error_char and secondary_error_char). If we cannot obtain the
  761. // AST information or we cannot identify special ranges within it, then left_end_offset and
  762. // right_end_offset will be set to -1.
  763. //
  764. // To keep the column indicators pertinent, they are not shown when the primary character
  765. // spans the whole line.
  766. // Convert the utf-8 byte offset to the actual character offset so we print the right number of carets.
  767. assert(source_line);
  768. Py_ssize_t start_offset = _PyPegen_byte_offset_to_character_offset(source_line, start_col_byte_offset);
  769. if (start_offset < 0) {
  770. err = ignore_source_errors() < 0;
  771. goto done;
  772. }
  773. Py_ssize_t end_offset = _PyPegen_byte_offset_to_character_offset(source_line, end_col_byte_offset);
  774. if (end_offset < 0) {
  775. err = ignore_source_errors() < 0;
  776. goto done;
  777. }
  778. Py_ssize_t left_end_offset = -1;
  779. Py_ssize_t right_start_offset = -1;
  780. char *primary_error_char = "^";
  781. char *secondary_error_char = primary_error_char;
  782. if (start_line == end_line) {
  783. int res = extract_anchors_from_line(filename, source_line, start_offset, end_offset,
  784. &left_end_offset, &right_start_offset,
  785. &primary_error_char, &secondary_error_char);
  786. if (res < 0 && ignore_source_errors() < 0) {
  787. goto done;
  788. }
  789. }
  790. else {
  791. // If this is a multi-line expression, then we will highlight until
  792. // the last non-whitespace character.
  793. const char *source_line_str = PyUnicode_AsUTF8(source_line);
  794. if (!source_line_str) {
  795. goto done;
  796. }
  797. Py_ssize_t i = source_line_len;
  798. while (--i >= 0) {
  799. if (!IS_WHITESPACE(source_line_str[i])) {
  800. break;
  801. }
  802. }
  803. end_offset = i + 1;
  804. }
  805. // Elide indicators if primary char spans the frame line
  806. Py_ssize_t stripped_line_len = source_line_len - truncation - _TRACEBACK_SOURCE_LINE_INDENT;
  807. bool has_secondary_ranges = (left_end_offset != -1 || right_start_offset != -1);
  808. if (end_offset - start_offset == stripped_line_len && !has_secondary_ranges) {
  809. goto done;
  810. }
  811. if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) {
  812. err = -1;
  813. goto done;
  814. }
  815. // Convert all offsets to display offsets (e.g. the space they would take up if printed
  816. // on the screen).
  817. Py_ssize_t dp_start = _PyPegen_calculate_display_width(source_line, start_offset);
  818. if (dp_start < 0) {
  819. err = ignore_source_errors() < 0;
  820. goto done;
  821. }
  822. Py_ssize_t dp_end = _PyPegen_calculate_display_width(source_line, end_offset);
  823. if (dp_end < 0) {
  824. err = ignore_source_errors() < 0;
  825. goto done;
  826. }
  827. Py_ssize_t dp_left_end = -1;
  828. Py_ssize_t dp_right_start = -1;
  829. if (has_secondary_ranges) {
  830. dp_left_end = _PyPegen_calculate_display_width(source_line, left_end_offset);
  831. if (dp_left_end < 0) {
  832. err = ignore_source_errors() < 0;
  833. goto done;
  834. }
  835. dp_right_start = _PyPegen_calculate_display_width(source_line, right_start_offset);
  836. if (dp_right_start < 0) {
  837. err = ignore_source_errors() < 0;
  838. goto done;
  839. }
  840. }
  841. if (print_error_location_carets(f, truncation, dp_start, dp_end,
  842. dp_right_start, dp_left_end,
  843. primary_error_char, secondary_error_char) < 0) {
  844. err = -1;
  845. goto done;
  846. }
  847. done:
  848. Py_XDECREF(source_line);
  849. return err;
  850. }
  851. static const int TB_RECURSIVE_CUTOFF = 3; // Also hardcoded in traceback.py.
  852. static int
  853. tb_print_line_repeated(PyObject *f, long cnt)
  854. {
  855. cnt -= TB_RECURSIVE_CUTOFF;
  856. PyObject *line = PyUnicode_FromFormat(
  857. (cnt > 1)
  858. ? " [Previous line repeated %ld more times]\n"
  859. : " [Previous line repeated %ld more time]\n",
  860. cnt);
  861. if (line == NULL) {
  862. return -1;
  863. }
  864. int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
  865. Py_DECREF(line);
  866. return err;
  867. }
  868. static int
  869. tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit,
  870. int indent, const char *margin)
  871. {
  872. PyCodeObject *code = NULL;
  873. Py_ssize_t depth = 0;
  874. PyObject *last_file = NULL;
  875. int last_line = -1;
  876. PyObject *last_name = NULL;
  877. long cnt = 0;
  878. PyTracebackObject *tb1 = tb;
  879. while (tb1 != NULL) {
  880. depth++;
  881. tb1 = tb1->tb_next;
  882. }
  883. while (tb != NULL && depth > limit) {
  884. depth--;
  885. tb = tb->tb_next;
  886. }
  887. while (tb != NULL) {
  888. code = PyFrame_GetCode(tb->tb_frame);
  889. int tb_lineno = tb->tb_lineno;
  890. if (tb_lineno == -1) {
  891. tb_lineno = tb_get_lineno(tb);
  892. }
  893. if (last_file == NULL ||
  894. code->co_filename != last_file ||
  895. last_line == -1 || tb_lineno != last_line ||
  896. last_name == NULL || code->co_name != last_name) {
  897. if (cnt > TB_RECURSIVE_CUTOFF) {
  898. if (tb_print_line_repeated(f, cnt) < 0) {
  899. goto error;
  900. }
  901. }
  902. last_file = code->co_filename;
  903. last_line = tb_lineno;
  904. last_name = code->co_name;
  905. cnt = 0;
  906. }
  907. cnt++;
  908. if (cnt <= TB_RECURSIVE_CUTOFF) {
  909. if (tb_displayline(tb, f, code->co_filename, tb_lineno,
  910. tb->tb_frame, code->co_name, indent, margin) < 0) {
  911. goto error;
  912. }
  913. if (PyErr_CheckSignals() < 0) {
  914. goto error;
  915. }
  916. }
  917. Py_CLEAR(code);
  918. tb = tb->tb_next;
  919. }
  920. if (cnt > TB_RECURSIVE_CUTOFF) {
  921. if (tb_print_line_repeated(f, cnt) < 0) {
  922. goto error;
  923. }
  924. }
  925. return 0;
  926. error:
  927. Py_XDECREF(code);
  928. return -1;
  929. }
  930. #define PyTraceBack_LIMIT 1000
  931. int
  932. _PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin,
  933. const char *header_margin, const char *header, PyObject *f)
  934. {
  935. PyObject *limitv;
  936. long limit = PyTraceBack_LIMIT;
  937. if (v == NULL) {
  938. return 0;
  939. }
  940. if (!PyTraceBack_Check(v)) {
  941. PyErr_BadInternalCall();
  942. return -1;
  943. }
  944. limitv = PySys_GetObject("tracebacklimit");
  945. if (limitv && PyLong_Check(limitv)) {
  946. int overflow;
  947. limit = PyLong_AsLongAndOverflow(limitv, &overflow);
  948. if (overflow > 0) {
  949. limit = LONG_MAX;
  950. }
  951. else if (limit <= 0) {
  952. return 0;
  953. }
  954. }
  955. if (_Py_WriteIndentedMargin(indent, header_margin, f) < 0) {
  956. return -1;
  957. }
  958. if (PyFile_WriteString(header, f) < 0) {
  959. return -1;
  960. }
  961. if (tb_printinternal((PyTracebackObject *)v, f, limit, indent, margin) < 0) {
  962. return -1;
  963. }
  964. return 0;
  965. }
  966. int
  967. PyTraceBack_Print(PyObject *v, PyObject *f)
  968. {
  969. int indent = 0;
  970. const char *margin = NULL;
  971. const char *header_margin = NULL;
  972. const char *header = EXCEPTION_TB_HEADER;
  973. return _PyTraceBack_Print_Indented(v, indent, margin, header_margin, header, f);
  974. }
  975. /* Format an integer in range [0; 0xffffffff] to decimal and write it
  976. into the file fd.
  977. This function is signal safe. */
  978. void
  979. _Py_DumpDecimal(int fd, size_t value)
  980. {
  981. /* maximum number of characters required for output of %lld or %p.
  982. We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits,
  983. plus 1 for the null byte. 53/22 is an upper bound for log10(256). */
  984. char buffer[1 + (sizeof(size_t)*53-1) / 22 + 1];
  985. char *ptr, *end;
  986. end = &buffer[Py_ARRAY_LENGTH(buffer) - 1];
  987. ptr = end;
  988. *ptr = '\0';
  989. do {
  990. --ptr;
  991. assert(ptr >= buffer);
  992. *ptr = '0' + (value % 10);
  993. value /= 10;
  994. } while (value);
  995. _Py_write_noraise(fd, ptr, end - ptr);
  996. }
  997. /* Format an integer as hexadecimal with width digits into fd file descriptor.
  998. The function is signal safe. */
  999. void
  1000. _Py_DumpHexadecimal(int fd, uintptr_t value, Py_ssize_t width)
  1001. {
  1002. char buffer[sizeof(uintptr_t) * 2 + 1], *ptr, *end;
  1003. const Py_ssize_t size = Py_ARRAY_LENGTH(buffer) - 1;
  1004. if (width > size)
  1005. width = size;
  1006. /* it's ok if width is negative */
  1007. end = &buffer[size];
  1008. ptr = end;
  1009. *ptr = '\0';
  1010. do {
  1011. --ptr;
  1012. assert(ptr >= buffer);
  1013. *ptr = Py_hexdigits[value & 15];
  1014. value >>= 4;
  1015. } while ((end - ptr) < width || value);
  1016. _Py_write_noraise(fd, ptr, end - ptr);
  1017. }
  1018. void
  1019. _Py_DumpASCII(int fd, PyObject *text)
  1020. {
  1021. PyASCIIObject *ascii = _PyASCIIObject_CAST(text);
  1022. Py_ssize_t i, size;
  1023. int truncated;
  1024. int kind;
  1025. void *data = NULL;
  1026. Py_UCS4 ch;
  1027. if (!PyUnicode_Check(text))
  1028. return;
  1029. size = ascii->length;
  1030. kind = ascii->state.kind;
  1031. if (ascii->state.compact) {
  1032. if (ascii->state.ascii)
  1033. data = ascii + 1;
  1034. else
  1035. data = _PyCompactUnicodeObject_CAST(text) + 1;
  1036. }
  1037. else {
  1038. data = _PyUnicodeObject_CAST(text)->data.any;
  1039. if (data == NULL)
  1040. return;
  1041. }
  1042. if (MAX_STRING_LENGTH < size) {
  1043. size = MAX_STRING_LENGTH;
  1044. truncated = 1;
  1045. }
  1046. else {
  1047. truncated = 0;
  1048. }
  1049. // Is an ASCII string?
  1050. if (ascii->state.ascii) {
  1051. assert(kind == PyUnicode_1BYTE_KIND);
  1052. char *str = data;
  1053. int need_escape = 0;
  1054. for (i=0; i < size; i++) {
  1055. ch = str[i];
  1056. if (!(' ' <= ch && ch <= 126)) {
  1057. need_escape = 1;
  1058. break;
  1059. }
  1060. }
  1061. if (!need_escape) {
  1062. // The string can be written with a single write() syscall
  1063. _Py_write_noraise(fd, str, size);
  1064. goto done;
  1065. }
  1066. }
  1067. for (i=0; i < size; i++) {
  1068. ch = PyUnicode_READ(kind, data, i);
  1069. if (' ' <= ch && ch <= 126) {
  1070. /* printable ASCII character */
  1071. char c = (char)ch;
  1072. _Py_write_noraise(fd, &c, 1);
  1073. }
  1074. else if (ch <= 0xff) {
  1075. PUTS(fd, "\\x");
  1076. _Py_DumpHexadecimal(fd, ch, 2);
  1077. }
  1078. else if (ch <= 0xffff) {
  1079. PUTS(fd, "\\u");
  1080. _Py_DumpHexadecimal(fd, ch, 4);
  1081. }
  1082. else {
  1083. PUTS(fd, "\\U");
  1084. _Py_DumpHexadecimal(fd, ch, 8);
  1085. }
  1086. }
  1087. done:
  1088. if (truncated) {
  1089. PUTS(fd, "...");
  1090. }
  1091. }
  1092. /* Write a frame into the file fd: "File "xxx", line xxx in xxx".
  1093. This function is signal safe. */
  1094. static void
  1095. dump_frame(int fd, _PyInterpreterFrame *frame)
  1096. {
  1097. assert(frame->owner != FRAME_OWNED_BY_CSTACK);
  1098. PyCodeObject *code = frame->f_code;
  1099. PUTS(fd, " File ");
  1100. if (code->co_filename != NULL
  1101. && PyUnicode_Check(code->co_filename))
  1102. {
  1103. PUTS(fd, "\"");
  1104. _Py_DumpASCII(fd, code->co_filename);
  1105. PUTS(fd, "\"");
  1106. } else {
  1107. PUTS(fd, "???");
  1108. }
  1109. int lineno = PyUnstable_InterpreterFrame_GetLine(frame);
  1110. PUTS(fd, ", line ");
  1111. if (lineno >= 0) {
  1112. _Py_DumpDecimal(fd, (size_t)lineno);
  1113. }
  1114. else {
  1115. PUTS(fd, "???");
  1116. }
  1117. PUTS(fd, " in ");
  1118. if (code->co_name != NULL
  1119. && PyUnicode_Check(code->co_name)) {
  1120. _Py_DumpASCII(fd, code->co_name);
  1121. }
  1122. else {
  1123. PUTS(fd, "???");
  1124. }
  1125. PUTS(fd, "\n");
  1126. }
  1127. static int
  1128. tstate_is_freed(PyThreadState *tstate)
  1129. {
  1130. if (_PyMem_IsPtrFreed(tstate)) {
  1131. return 1;
  1132. }
  1133. if (_PyMem_IsPtrFreed(tstate->interp)) {
  1134. return 1;
  1135. }
  1136. return 0;
  1137. }
  1138. static int
  1139. interp_is_freed(PyInterpreterState *interp)
  1140. {
  1141. return _PyMem_IsPtrFreed(interp);
  1142. }
  1143. static void
  1144. dump_traceback(int fd, PyThreadState *tstate, int write_header)
  1145. {
  1146. if (write_header) {
  1147. PUTS(fd, "Stack (most recent call first):\n");
  1148. }
  1149. if (tstate_is_freed(tstate)) {
  1150. PUTS(fd, " <tstate is freed>\n");
  1151. return;
  1152. }
  1153. _PyInterpreterFrame *frame = tstate->cframe->current_frame;
  1154. if (frame == NULL) {
  1155. PUTS(fd, " <no Python frame>\n");
  1156. return;
  1157. }
  1158. unsigned int depth = 0;
  1159. while (1) {
  1160. if (frame->owner == FRAME_OWNED_BY_CSTACK) {
  1161. /* Trampoline frame */
  1162. frame = frame->previous;
  1163. if (frame == NULL) {
  1164. break;
  1165. }
  1166. /* Can't have more than one shim frame in a row */
  1167. assert(frame->owner != FRAME_OWNED_BY_CSTACK);
  1168. }
  1169. if (MAX_FRAME_DEPTH <= depth) {
  1170. PUTS(fd, " ...\n");
  1171. break;
  1172. }
  1173. dump_frame(fd, frame);
  1174. frame = frame->previous;
  1175. if (frame == NULL) {
  1176. break;
  1177. }
  1178. depth++;
  1179. }
  1180. }
  1181. /* Dump the traceback of a Python thread into fd. Use write() to write the
  1182. traceback and retry if write() is interrupted by a signal (failed with
  1183. EINTR), but don't call the Python signal handler.
  1184. The caller is responsible to call PyErr_CheckSignals() to call Python signal
  1185. handlers if signals were received. */
  1186. void
  1187. _Py_DumpTraceback(int fd, PyThreadState *tstate)
  1188. {
  1189. dump_traceback(fd, tstate, 1);
  1190. }
  1191. /* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
  1192. is_current is true, "Thread 0xHHHH:\n" otherwise.
  1193. This function is signal safe. */
  1194. static void
  1195. write_thread_id(int fd, PyThreadState *tstate, int is_current)
  1196. {
  1197. if (is_current)
  1198. PUTS(fd, "Current thread 0x");
  1199. else
  1200. PUTS(fd, "Thread 0x");
  1201. _Py_DumpHexadecimal(fd,
  1202. tstate->thread_id,
  1203. sizeof(unsigned long) * 2);
  1204. PUTS(fd, " (most recent call first):\n");
  1205. }
  1206. /* Dump the traceback of all Python threads into fd. Use write() to write the
  1207. traceback and retry if write() is interrupted by a signal (failed with
  1208. EINTR), but don't call the Python signal handler.
  1209. The caller is responsible to call PyErr_CheckSignals() to call Python signal
  1210. handlers if signals were received. */
  1211. const char*
  1212. _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
  1213. PyThreadState *current_tstate)
  1214. {
  1215. if (current_tstate == NULL) {
  1216. /* _Py_DumpTracebackThreads() is called from signal handlers by
  1217. faulthandler.
  1218. SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals
  1219. and are thus delivered to the thread that caused the fault. Get the
  1220. Python thread state of the current thread.
  1221. PyThreadState_Get() doesn't give the state of the thread that caused
  1222. the fault if the thread released the GIL, and so
  1223. _PyThreadState_GET() cannot be used. Read the thread specific
  1224. storage (TSS) instead: call PyGILState_GetThisThreadState(). */
  1225. current_tstate = PyGILState_GetThisThreadState();
  1226. }
  1227. if (current_tstate != NULL && tstate_is_freed(current_tstate)) {
  1228. return "tstate is freed";
  1229. }
  1230. if (interp == NULL) {
  1231. if (current_tstate == NULL) {
  1232. interp = _PyGILState_GetInterpreterStateUnsafe();
  1233. if (interp == NULL) {
  1234. /* We need the interpreter state to get Python threads */
  1235. return "unable to get the interpreter state";
  1236. }
  1237. }
  1238. else {
  1239. interp = current_tstate->interp;
  1240. }
  1241. }
  1242. assert(interp != NULL);
  1243. if (interp_is_freed(interp)) {
  1244. return "interp is freed";
  1245. }
  1246. /* Get the current interpreter from the current thread */
  1247. PyThreadState *tstate = PyInterpreterState_ThreadHead(interp);
  1248. if (tstate == NULL)
  1249. return "unable to get the thread head state";
  1250. /* Dump the traceback of each thread */
  1251. tstate = PyInterpreterState_ThreadHead(interp);
  1252. unsigned int nthreads = 0;
  1253. _Py_BEGIN_SUPPRESS_IPH
  1254. do
  1255. {
  1256. if (nthreads != 0)
  1257. PUTS(fd, "\n");
  1258. if (nthreads >= MAX_NTHREADS) {
  1259. PUTS(fd, "...\n");
  1260. break;
  1261. }
  1262. write_thread_id(fd, tstate, tstate == current_tstate);
  1263. if (tstate == current_tstate && tstate->interp->gc.collecting) {
  1264. PUTS(fd, " Garbage-collecting\n");
  1265. }
  1266. dump_traceback(fd, tstate, 0);
  1267. tstate = PyThreadState_Next(tstate);
  1268. nthreads++;
  1269. } while (tstate != NULL);
  1270. _Py_END_SUPPRESS_IPH
  1271. return NULL;
  1272. }