]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-138661: fix data race in `PyCode_Addr2Line` (#138664)
authorKumar Aditya <kumaraditya@python.org>
Fri, 12 Sep 2025 12:34:55 +0000 (18:04 +0530)
committerGitHub <noreply@github.com>
Fri, 12 Sep 2025 12:34:55 +0000 (18:04 +0530)
Include/internal/pycore_code.h
Objects/codeobject.c
Python/traceback.c

index 8e1415f27b63f3d1c16ea239f5d04b4f61ab6924..0f0804d5db61f7ffc73f54c80ea5eaec0104cc0d 100644 (file)
@@ -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);
index 55ba6ae372be41351a7e0ee24e226a9decca0702..0d264a6e346f95a046bbedfc47fd371b8c0ea310 100644 (file)
@@ -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)
 {
index da7956d1ec47b4e1ae579b60a2e29a3cbaf67b65..46106e52dbaf82c67fe3fa0ca332317f97dc67c2 100644 (file)
@@ -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);