Skip to content

Commit ea26f6d

Browse files
pythongh-138661: fix data race in PyCode_Addr2Line (python#138664)
1 parent c3fca5d commit ea26f6d

File tree

3 files changed

+15
-3
lines changed

3 files changed

+15
-3
lines changed

Include/internal/pycore_code.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ extern void _PyLineTable_InitAddressRange(
274274
/** API for traversing the line number table. */
275275
extern int _PyLineTable_NextAddressRange(PyCodeAddressRange *range);
276276
extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);
277+
// This is used in dump_frame() in traceback.c without an attached tstate.
278+
extern int _PyCode_Addr2LineNoTstate(PyCodeObject *co, int addr);
277279

278280
/** API for executors */
279281
extern void _PyCode_Clear_Executors(PyCodeObject *code);

Objects/codeobject.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
10061006
******************/
10071007

10081008
int
1009-
PyCode_Addr2Line(PyCodeObject *co, int addrq)
1009+
_PyCode_Addr2LineNoTstate(PyCodeObject *co, int addrq)
10101010
{
10111011
if (addrq < 0) {
10121012
return co->co_firstlineno;
@@ -1020,6 +1020,16 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq)
10201020
return _PyCode_CheckLineNumber(addrq, &bounds);
10211021
}
10221022

1023+
int
1024+
PyCode_Addr2Line(PyCodeObject *co, int addrq)
1025+
{
1026+
int lineno;
1027+
Py_BEGIN_CRITICAL_SECTION(co);
1028+
lineno = _PyCode_Addr2LineNoTstate(co, addrq);
1029+
Py_END_CRITICAL_SECTION();
1030+
return lineno;
1031+
}
1032+
10231033
void
10241034
_PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range)
10251035
{

Python/traceback.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -993,8 +993,8 @@ dump_frame(int fd, _PyInterpreterFrame *frame)
993993
} else {
994994
PUTS(fd, "???");
995995
}
996-
997-
int lineno = PyUnstable_InterpreterFrame_GetLine(frame);
996+
int lasti = PyUnstable_InterpreterFrame_GetLasti(frame);
997+
int lineno = _PyCode_Addr2LineNoTstate(code, lasti);
998998
PUTS(fd, ", line ");
999999
if (lineno >= 0) {
10001000
_Py_DumpDecimal(fd, (size_t)lineno);

0 commit comments

Comments
 (0)