From: Kumar Aditya Date: Fri, 12 Sep 2025 12:34:55 +0000 (+0530) Subject: gh-138661: fix data race in `PyCode_Addr2Line` (#138664) X-Git-Tag: v3.15.0a1~395 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ea26f6da39294b7d3c28873d070a2218bd528b5f;p=thirdparty%2FPython%2Fcpython.git gh-138661: fix data race in `PyCode_Addr2Line` (#138664) --- diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 8e1415f27b63..0f0804d5db61 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -274,6 +274,8 @@ extern void _PyLineTable_InitAddressRange( /** API for traversing the line number table. */ extern int _PyLineTable_NextAddressRange(PyCodeAddressRange *range); extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); +// This is used in dump_frame() in traceback.c without an attached tstate. +extern int _PyCode_Addr2LineNoTstate(PyCodeObject *co, int addr); /** API for executors */ extern void _PyCode_Clear_Executors(PyCodeObject *code); diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 55ba6ae372be..0d264a6e346f 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1006,7 +1006,7 @@ failed: ******************/ int -PyCode_Addr2Line(PyCodeObject *co, int addrq) +_PyCode_Addr2LineNoTstate(PyCodeObject *co, int addrq) { if (addrq < 0) { return co->co_firstlineno; @@ -1020,6 +1020,16 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq) return _PyCode_CheckLineNumber(addrq, &bounds); } +int +PyCode_Addr2Line(PyCodeObject *co, int addrq) +{ + int lineno; + Py_BEGIN_CRITICAL_SECTION(co); + lineno = _PyCode_Addr2LineNoTstate(co, addrq); + Py_END_CRITICAL_SECTION(); + return lineno; +} + void _PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range) { diff --git a/Python/traceback.c b/Python/traceback.c index da7956d1ec47..46106e52dbaf 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -993,8 +993,8 @@ dump_frame(int fd, _PyInterpreterFrame *frame) } else { PUTS(fd, "???"); } - - int lineno = PyUnstable_InterpreterFrame_GetLine(frame); + int lasti = PyUnstable_InterpreterFrame_GetLasti(frame); + int lineno = _PyCode_Addr2LineNoTstate(code, lasti); PUTS(fd, ", line "); if (lineno >= 0) { _Py_DumpDecimal(fd, (size_t)lineno);