Problems with shared library (-fPIC) and tango

Sean Kelly sean at invisibleduck.org
Fri Oct 24 14:41:12 PDT 2008


Thomas Leonard wrote:
> On Thu, 23 Oct 2008 19:59:30 -0700, Sean Kelly wrote:
>> Thomas Leonard wrote:
>>> On Sun, 06 Jul 2008 03:31:44 +0000, Sean Kelly wrote:
>>>> == Quote from e-t172 (e-t172 at akegroup.org)'s article
>>>>> IIRC, there is only one problem when trying to build Tango with -fPIC
>>>>> : the garbage collector, which segfaults on collection. Fix the GC
>>>>> and you have your Tango shared library.
>>>> I believe this is an issue with the static data segments not being
>>>> represented in the way that the GC expects in a shared library.  I
>>>> really need to do some research to figure out how things are different
>>>> in this instance.  Though if someone knows then that would be good too
>>>> :-)
>>> Could that be why this program crashes?
>>>
>>> import std.gc: fullCollect;
>>> import mi = std.moduleinit;
>>>
>>> int main(string[] args) {
>>> 	//printf("%p\n", mi._moduleinfo_dtors[6]); fullCollect();
>>>
>>> 	return 0;
>>> }
>>>
>>> If I uncomment the printf line, it works (I guess because the address
>>> gets left on the stack). Without calling fullCollect() explicitly, my
>>> programs work until the GC gets called, then they crash.
>>>
>>> I'm using a (rather modified) GDC on Linux, with libgphobos2 as a
>>> shared library.
>>>
>>> How are module variables like _moduleinfo_dtors supposed to get
>>> registered as roots with the GC?
>> The shared data segment(s) of a binary are identified by the runtime at
>> startup and the runtime passes them to the GC for scanning.  For
>> example, look at initStaticDataPtrs() in this file:
>>
>> http://dsource.org/projects/tango/browser/trunk/lib/compiler/gdc/
> memory.d
>> However, I think the way that the static data segment is identified in a
>> shared library is different from in an executable app.  I'm pretty sure
>> the Boehm GC handles this properly and have been meaning to look at it
>> for clues, but that hasn't made it to the top of my priority list yet.
> 
> Ah, thanks for the hints. I found some disabled code in gcgcc.d that 
> tried to scan /proc/self/maps, and with a bit of tweaking it now works 
> for me (tested on x86_64):
> 
> http://repo.or.cz/w/delight/core.git?
> a=commitdiff;h=83befaa3f72973eb8afd8589d2e1cee4b37ee4fb;hp=03f581cf37409b35521bcfd6f239a14f1fa73221

Cool!  I'll see about integrating these changes into druntime.

> BTW, would it be possible to get rid of this moduleinfo stuff? It seems 
> to cause a lot of problems, because when a program imports a library it 
> might not use exactly the same flags that were used when the library was 
> compiled (e.g. program is compiled with unit-tests, library wasn't). So 
> the program might try to use the moduleinfo, even though it doesn't 
> actually exist.

I don't think there's any way around moduleinfo in general, since it's 
the way that static ctors and dtors are called.  However, I'd expect 
everything to work correctly regardless of the flags passed because the 
runtime code simply iterates across a list of ModuleInfo objects and 
calls whatever functions it needs to (after checking if the function 
pointers are non-null).

> Doesn't the dynamic linker already provide for calling static 
> initialisers? I'm not sure.

Possibly the static initializers that C uses, if any, but not the D 
initializers.  However, I've started working on some new runtime 
functions to do dynamic loading and unloading of libraries on druntime, 
and this will do everything needed to properly initialize the library.


Sean



More information about the Digitalmars-d mailing list