<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body bgcolor="#ffffff" text="#000000">
It was failing hard with the latest changes on loading Windows DLLs, so
I looked into it.<br>
<br>
I don't see how it ever could have worked.<br>
<br>
Note that DLLs link with gcstub.obj, this is because DLLs share the gc
with the caller's gc, instead of having a separate gc that fights the
caller's. The general idea is that upon initialization the DLL sets
"proxy" to point to the caller's gc, and then all gc calls are routed
through the proxy.<br>
<br>
First, in our DLL's DllMain(), we call:<br>
<br>
<tt> case DLL_PROCESS_ATTACH:<br>
dll_process_attach(hInstance);</tt><br>
<br>
In dll_process_attach(), druntime calls:<br>
<br>
<tt> Runtime.initialize()</tt><br>
<br>
which calls:<br>
<br>
<tt> rt_init(null)</tt><br>
<br>
which calls:<br>
<br>
<tt> gc_init();<br>
initStaticDataGC();</tt><br>
<br>
which calls:<br>
<br>
<tt> gcstub.gc.gc_addRange()</tt><br>
<br>
which looks like:<br>
<br>
<tt>extern (C) void gc_addRange( void* p, size_t sz )<br>
{<br>
printf("gcstub::gc_addRange() proxy = %p\n", proxy);<br>
if( proxy is null )<br>
{<br>
Range* r = cast(Range*) realloc( ranges,<br>
(nranges+1) * ranges[0].sizeof
);<br>
if( r is null )<br>
onOutOfMemoryError();<br>
r[nranges].pos = p;<br>
r[nranges].len = sz;<br>
ranges = r;<br>
++nranges;<br>
}<br>
return proxy.gc_addRange( p, sz );<br>
}</tt><br>
<br>
which will ALWAYS crash because proxy is null. But we never notice the
crash, because rt_init() ignores exceptions when dg is null, as in:<br>
<br>
<tt> catch (Throwable e)<br>
{<br>
if (dg)<br>
dg(e);<br>
}</tt><br>
<br>
and things then proceed with a half-crashed uninitialized runtime.<br>
<br>
<b>Bugs:</b><br>
<br>
1. proxy is null. It is supposed to be initialized by rt_loadLibrary().
But, sadly, it dll_process_attach() gets called first by LoadLibrary()!
Disaster.<br>
<br>
2. gcstub's gc_addRange() and gc_addRoot() will always crash if proxy
is null.<br>
<br>
3. gc_isCollecting() needs to be added to gcstub.gc. Otherwise, the
linker mixes in gcstub with the regular gc in a truly frankensteinian
mess.<br>
<br>
4. rt_init() should not ignore exceptions when dg is null, it should
rethrow them.<br>
<br>
<br>
<br>
</body>
</html>