On Sunday, 4 May 2014 at 10:28:30 UTC, Mike Parker wrote:
On 5/4/2014 6:42 PM, Alex wrote:
Hello,

I am trying to use the std.log module that is here:

https://github.com/linkrope/log.d

And I encountered a segmentation fault using dmd 2.065 on a Linux 64
platform. The reduced test case is this:

//============================================================================

import std.stdio;
import std.log;

private class CHello {

    ~this() {
info("info - destructor"); //info, warning, error segfault;
however, writefln works
    }
}

void main(string[] args) { CHello chello = new CHello(); }
//============================================================================


Is this a bug?

No, it is not a bug. It's a hazard of destructors in D.

Because of the GC, there are certain things you cannot rely on when it comes to destruction. One is that there is no guarantee that the destructor will ever be called during the lifetime of the app. The second, and likely the problem you're seeing, is that you cannot rely on the order of destruction.

If you look at the source for std.log, you'll see that info() ultimately (via some templating) maps to an instance of LogFilter, which is a class allocated on the GC heap in a module constructor. When the app exits, one of the last things DRuntime does is to terminate the GC (see rt_term in dmain2.d in the DRuntime source). The current implementation of the GC will run destructors on any objects still resident on the heap during termination. There is no way to guarantee the order in which those destructors will be run.

Most likely, what you're seeing is that the LogFilter instance referenced by the info template is being destroyed before the destructor on CHello is run. Therefore, you're referencing an invalid memory location.

The short of it is that you should never touch anything on that lives on the GC heap from inside a destructor -- there's no guarantee that it will still be alive when your destructor is run.

Thank you, but I find it to be quite awkward. Why the compiler does not complain or, at least, give a more meaningful runtime error message? Is there any official std.log that is destructor-safe?

Reply via email to