Skip to content

Enable abort support #15392

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

Closed

Conversation

RealJohnSmith
Copy link

Summary

Add abort setup code (nlr_set_abort) to standard runtime. This makes the standard runtime respond to abort signal without any further modifications.

  • When aborted, the program exits with 137 exit code (configurable, same as posix sig abort), to differentiate from a normal shutdown.
  • When exited by exception/crash, the program will exit with exit code 1 (configurable)
  • When exited by exception KeyboardInterrupt, the program will exit with exit code 130 (configurable, same as posix sig int)

This PR updates previous PR/discussion at: #14419 but in this new PR, the code is rebased on top of the current master.

Testing

Tested on ESP32, should work in other places. The changes are guarded by #if abort is enabled in the runtime -> only people who want the abort functionality will get this change.

Trade-offs and Alternatives

This code may return non-zero exit code in scenarios where previous version did return zero exit code. The exit codes are configurable and the defaults are zero, so not to introduce any breaking changes.

Copy link

github-actions bot commented Jul 2, 2024

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS

@RealJohnSmith RealJohnSmith force-pushed the enable-abort-support branch from 253df70 to 3ce8061 Compare July 2, 2024 11:58
Copy link

codecov bot commented Jul 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.41%. Comparing base (91f4a6b) to head (a931243).
Report is 49 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #15392      +/-   ##
==========================================
- Coverage   98.43%   98.41%   -0.03%     
==========================================
  Files         161      163       +2     
  Lines       21281    21576     +295     
==========================================
+ Hits        20948    21234     +286     
- Misses        333      342       +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@dpgeorge dpgeorge added the py-core Relates to py/ directory in source label Jul 2, 2024
ret = pyexec_abort;
} else
#endif
if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) { // system exit
Copy link
Member

Choose a reason for hiding this comment

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

This updated SystemExit handling code (the second commit in the PR) adds quite a bit of code size to existing builds, which don't really use the functionality.

How useful is this new code? Does it make sense to guard it with a compile-time configuration flag?

Copy link
Contributor

Choose a reason for hiding this comment

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

Or perhaps to make it even more flexible, use a macro similar to other port-specific hooks.

I.e. MICROPY_VM_HOOK_ABORT. This way, the code can be customized without modifying pyexec.c.

Copy link
Author

Choose a reason for hiding this comment

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

I am not sure how to do the part with the hook. What do you mean, can you please explain?

Copy link
Author

Choose a reason for hiding this comment

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

It doesnt feel like a lot of code size to me, but I can add some compile time guards, that is not a problem

Copy link
Author

Choose a reason for hiding this comment

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

I implemented the guard using a new macro "MICROPY_ENABLE_EXIT_CODE_HANDLING"

if set to 0, the behavior should be the same as before. As well as code size. This means, the exit code is written into the variable pyexec_system_exit internally, before the SystemExit exception is raised (e.g. soft reset method).

if set to 1, the values defined in macros such as PYEXEC_KEYBOARD_INTERRUPT are used for the appropriate exit value.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure how to do the part with the hook. What do you mean, can you please explain?

Maybe I am remembering wrong, but in the previous PR, it seems like at one point, there was some extra printing or something in the abort path. I don't see that now. So this is something we could add later if needed.

What you did with MICROPY_ENABLE_EXIT_CODE_HANDLING looks good to me.

@RealJohnSmith RealJohnSmith force-pushed the enable-abort-support branch 3 times, most recently from a212069 to d2bfc85 Compare July 8, 2024 18:17
@RealJohnSmith
Copy link
Author

What do you think, @dpgeorge @dlech? Is this ok for merge?

@RealJohnSmith RealJohnSmith requested review from dlech and dpgeorge August 2, 2024 14:03
ret = pyexec_abort;
} else
#endif
if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) { // system exit
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure how to do the part with the hook. What do you mean, can you please explain?

Maybe I am remembering wrong, but in the previous PR, it seems like at one point, there was some extra printing or something in the abort path. I don't see that now. So this is something we could add later if needed.

What you did with MICROPY_ENABLE_EXIT_CODE_HANDLING looks good to me.

#if MICROPY_ENABLE_VM_ABORT
int pyexec_abort = 0; // kept at 0 for backward compatibility
#endif
int pyexec_keyboard_interrupt = 0; // kept at 0 for backward compatibility
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we still need pyexec_keyboard_interrupt? It doesn't look like it is being used anywhere.

Copy link
Author

Choose a reason for hiding this comment

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

we dont, I forgot it there

@@ -45,6 +45,11 @@

pyexec_mode_kind_t pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
int pyexec_system_exit = 0;
#if MICROPY_ENABLE_VM_ABORT
int pyexec_abort = 0; // kept at 0 for backward compatibility
Copy link
Contributor

Choose a reason for hiding this comment

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

Since abort handling wasn't implemented before, I'm not sure we need to worry about backwards compatibility here.

Copy link
Author

Choose a reason for hiding this comment

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

Ok, removing the comment. The original value was 0 and I think we should keep it there.

#if MICROPY_ENABLE_VM_ABORT
// Set this to the value (eg PYEXEC_ABORT) that will be propagated through
// the pyexec functions if the VM is aborted for immediate exit.
// It will reset to 0 at the start of each execution (eg each REPL entry).
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see where this is reset to 0 in the code.

Copy link
Author

Choose a reason for hiding this comment

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

Here:

// by default a SystemExit exception returns 0
pyexec_system_exit = 0;

This is the original part (e.g. relevant without the MICROPY_ENABLE_EXIT_CODE_HANDLING) I didn't modify it in any way.

@RealJohnSmith
Copy link
Author

If I understand correctly the conflict that occurred since the last time, the pyexec_system_exit was removed. I removed it as well, which also solves the comments you had

@RealJohnSmith
Copy link
Author

Can we merge it now?

@dpgeorge
Copy link
Member

Superseded by #15730.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
py-core Relates to py/ directory in source
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants