Thread overview
Half-baked thought: Out-of-process asserts
Sep 04, 2018
Neia Neutuladh
Sep 04, 2018
H. S. Teoh
Sep 04, 2018
Arjan
September 03, 2018
It seems pretty well established around here that:

1. Doing anything after a process has entered an unknown state is dangerous, and the more activity, the more danger (Note also, the transition to an unknown state actually occurs *before* any assert which is intended to detect it.)

2. For practical reasons, some things currently still need to be done in the process which is already in an invalid state: Evaluating the assert in the first place, generating a diagnostic message, generating the stack trace, etc...

What if a compiler (or library, standard tool, etc...) could automatically add an additional separate OS process to the program (or perhaps some other form of encapsulation that would isolate it from any corruption in the main process), and it is in this separate process where the compiler would insert the code responsible for one or more of the following:

- Generating stack traces upon detection of an assert failure (or bounds-check violation, or out-of-memory, etc).
- Formatting the custom assert failure string.
- Anything additional data gathering? Like a core dump?
- Display/log/report these diagnostics.
- Optionally restart the main process, depending on the type of program.
- Maybe even *performing* the assert/etc. checks by closely monitoring the main process and being aware of its state and memory layout.

The idea of course being to even further minimizing the work the errant process needs to do.

Discussion questions:
- What would be the feasibility of the various parts of this?
- Would this be an improvement or not?
- What would be the downsides, and how serious would they be?
September 04, 2018
On Tuesday, 4 September 2018 at 03:39:04 UTC, Nick Sabalausky (Abscissa) wrote:
> Discussion questions:
> - What would be the feasibility of the various parts of this?

You'd need to interrupt the process. You'd need a parent process that detects the interrupt. Then you'd need to use the debugger API to attach to the child process and get the relevant data.

Annoying to write, but it should work, assuming the child process didn't install a signal handler to handle SIGABRT.

You could simply call SIGABRT and create a core dump, but that can be costly on a system where your application might use multiple gigabytes of RAM.

> - What would be the downsides, and how serious would they be?

It's extra complexity. It means you must run in a multiprocessing environment (which is almost, but not quite, a trivial requirement). If you're running as a user without debugger privileges, you're horked; you aren't getting an error message at all.

The benefit is that you can safely do more elaborate logging when more of your runtime and base frameworks are in an invalid state. I think most people are happy to live dangerously or to go with simpler logging.
September 04, 2018
On Mon, Sep 03, 2018 at 11:39:04PM -0400, Nick Sabalausky (Abscissa) via Digitalmars-d wrote:
> It seems pretty well established around here that:
> 
> 1. Doing anything after a process has entered an unknown state is dangerous, and the more activity, the more danger [...]
> 
> 2. For practical reasons, some things currently still need to be done in the process which is already in an invalid state: Evaluating the assert in the first place, generating a diagnostic message, generating the stack trace, etc...
> 
> What if a compiler (or library, standard tool, etc...) could automatically add an additional separate OS process to the program (or perhaps some other form of encapsulation that would isolate it from any corruption in the main process), [...]
[...]

This is an interesting idea.  At least on Posix systems, this monitor process could attach to the main process via the debugging mechanism (the same way utilities like strace or gdb can attach to an existing process), and use SIGSTOP to suspend the process when a problem is detected, extract stacktraces and other info, and use SIGKILL / SIGABRT / etc. to terminate the program.

I've seen similar this actually implemented manually in the form of a set of cooperating processes, though this is the first time I've heard of the compiler automatically generating this sort of code.

Possible wrinkles in the works are debugging privileges, which the monitor process may not have, which would limit the kind of information you could monitor / extract from the terminated process.  It's probably possible, if coredumps are turned on, to extract the stacktrace from the coredump file directly, so you wouldn't need debugging privileges.  But you wouldn't be able to monitor the process independently without explicit cooperation unless you had debug privileges (like reading the process's memory).  Still, even an explicit scheme could be useful, e.g., a pipe of some sort that the main process writes status codes to, and the monitor process reads from it and suspends / terminates the main process if anything looks out-of-place.  But this may be much harder to automatically generate code for.


T

-- 
Let's call it an accidental feature. -- Larry Wall
September 04, 2018
On Tuesday, 4 September 2018 at 03:39:04 UTC, Nick Sabalausky (Abscissa) wrote:
> It seems pretty well established around here that:
>
> 1. Doing anything after a process has entered an unknown state is dangerous, and the more activity, the more danger (Note also, the transition to an unknown state actually occurs *before* any assert which is intended to detect it.)
>
> [...]

Reminds me of google breakpad: https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/