https://issues.dlang.org/show_bug.cgi?id=14824
ponce <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |[email protected] --- Comment #1 from ponce <[email protected]> --- I'm hitting a very similar bug on OS X 10.10.4, let me explain. == Setup == Here the host program source. What it does is: - for each dynlib in command line: - load dynlibs - call the VSTPluginMain function if it exist, - unload it --------------------- ldvst.cpp -------------------- #include <dlfcn.h> #include <cstdio> #include <cstring> #include <vector> typedef __cdecl void* (*VSTPluginMain_t)(void*); int main(int argc, char**argv) { std::vector<char*> dllPaths; if (argc < 2) { printf("usage: ldvst [-lazy] <thing.vst>\n"); return 1; } bool lazy = false; for (int i = 1; i < argc; ++i) { char* arg = argv[i]; if (strcmp(arg, "-lazy") == 0) lazy = true; else if (strcmp(arg, "-now") == 0) lazy = false; else dllPaths.push_back(arg); } for (int i = 0; i < dllPaths.size(); ++i) { char* dllPath = dllPaths[i]; printf("dlopen(%s)\n", dllPath); void* handle = dlopen(dllPath, lazy ? RTLD_LAZY : RTLD_NOW); if (handle == NULL) { printf("error: dlopen of %s failed\n", dllPath); return 2; } VSTPluginMain_t VSTPluginMain = (VSTPluginMain_t) dlsym(handle, "VSTPluginMain"); printf("dlsym returned %p\n", (void*)VSTPluginMain); if (VSTPluginMain != NULL) { void* result = VSTPluginMain(NULL); printf("VSTPluginMain returned %p\n", result); } printf("dlclose(%s)\n\n", dllPath); dlclose(handle); } return 0; } ----------------------------------------------------- The host is compiled with: $ clang++ ldvst.cpp -o ldvst-cpp Here the whole dynlib source: ----------------- distort.d ------------------------- extern(C) void* VSTPluginMain(void* hostCallback) { import core.runtime; Runtime.initialize(); import std.stdio; import core.stdc.stdio; printf("Hello !\n"); Runtime.terminate(); return null; } ------------------------------------------------------ This dynlib can be built with ldc: $ ldc2 -shared -oflibdistort.so -g -w -I. distort.d -relocation-model=pic or with dmd $ dmd -c -ofdistort.o -debug -g -w -version=Have_distort -I. distort.d -fPIC $ dmd -oflibdistort.so distort.o -shared -g For the purpose of demonstration you need another C dynlib, for example /System/Library/Frameworks/Cocoa.framework/Cocoa on OS X. Now the bug triggers when calling: == How to reproduce == $ ldvst-cpp libdistort.so => works $ ldvst-cpp libdistort.so libdistort.so => works $ ldvst-cpp /System/Library/Frameworks/Cocoa.framework/Cocoa libdistort.so => works $ ldvst-cpp libdistort.so /System/Library/Frameworks/Cocoa.framework/Cocoa => FAIL, and that's precisely the case that happen in production :( $ ldvst-cpp /System/Library/Frameworks/Cocoa.framework/Cocoa libdistort.so /System/Library/Frameworks/Cocoa.framework/Cocoa => works In other words, if the host program loads a D dynlib first, then a C dynlib, then the second dlopen fail. This has eluded me for a complete month. --
