Skip to content

Conversation

@DinoV
Copy link
Contributor

@DinoVDinoV commented May 1, 2024

When tracing is getting enabled / disabled locally we are currently updating the per-instruction-tools and per-line-tools, either clearing or restoring the non-optimized opcodes that we should fall back to.

When another thread is executing it may see the instrumented opcode and then race with the events and then not see the original opcode as tracing may have changed.

This changes it so that we just always maintain the original opcodes for all of the instructions. It means we can't do some sanity checks but the fact that it's not changing simplifies things.

There's also some assertions that can fire because the local events are being enabled or disabled. At runtime these races are benign, we're just delivering events on other threads in a short window after tracing is disabled or not delivering events in a short window after it's enabled. But the asserts need to lock the code object to be able to get a consistent view on the world.

@DinoVDinoV marked this pull request as ready for review May 2, 2024 01:50
@colesburycolesbury changed the title [gh-118415] Fix issues with local tracing being enabled/disabled on a functiongh-118415: Fix issues with local tracing being enabled/disabled on a functionMay 2, 2024
@DinoVDinoVforce-pushed the nogil_trace_assert branch from b108af7 to 855157fCompareMay 2, 2024 17:01
@colesburycolesbury self-requested a review May 3, 2024 20:01
Comment on lines 1003 to 1004
static inline
int debug_check_sanity(PyInterpreterState *interp, PyCodeObject *code)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
staticinline
intdebug_check_sanity(PyInterpreterState*interp, PyCodeObject*code)
staticint
debug_check_sanity(PyInterpreterState*interp, PyCodeObject*code)

self.assertEqual(ref(), None)

def test_set_local_trace_opcodes(self):
return
Copy link
Contributor

Choose a reason for hiding this comment

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

The return here doesn't look right

with l:
pass

t = threading.Thread(target=f)
Copy link
Contributor

Choose a reason for hiding this comment

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

missing import threading or t = Thread(target=f)

for (int i = 0; i < code_len; i++){
code->_co_monitoring->per_instruction_tools[i] = 0;
int opcode = _PyCode_CODE(code)[i].op.code;
code->_co_monitoring->per_instruction_tools[i] = _PyOpcode_Deopt[opcode];
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't look right. Shouldn't it be initialized to zero?

}

static inline
static
Copy link
Contributor

Choose a reason for hiding this comment

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

My previously comment was mostly intended to be that static int should be on one line

Copy link
Contributor

@colesburycolesbury left a comment

Choose a reason for hiding this comment

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

LGTM, but I'd fix the formatting of debug_check_sanity

@DinoVDinoVforce-pushed the nogil_trace_assert branch from 5d3c321 to c19b622CompareMay 6, 2024 18:33
@DinoVDinoV merged commit 00d913c into python:mainMay 6, 2024
SonicField pushed a commit to SonicField/cpython that referenced this pull request May 8, 2024
@DinoVDinoV deleted the nogil_trace_assert branch May 31, 2024 18:21
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@DinoV@colesbury