mirror of
https://github.com/corda/corda.git
synced 2025-01-04 04:04:27 +00:00
Fixes dynamic symbol loading bug on Mac OS X.
On OS X, when you call dlopen() on a null library, and then call dlsym(), the most recently loaded symbols are always used, no matter what flags we seem to pass to dlopen(). The solution is to explicitly find the name of the running executable, and open that as a library.
This commit is contained in:
parent
d68c2e6e2c
commit
c1f3d28d24
2
makefile
2
makefile
@ -82,7 +82,7 @@ endif
|
||||
ifeq ($(platform),darwin)
|
||||
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
||||
-I$(JAVA_HOME)/include/linux -I$(src)
|
||||
lflags = $(common-lflags) -ldl
|
||||
lflags = $(common-lflags) -ldl -framework CoreFoundation
|
||||
strip-all = -S -x
|
||||
binaryToMacho = $(native-build)/binaryToMacho
|
||||
endif
|
||||
|
@ -1,3 +1,6 @@
|
||||
#ifdef __APPLE__
|
||||
#include "CoreFoundation/CoreFoundation.h"
|
||||
#endif
|
||||
#include "sys/mman.h"
|
||||
#include "sys/types.h"
|
||||
#include "sys/stat.h"
|
||||
@ -116,6 +119,27 @@ allocate(System* s, unsigned size)
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
pathOfExecutable(System* s, const char** retBuf, unsigned* size)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
CFBundleRef bundle = CFBundleGetMainBundle();
|
||||
CFURLRef url = CFBundleCopyExecutableURL(bundle);
|
||||
CFStringRef path = CFURLCopyPath(url);
|
||||
CFIndex pathSize = CFStringGetMaximumSizeOfFileSystemRepresentation(path);
|
||||
char* buffer = reinterpret_cast<char*>(allocate(s, pathSize));
|
||||
if (CFStringGetFileSystemRepresentation(path, buffer, pathSize)) {
|
||||
*size = pathSize;
|
||||
*retBuf = buffer;
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
#else
|
||||
*size = 0;
|
||||
*retBuf = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const bool Verbose = false;
|
||||
|
||||
const unsigned Waiting = 1 << 0;
|
||||
@ -646,6 +670,7 @@ class MySystem: public System {
|
||||
bool mapName)
|
||||
{
|
||||
void* p;
|
||||
bool alreadyAllocated = false;
|
||||
unsigned nameLength = (name ? strlen(name) : 0);
|
||||
if (mapName) {
|
||||
unsigned size = nameLength + 3 + sizeof(SO_SUFFIX);
|
||||
@ -653,6 +678,10 @@ class MySystem: public System {
|
||||
snprintf(buffer, size, "lib%s" SO_SUFFIX, name);
|
||||
p = dlopen(buffer, RTLD_LAZY);
|
||||
} else {
|
||||
if (!name) {
|
||||
pathOfExecutable(this, &name, &nameLength);
|
||||
alreadyAllocated = true;
|
||||
}
|
||||
p = dlopen(name, RTLD_LAZY);
|
||||
}
|
||||
|
||||
@ -665,6 +694,9 @@ class MySystem: public System {
|
||||
if (name) {
|
||||
n = static_cast<char*>(allocate(this, nameLength + 1));
|
||||
memcpy(n, name, nameLength + 1);
|
||||
if (alreadyAllocated) {
|
||||
free(name, nameLength, false);
|
||||
}
|
||||
} else {
|
||||
n = 0;
|
||||
}
|
||||
|
@ -134,6 +134,7 @@ expect(System* s, bool v)
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
||||
# undef assert
|
||||
# define assert(a, b)
|
||||
|
||||
#else // not NDEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user