Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix the lineno cache issue
  • Loading branch information
gaogaotiantian committed Apr 20, 2024
commit a6cee96faf8bf079564160e8ba9f573fd131fe8b
13 changes: 11 additions & 2 deletions Objects/frameobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,19 @@ int
PyFrame_GetLineNumber(PyFrameObject *f)
{
assert(f != NULL);
if (f->f_lineno == 0) {
if (f->f_lineno == -1) {
// We should calculate it once. If we can't get the line number,
// set f->f_lineno to 0.
f->f_lineno = PyUnstable_InterpreterFrame_GetLine(f->f_frame);
if (f->f_lineno < 0) {
f->f_lineno = 0;
}
}

if (f->f_lineno > 0) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If f->f_lineno == 0 we end up recalculating the line number, so if PyUnstable_InterpreterFrame_GetLine() returns -1 it will get called twice.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that makes sense.

return f->f_lineno;
}
return f->f_lineno;
return PyUnstable_InterpreterFrame_GetLine(f->f_frame);
}

static PyObject *
Expand Down
10 changes: 5 additions & 5 deletions Python/instrumentation.c
Original file line number Diff line number Diff line change
Expand Up @@ -1228,9 +1228,9 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
int line = 0;

if (line_delta == COMPUTED_LINE_LINENO_CHANGE) {
// We know the line number must changed, don't need to calculate the
// line number for now because we might not need it.
line = 0;
// We know the line number must have changed, don't need to calculate
// the line number for now because we might not need it.
line = -1;
} else {
line = compute_line(code, i, line_delta);
assert(line >= 0);
Expand Down Expand Up @@ -1269,7 +1269,7 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
tstate->tracing++;
/* Call c_tracefunc directly, having set the line number. */
Py_INCREF(frame_obj);
if (line == 0 && line_delta > COMPUTED_LINE) {
if (line == -1 && line_delta > COMPUTED_LINE) {
/* Only assign f_lineno if it's easy to calculate, otherwise
* do lazy calculation by setting the f_lineno to 0.
*/
Expand All @@ -1292,7 +1292,7 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
goto done;
}

if (line == 0) {
if (line == -1) {
/* Need to calculate the line number now for monitoring events */
line = compute_line(code, i, line_delta);
}
Expand Down