Skip to content
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

Fatal error / exception handling #10

Merged
merged 8 commits into from
Dec 24, 2021

Conversation

mikee47
Copy link
Contributor

@mikee47 mikee47 commented Dec 16, 2021

The goal of this PR is to be really horrible to jerryscript and do nasty things in javascript to see what breaks.

First thing is to allocate large array and see what happens.
We get a fatal 'out of memory' exception which trips 'jerry_port_fatal. As this is a no-return function, I've used setjmp/longjmp to catch these failures in call`, which works.

BUT. How to indicate this to the caller? In general, we cannot rely on the state of jerryscript after a fatal error so it must be re-initialised. That requires application co-operation.

The solution proposed here implements a simple exception handling mechanism using setjmp/longjmp.
Two macros, JS_TRY() and JS_CATCH() could be re-implemented using regular C++ exception handling if required.

The handler has to go at the top execution level. I've revised the Event_Jsvm sample to demonstrate how this works.

Note: Enabling jerryscript assertions makes recovery impossible in some situations, so clearly that's only intended for debugging jerryscript itself.

slaff pushed a commit that referenced this pull request Dec 20, 2021
Some additional revisions which should be considered before release.

**fixes**

- Update 'load' and 'eval' functions, they return a value, not bool
- Tidy up `Object::getFunction` to return only requested function or error
- Fix Value move constructor / assignment operator, reset()
- Fix `Value::isEmpty()` and String() operator
- Prevent `Null`, `Undefined` from being constructed with different values.
- Must not use internal jerryscript headers publicly. Can introduce invalid #defines.

**improvements**

- Enable snapshot compiler error messages. e.g. shows position of syntax errors in .js
- Update Advanced_Jsvm README. Remove diagram, etc. which is in main library README, and re-word appropriately.
- Add JERRY_ERROR_MESSAGES variable, optionally include library messages
- Generate type maps from jerryscript headers. Avoids manual copying of values which may change in future releases.
- Add feature test, i.e. JS::isFeatureEnabled()
- Only enable JERRY_ENABLE_DEBUG explicitly; should only be required for jerryscript library debugging.
- Additional tests.
- Enable parser support via `JERRY_PARSER` variable - `eval()` won't work without this.

Known issues;

- For esp8266, constant data cannot be easily moved to flash as accesses are not always word aligned. This will be more involved and handled as a separate PR.
- Fatal errors are not handled and will cause system reset. See #10.
- Whilst `eval()` will work with parser support enabled, the main parse/run interfaces are more extensive and have not yet been ported.
Use Except object for nestable exception handling.
Add fatal test module
@mikee47
Copy link
Contributor Author

mikee47 commented Dec 20, 2021

@slaff Tried a few approaches to this and think this is the way to go. Thoughts?

@slaff
Copy link
Owner

slaff commented Dec 20, 2021

Tried a few approaches to this and think this is the way to go. Thoughts?

@mikee47 I like this PR the way it is. If you have some additional work to polish this PR - can you do it so that I can merge this PR and have these changes also in Sming v4.5.0 ?

@mikee47 mikee47 changed the title [WIP] Fatal error handling Fatal error / exception handling Dec 20, 2021
JS::Object event;
event["name"] = name;
event["params"] = params;
JS_TRY()
Copy link
Owner

Choose a reason for hiding this comment

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

@mikee47 I am wondering isn't it possible to use try-catch directly in the JavaScript code and catch out-of-memory exception? We could expose a reset() JavaScript function that resets the VM and give the JS developers (end user) better control. On the C/C++ side we could check if the VM is in error state and restart the VM automatically if it stays in this error state for 8 seconds.

Copy link
Contributor Author

@mikee47 mikee47 Dec 22, 2021

Choose a reason for hiding this comment

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

Unfortunately fatal errors are not the same as javascript exceptions and cannot be caught in script. The engine is essentially halted. No attempt to even tidy up intermediate allocations so cleanup won't work. Try running the tests with JERRY_ENABLE_DEBUG=1 and see what happens!

A reset() function would be very easy to implement. However, depending on the use-case if we wanted multiple clients runninng together would we really want one of them to be able to pull the rug out from the others? Maybe, but that'll depend on usage.

It's going to get confused with external contexts.
@mikee47 mikee47 force-pushed the feature/fatal-error-handling branch 2 times, most recently from 4f364aa to 651d12a Compare December 23, 2021 13:05
@slaff slaff merged commit e0328a3 into slaff:develop Dec 24, 2021
@mikee47 mikee47 deleted the feature/fatal-error-handling branch December 25, 2021 10:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants