digitalmars.D - Why does logging in destructor lead to segmentation fault?
- Vladimir Marchevsky (3/3) Sep 11 2023 https://run.dlang.io/is/NMMpLn - minimal example. Debugging on
- cc (15/18) Sep 11 2023 ```
- Bradley Chatha (16/19) Sep 11 2023 Generally you shouldn't access anything to do with the GC (or
- Vladimir Marchevsky (10/16) Sep 11 2023 What's confusing me is that debugger stops exactly on
https://run.dlang.io/is/NMMpLn - minimal example. Debugging on Windows, it crashes on `synchronized(mutex)` with "Access violation" trying to read at zero address.
Sep 11 2023
On Monday, 11 September 2023 at 17:31:17 UTC, Vladimir Marchevsky wrote:https://run.dlang.io/is/NMMpLn - minimal example. Debugging on Windows, it crashes on `synchronized(mutex)` with "Access violation" trying to read at zero address.``` core.exception.InvalidMemoryOperationError src\core\lifetime.d(126): Invalid memory operation ``` `log()` allocates on the GC apparently, which can't occur when the druntime is being torn down and everything being finalized on program termination. ```d ~this() { printf("inFinalizer: %d\n", GC.inFinalizer); if (!GC.inFinalizer) log("dtor"); } ```
Sep 11 2023
On Monday, 11 September 2023 at 17:31:17 UTC, Vladimir Marchevsky wrote:https://run.dlang.io/is/NMMpLn - minimal example. Debugging on Windows, it crashes on `synchronized(mutex)` with "Access violation" trying to read at zero address.Generally you shouldn't access anything to do with the GC (or even really global state, such as the `sharedLogger`) within a dtor. What's happening is that the GC is running the dtors for all objects after the main function's finished in a final cleanup, which prevents you from allocating any GC memory without crashing. Potentially as well the GC has already cleaned up the `sharedLogger` causing the null read. If you look at this example: https://run.dlang.io/is/PvyfOc By making the class instance `scope` the class is allocated on the stack, and dtor-ed immediately after the function ends, rather than when DRuntime is finalising, which prevents the crash from occurring. It's a bit of an annoying, weird quirk.
Sep 11 2023
On Monday, 11 September 2023 at 18:08:45 UTC, Bradley Chatha wrote:What's happening is that the GC is running the dtors for all objects after the main function's finished in a final cleanup, which prevents you from allocating any GC memory without crashing. Potentially as well the GC has already cleaned up the `sharedLogger` causing the null read.What's confusing me is that debugger stops exactly on `synchronized(mutex)` line inside of `log` implementation. Does this operation allocate any GC memory?.. Also looking through locals in debugger, logger object seems to be fine (otherwise it would crash earlier, I guess?.. At least, `this` points to something at non-zero address), `mutex` looks alive as well. Isn't it wrong to have something garbage-collected while object containing it is still alive?
Sep 11 2023