Skip to content

Commit 2ec4dc8

Browse files
committed
[Macros] Don't dlclose InProcessPluginServer shared library
llvm::DynamicLibrary does dlclose on all the libraries when global destructor runs. Which causes dangling pointers if the library contains Swift code. rdar://131048379
1 parent 915b531 commit 2ec4dc8

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

include/swift/AST/PluginRegistry.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "llvm/ADT/StringMap.h"
1818
#include "llvm/ADT/StringRef.h"
1919
#include "llvm/Support/Chrono.h"
20-
#include "llvm/Support/DynamicLibrary.h"
2120
#include "llvm/Support/Error.h"
2221
#include "llvm/Support/Program.h"
2322

@@ -98,8 +97,8 @@ class CompilerPlugin {
9897

9998
/// Represents a in-process plugin server.
10099
class InProcessPlugins : public CompilerPlugin {
101-
/// PluginServer
102-
llvm::sys::DynamicLibrary server;
100+
/// PluginServer shared library handle.
101+
void *server;
103102

104103
/// Entry point in the in-process plugin server. It receives the request
105104
/// string and populate the response string. The return value indicates there
@@ -114,7 +113,7 @@ class InProcessPlugins : public CompilerPlugin {
114113
/// Temporary storage for the response data from 'handleMessageFn'.
115114
std::string receivedResponse;
116115

117-
InProcessPlugins(llvm::StringRef serverPath, llvm::sys::DynamicLibrary server,
116+
InProcessPlugins(llvm::StringRef serverPath, void *server,
118117
HandleMessageFunction handleMessageFn)
119118
: CompilerPlugin(serverPath), server(server),
120119
handleMessageFn(handleMessageFn) {}

lib/AST/PluginRegistry.cpp

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#if defined(_WIN32)
2929
#define WIN32_LEAN_AND_MEAN
3030
#define NOMINMAX
31+
#include "llvm/Support/ConvertUTF.h"
32+
#include "llvm/Support/Windows/WindowsSupport.h"
3133
#include <windows.h>
3234
#else
3335
#include <dlfcn.h>
@@ -41,6 +43,46 @@
4143

4244
using namespace swift;
4345

46+
namespace {
47+
void *loadLibrary(const char *path, std::string *err);
48+
void *getAddressOfSymbol(void *handle, const char *symbol);
49+
50+
#if defined(_WIN32)
51+
void *loadLibrary(const char *path, std::string *err) {
52+
SmallVector<wchar_t, MAX_PATH> pathUnicode;
53+
if (std::error_code ec = llvm::sys::windows::UTF8ToUTF16(path, pathUnicode)) {
54+
SetLastError(ec.value());
55+
llvm::MakeErrMsg(err, std::string(path) + ": Can't convert to UTF-16");
56+
return nullptr;
57+
}
58+
59+
HMODULE handle = LoadLibraryW(pathUnicode.data());
60+
if (handle == NULL) {
61+
llvm::MakeErrMsg(err, std::string(path) + ": Can't open");
62+
return nullptr;
63+
}
64+
return (void *)handle;
65+
}
66+
67+
void *getAddressOfSymbol(void *handle, const char *symbol) {
68+
return (void *)uintptr_t(GetProcAddress((HMODULE)handle, symbol));
69+
}
70+
71+
#else
72+
void *loadLibrary(const char *path, std::string *err) {
73+
void *handle = ::dlopen(path, RTLD_LAZY | RTLD_LOCAL);
74+
if (!handle)
75+
*err = ::dlerror();
76+
return handle;
77+
}
78+
79+
void *getAddressOfSymbol(void *handle, const char *symbol) {
80+
return ::dlsym(handle, symbol);
81+
}
82+
83+
#endif
84+
} // namespace
85+
4486
PluginRegistry::PluginRegistry() {
4587
dumpMessaging = ::getenv("SWIFT_DUMP_PLUGIN_MESSAGING") != nullptr;
4688
}
@@ -54,13 +96,13 @@ CompilerPlugin::~CompilerPlugin() {
5496
llvm::Expected<std::unique_ptr<InProcessPlugins>>
5597
InProcessPlugins::create(const char *serverPath) {
5698
std::string err;
57-
auto server = llvm::sys::DynamicLibrary::getLibrary(serverPath, &err);
58-
if (!server.isValid()) {
99+
auto server = loadLibrary(serverPath, &err);
100+
if (!server) {
59101
return llvm::createStringError(llvm::inconvertibleErrorCode(), err);
60102
}
61103

62104
auto funcPtr =
63-
server.getAddressOfSymbol("swift_inproc_plugins_handle_message");
105+
getAddressOfSymbol(server, "swift_inproc_plugins_handle_message");
64106
if (!funcPtr) {
65107
return llvm::createStringError(llvm::inconvertibleErrorCode(),
66108
"entry point not found in '%s'", serverPath);

0 commit comments

Comments
 (0)