https://issues.dlang.org/show_bug.cgi?id=16856
--- Comment #10 from Nemanja Boric <4bur...@gmail.com> --- Ok, I finally got some time to get back to this issue. There's a sigbus really running, but this is caused by GC, because the runtime asserts in the shared library finalizers, so it seems that the instance is no longer there. I've traced the failing druntime assert (so far, who knows what else is waiting for us) to this particular commit in rtld.c: https://github.com/freebsd/freebsd/commit/3ff2e66ecba2094f5c1c1efe7f2d009649527195 So, this is the problem. At the end of the program, fini()s are called for the shared library and the main executable. Then they call `_do_global_dtors_aux`, and at that point they will call _d_dso_registry, which will (the problem is here:) call dlopen (albeit with RTLD_NOLOAD) to obtain the handle for the object by name. However, since this particular commit, this doesn't work anymore (and it's questionable if it should work) - you can't bump a reference count of an object that's just going to die (dlopen still bumps reference count, even with RTLD_LOAD passed). I would guess somehow skipping dlopen calls in this scenario should be figured out. Maybe skipping just for the current object, or maybe caching the handles when first obtained (not sure if they can change on their own; I don't think so, but still). I'll see to submit a PR tomorrow, now I know where the problem is. It was quite a ride finding this out. Because first call to dlopen was failing for the main executable, so documentation says: "use NULL if you want the main executable instead", so after doing this - I got it working, so I thought there's something special with this path. What's interesting is that my confusion is caused by the bug in FreeBSD's code - if the current limitation apply - don't reference "doomed" object, one shouldn't be able to work around it by passing NULL. I'll see into sending a patch there as well. --