How to handle exceptions (e.g. LoadProhibited)?

Miraculix
Posts: 20
Joined: Wed Sep 16, 2020 9:43 am

How to handle exceptions (e.g. LoadProhibited)?

Postby Miraculix » Wed Jul 27, 2022 7:46 pm

So I get reboots like these, and it takes quite some effort to pinpoint the cause:

Code: Select all

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
It specifically says "Exception was unhandled", so I assume there is a way to handle the exception. However when I put a try-catch statement around the large region of code where it happens, it simply gets ignored. I've tried catch(...), catch(std::runtime_error &e) and catch(std::exception &e), but nothing worked.

So how am I supposed to handle the exception, to at least prevent a reboot if I don't find the cause? Is it actually possible in Arduino IDE (using Arduino-ESP32 2.0.3 right now, with the code running on a ESP32-S3)

Edit: Pinpointing the cause is also hard because the backtrace is just one entry and it says corrupted. So ESP Exception Decoder doesn't show a line where it happens. So don't suggest I should use ESP Exception Decoder.

ESP_Sprite
Posts: 9764
Joined: Thu Nov 26, 2015 4:08 am

Re: How to handle exceptions (e.g. LoadProhibited)?

Postby ESP_Sprite » Thu Jul 28, 2022 1:14 am

Yeah, that sucks, sorry. You could technically (although that would require rebuilding the Arduino libraries) hook the exception, but it wouldn't help much: in the end, this is a bug somewhere and ignoring it will likely make more stuff fall over in unpredictable ways. If you used ESP-IDF, you could use a debugger to see if that could eke out more info, but that's not really available in Arduino.

ESP_Dazz
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: How to handle exceptions (e.g. LoadProhibited)?

Postby ESP_Dazz » Thu Jul 28, 2022 2:33 am

@Miraculix Could you post a copy of the error log (including the CPU register dump). Those might provide a few clues as to what's happening. Or if you like to have a go at it yourself, the IDF Fatal Errors Guide explains how to read those Guru Meditation Errors.

Miraculix
Posts: 20
Joined: Wed Sep 16, 2020 9:43 am

Re: How to handle exceptions (e.g. LoadProhibited)?

Postby Miraculix » Thu Jul 28, 2022 1:46 pm

Ah ok. So it doesn't work like that with Arduino-ESP32. Do try/catch statements work at all? Or just not with exceptions?

Will post the error log when it happens again. For some weird reason it didn't happen in the past few hours however. It's one of those exceptions which don't always happen, likely while parsing text received every 5 minutes from a radio module (NRF24L01+). I just remember EXCVADDR was always either 0x00000001 or 0xff000000. And I have no idea which part of the code would try to read from that address.

Anyway, getting closer to finding the problem. Would probably have found it faster if try-catch statements worked. It's likely a problem with a lambda function which captured the reference of a Arduino string instead of the string itself, while the code of the lambda function gets executed 1 to 10 milliseconds later in another task, when the string is already gone.
Last edited by Miraculix on Thu Jul 28, 2022 9:39 pm, edited 6 times in total.

Miraculix
Posts: 20
Joined: Wed Sep 16, 2020 9:43 am

Re: How to handle exceptions (e.g. LoadProhibited)?

Postby Miraculix » Thu Jul 28, 2022 9:26 pm

Also, what means "<- CORRUPTED" in a backtrace? That the stack pointer may be messed up? The docs don't seem to explain it

ESP_Sprite
Posts: 9764
Joined: Thu Nov 26, 2015 4:08 am

Re: How to handle exceptions (e.g. LoadProhibited)?

Postby ESP_Sprite » Fri Jul 29, 2022 2:31 am

A C++ exception is something else than a hardware exception, even if they share the same name. A C++ exception is thrown by software (you throw them if something goes wrong inside an api, for instance) while a hardware exception is thrown, well, by the hardware. It's the equivalent of a general protection failure on Windows or a segfault on Linux/Unix; you get them when e.g. you dereference a null pointer. That also explains why you can't catch hardware exceptions with things intended for C++ exceptions: they're different beasts.

When the exception happens, the default handler will try to show a backtrace of the call chain of functions leading up to the error. It does that (roughly speaking) by following stack frames: a register contains the address of the stack frame of the calling function, which contains a pointer to the stack frame of its own calling function, which contains a pointer to... you get the gist. The 'CORRUPTED' message means that something the pointer expected to be pointing at the previous stack frame, contains something invalid, e.g. a pointer to an unused address or a null pointer. As such, it can't follow the linked list any longer.

So normally, the stack trace would have shown you the location where the code tried to read from the already-written object. It looks like it tried to write there first, though, and inadvertently corrupted the stack, corrupting the stack frame that allows the software to get that backtrace. Bad luck I guess.

Who is online

Users browsing this forum: No registered users and 96 guests