From 78266bf7b3631ed81ca01bfa5eeb75a927de2c65 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Fri, 12 Sep 2025 18:04:55 +0530 Subject: [PATCH] gh-138661: fix data race in `PyCode_Addr2Line` (GH-138664) (cherry picked from commit ea26f6da39294b7d3c28873d070a2218bd528b5f) Co-authored-by: Kumar Aditya --- Include/internal/pycore_code.h | 2 ++ Objects/codeobject.c | 12 +++++++++++- Python/traceback.c | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 37a747aa4e3e46..43286774eb2c71 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 42e021679b583f..1dbbb053e3fc48 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1014,7 +1014,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) ******************/ int -PyCode_Addr2Line(PyCodeObject *co, int addrq) +_PyCode_Addr2LineNoTstate(PyCodeObject *co, int addrq) { if (addrq < 0) { return co->co_firstlineno; @@ -1028,6 +1028,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 c06cb1a59089e2..f3c5644aeb1799 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -994,8 +994,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);