C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Exceptions : lost all hope -- do not resuscitate

From: Jonathan Grant <jgrantonline_at_[hidden]>
Date: Sat, 6 Jun 2026 22:02:27 +0100
On 06/06/2026 19:03, Frederick Virchanza Gotham via Std-Proposals wrote:
> In my work this week, I submitted a pull request containing code like this:
>
> struct S {
> optional<T> var;
> void reset(void) noexcept
> {
> lock_guard mylock{some_global_mutex};
> var.reset();
> }
> }
>
> The pull request went through code review, and a colleague of mine
> responded to say:
>
> "You've marked that function 'noexcept' but 'mutex::lock' might throw"
>
> My response to him was:
>
> "If a mutex fails to lock, the entire process is fried"
>
> Mulling over this for a bit longer, I think that the Standard should
> make a distinction between "normal exceptions" and "lost-all-hope
> exceptions".
>
> For instance if you think a mutex might ever fail to lock in your
> program, I think you should do something like the following:
>
> Step 1 - When the process starts, use 'std::fopen' to open a file on
> disk for writing.
> Step 2 - Invoke 'std::set_terminate_handler' to register a handler
> that writes critical data to disk with 'std::fwrite', then
> 'std::fclose', and then invokes 'std::_Exit' to immediately kill the
> process.
> Step 3 - Mark the aforementioned 'S::reset' method as 'noexcept', and
> just let the terminate handler save critical data if 'mutex::lock'
> throws.
>
> I don't think it's good enough that the Standard simply says that
> 'mutex::lock' might throw 'std::system_error', reason being that this
> isn't something you can just catch and recover from. If a mutex fails
> to lock, you need to do one of the two following:
>
> Strategy 1 - Kill the entire process like I described above (i.e. let
> the terminate handler save critical data and call 'std::_Exit').
>
> Strategy 2 - If not killing the entire process, at least mark a
> portion of the program as unusable -- and this is where I would use a
> "Do not resuscitate" flag (i.e. a DNR flag).
>
> A few years ago when I was programming security cameras in embedded
> Linux, there was a background process that managed the mounting of an
> encrypted volume. Sometimes the encrypted volume would spontaneously
> unmount. We found that if you ever re-mounted the volume after it
> spontaneously unmounted, you would get unreliable behaviour and data
> corruption. For this reason I introduced a 'Do not resuscitate' flag.
> If the encrypted volume were ever to spontaneously unmount, and as
> soon as this was detected, the DNR flag would be set -- meaning that
> the next time a script tried to mount the encrypted volume, the DNR
> flag would forbid its re-mount. This strategy minimised data
> corruption.

For functional safety, it might need to signal another circuit to take over control of the camera. Of course this one could reboot and see if it could re-mount, given the kernel has a corruption bug a reboot might clear it.

>
> I don't think C++ programmers should be accommodating the throwing of
> 'std::system_error' from 'mutex::lock', for example by refraining from
> marking 'S::reset' as 'noexcept'. Instead, C++ should have two
> categories of exception -- normal exceptions and lost-all-hope
> exceptions. So if you were to look up "mutex::lock" on
> 'cppreference.com', instead of it saying:
>
> "Throws std::system_error when errors occur, including errors from the
> underlying operating system that would prevent lock from meeting its
> specifications. The mutex is not locked in the case of any exception
> being thrown."
>
> Perhaps it would say something like:
>
> "Invokes the 'lost_all_hope' terminate handler when errors occur,
> including errors from the underlying operating system that would
> prevent lock from meeting its specifications."

std::system_error might mean some memory corruption of the handle, or pthreads has some issue, there's less C++ can do if the OS or HW has a serious issue.

Don't applications have a top level catch for std::system_error, or even std::exception? That could call a lost_all_hope() function. Which might close modules and rerun, or even relaunch the application.. or hand over to another circuit to handle a critical function.

Regards
Jonathan

Received on 2026-06-06 21:02:31