-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
profiling: sys.settrace implementation (v2) #5026
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
8c05738 to
960c8e4
Compare
|
@malinah Here I've taken your PR and added some commits (fixes) to get it building on most of the ports. There a problem running the test Also, I'd like to rename the |
Wow. Awesome!
Ah. How is it possible for the Anyway. The frame and subsequent code objects created in the // allocate state for locals and stack
mp_code_state_t *code_state = NULL;
#if MICROPY_ENABLE_PYSTACK
code_state = mp_pystack_alloc(sizeof(mp_code_state_t) + state_size);
#else
if (state_size > VM_MAX_STATE_ON_STACK) {
code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size);
#if MICROPY_DEBUG_VM_STACK_OVERFLOW
if (code_state != NULL) {
memset(code_state->state, 0, state_size);
}
#endif
}
if (code_state == NULL) {
code_state = alloca(sizeof(mp_code_state_t) + state_size);
#if MICROPY_DEBUG_VM_STACK_OVERFLOW
memset(code_state->state, 0, state_size);
#endif
state_size = 0; // indicate that we allocated using alloca
}
#endifLater when the trace callback is invoked the actual micropython objects are created. This should be the correct solution. Although a bit slower and memory inefficient. This hack in bool gc_is_locked_tmp = gc_is_locked();
if (gc_is_locked_tmp) {
gc_unlock();
}BTW What is the use-case for the
Sure, no problem. |
No it's not. Sweeping can run finalisers (during the sweep) which can run arbitrary Python code. Such finalisers are restricted in that they can't allocate memory.
This does sound like a reasonable solution, but as you say it's going to use a lot of RAM. Another option is to simply not create a frame when the GC is locked and don't do any tracing/profiling for such calls. I think it's acceptable for now that heap locking restricts what can be profiled. I've push a commit to do this.
It's needed by hard interrupt handlers: the IRQ may interrupt the GC during a collection phase, and the IRQ handler must still execute at that time (it cannot wait until the collection is finished), so the only thing to do is lock out any heap allocation for the duration of the IRQ handler.
"trace" is currently only used for "traceback" in the py/ directory, but I agree that a file called I think the word "profile" is a good choice, and being part of a Python implementation I don't think it'd be mistaken for user profiles. |
|
OK. Everything looks good now :) |
|
I added initial support for tracing/profiling of frozen bytecode. |
d953491 to
054bbd8
Compare
aa74c4a to
0938050
Compare
|
@malinah this is very close to being ready for merge. I added a new Travis CI target to test the settrace code and it is passing. I also renamed the test to One remaining question: I see you added the |
tests/misc/sys_settrace_profile.py
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line from uio import open is obsoleted. Please remove it.
Awesome!
I didn't notice filenames being handled differently. When executed from the same directory
Yeah. That was my idea too but right now I don't think it's easily doable. The main reason being the uPy compiler produces different bytecode for conditional jumps in loops, generators, exceptions and probably something else I can't remember right now. When you run the test |
0938050 to
d8884ab
Compare
You're right, I made a mistake and wasn't executing them from the
In the latest set of commits I have somewhat implemented this: I pulled out the tests that were different between CPy and uPy into So now this PR should be good to go in! |
Well done! :) |
adb0fb0 to
53c76f2
Compare
Prior to this patch the line number for a lambda would be "line 1" if the body of the lambda contained only a simple expression (with no line number stored in the parse node). Now the line number is always reported correctly.
This commit adds support for sys.settrace, allowing to install Python handlers to trace execution of Python code. The interface follows CPython as closely as possible. The feature is disabled by default and can be enabled via MICROPY_PY_SYS_SETTRACE.
53c76f2 to
0b85b5b
Compare
|
This is now merged! Thank you very much @malinah for the contribution, really great work! Note: I did a little more cleaning of the code before merging, including factoring out the |
|
Congratulations to you both! |
|
Great collaboration all round! |
|
Yes this is a really nice addition, opening the door for a debugger :) |
Fix crash when UART construct fails
Based on #4265, with changes to build on all ports.