Subject: Re: dlopen(0, RTLD_LAZY) doesn't work?
From: Kent Watsen <[email-masked]>
To: Charles Wilson <[email-masked]>
Cc: Stephano Mariani <[email-masked]>, [email-masked]
Date: Fri, 08 Feb 2002 12:10:53 -0800

True, the second parameter is ignored by cygwin's dlopen(), but I did
reproduce the exact same problem using win32's GetModuleHandle()
and GetProcAddress() - the bug is not in the code but the compiler.

The code works fine when compiled on linux via "gcc -rdynamic foo.c -ldl"
or "gcc -export-dynamic foo.c -ldl."  On Cygwin, it is not necessary to
specify -ldl and its not possible to specify -rdynamic (why not?).  But 
alas,
when I compile on Cygwin using "gcc -export-dynamic foo.c", the code
still doesn't work - so I think the cygwin's compiler is broken.

Kent

Charles Wilson wrote:

> Use the (kernel) source, luke.
>
> In winsup/cygwin/include/dlfcn.h, you see a comment that "the 
> following don't exist in win32 API".  Since cygwin's dlopen stuff is 
> built on top of windows shared lib (DLL) support, the definitions 
> which appear in that header file:
>
> #define RTLD_LAZY   1
> #define RTLD_NOW    2
> #define RTLD_GLOBAL 4
>
> have zero effect in cygwin's dlopen.
>
> Even better, looking at winsup/cygwin/dlfcn.cc, you can see that the 
> function definition doesn't even assign the second argument to a 
> variable:
>
> void *
> dlopen (const char *name, int)
> {
> ...
> }
>
> RTLD_LAZY is not supported. QED.
>
> --Chuck
>
>
> Stephano Mariani wrote:
>
>> In my experience, this is probably because the linker (or cc1) insists
>> on eliminating "dead code", since it is never (directly) called.
>>
>> I have managed to overcome this by using:
>>
>> #include <stdio.h>
>> #include <dlfcn.h>
>> #include <windows.h>
>>
>> __declspec(dllexport) void foo(void)
>> {
>>    printf("hello\n");
>> }
>>
>> int main(int argc, char *argv[])
>> {
>>    void* dl    = NULL;
>>    void* func = NULL;
>>
>>    dl = dlopen(0 , RTLD_LAZY);
>>    if (dl == NULL) {
>>        printf("dlopen() failed\n");
>>        exit(0);
>>    }
>>
>>    func = dlsym(dl, "foo");
>>    if (func == NULL) {
>>        printf("dlsym() failed\n");
>>        exit(0);
>>    }
>>
>>    printf("do something meaningful\n");
>>
>>    dlclose(dl);
>>    return 0;
>> }
>>
>> and compiling with first:
>> gcc -mdll foo.c -c -o ...
>> then linking without -mdll:
>> gcc foo.o ... -o foo
>>
>>
>> Note: I have not tried this, but I have previously used
>> dlopen(NULL,RTLD_LAZY) successfully. Also, I do not think that you can
>> call printf() without first attaching to the console within your
>> dlopened routine.
>>
>> Stephano Mariani
>>
>> -----Original Message-----
>> From: [email-masked] [mailto:[email-masked]] On Behalf
>> Of Kent Watsen
>> Sent: Thursday, 7 February 2002 2 57
>> To: [email-masked]
>> Subject: Re: dlopen(0, RTLD_LAZY) doesn't work?
>>
>>
>> OK, so I've written the windows equivalent of my original program
>> and still get the same error - is there some linking option I'm missine?
>>
>> Here is the new code, again just compile (gcc foo.c) and run (foo.exe):
>>
>> #include <stdio.h>
>> #include <windows.h>
>>
>> extern __declspec(dllexport) void foo(void)
>> {
>>     printf("hello\n");
>> }
>>
>> int main(int argc, char *argv[])
>> {
>>     void* dl   = NULL;
>>     void* func = NULL;
>>
>>     dl = (void *) GetModuleHandle (NULL);
>>     if (dl == NULL) {
>>         printf("GetModuleHandle() failed\n");
>>         exit(0);
>>     }
>>
>>     func = (void*)GetProcAddress((HMODULE)dl, "foo");
>>     if (func == NULL) {
>>         printf("GetProcAddress() failed (code %u)\n", GetLastError());
>>         exit(0);
>>     }
>>
>>     printf("do something meaningful\n");
>>
>>     return 0;
>> }
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> Kent Watsen wrote:
>>
>>
>>> Hi,
>>>
>>> I've read the mailing list archives and searched google trying
>>> to figure out how to get the following program to work.  All
>>> you have to do is save it to a file (foo.c), compile (gcc foo.c),
>>> and run - I always get "dlsym() failed."
>>>
>>> Note, I have tried many variations of extern and _declspec
>>> as well as looking for "_foo" in addition to "foo" ("nm a.exe |
>>> grep foo" returned "0040104c T _foo"...
>>>
>>> Here is the code - help would be greatly appreciated - thanks!
>>>
>>> #include <stdio.h>
>>> #include <dlfcn.h>
>>> #include <windows.h>
>>>
>>> extern __declspec(dllexport) void foo(void)
>>> {
>>>   printf("hello\n");
>>> }
>>>
>>> int main(int argc, char *argv[])
>>> {
>>>   void* dl    = NULL;
>>>   void* func = NULL;
>>>
>>>   dl = dlopen(0 , RTLD_LAZY);
>>>   if (dl == NULL) {
>>>       printf("dlopen() failed\n");
>>>       exit(0);
>>>   }
>>>
>>>   func = dlsym(dl, "foo");
>>>   if (func == NULL) {
>>>       printf("dlsym() failed\n");
>>>       exit(0);
>>>   }
>>>
>>>   printf("do something meaningful\n");
>>>
>>>   dlclose(dl);
>>>   return 0;
>>> }
>>>
>>>
>>>
>>>
>>> -- 
>>> Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
>>> Bug reporting:         http://cygwin.com/bugs.html
>>> Documentation:         http://cygwin.com/docs.html
>>> FAQ:                   http://cygwin.com/faq/
>>>
>>>
>>
>>
>>
>> -- 
>> Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
>> Bug reporting:         http://cygwin.com/bugs.html
>> Documentation:         http://cygwin.com/docs.html
>> FAQ:                   http://cygwin.com/faq/
>>
>>
>>
>>
>> -- 
>> Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
>> Bug reporting:         http://cygwin.com/bugs.html
>> Documentation:         http://cygwin.com/docs.html
>> FAQ:                   http://cygwin.com/faq/
>>
>>
>
>
>
> -- 
> Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
> Bug reporting:         http://cygwin.com/bugs.html
> Documentation:         http://cygwin.com/docs.html
> FAQ:                   http://cygwin.com/faq/
>

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/