Skip to content

Commit 72b6e75

Browse files
authored
Merge pull request #2308 from bnbarham/remove-precondition
Avoid crashing when loading client plugins from the same path
2 parents ad842bf + add109d commit 72b6e75

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

Sources/SourceKitD/SourceKitD.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ package enum SKDError: Error, Equatable {
100100
/// `set_notification_handler`, which are global state managed internally by this class.
101101
package actor SourceKitD {
102102
/// The path to the sourcekitd dylib.
103-
package let path: URL
103+
nonisolated package let path: URL
104104

105105
/// The handle to the dylib.
106106
private let dylib: DLHandle

Sources/SwiftSourceKitClientPlugin/ClientPlugin.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,20 @@ public func sourcekitd_plugin_initialize_2(
2828
_ params: sourcekitd_api_plugin_initialize_params_t,
2929
_ sourcekitdPath: UnsafePointer<CChar>
3030
) {
31+
let pluginPath = URL(fileURLWithPath: String(cString: sourcekitdPath))
32+
33+
if SourceKitD.isPluginLoaded {
34+
// When `DYLD_(FRAMEWORK|LIBRARY)_PATH` is set, `dlopen` will first check if the basename of the provided path is
35+
// within any of its search paths. Thus it's possible that only a single library is loaded for each toolchain,
36+
// rather than a separate like we expect. The paths should be equal in this case, since the client plugin is loaded
37+
// based on the path of `sourcekitd.framework` (and we should only have one for the same reason). Allow this case
38+
// and just avoid re-initializing.
39+
precondition(SourceKitD.forPlugin.path == pluginPath)
40+
return
41+
}
42+
3143
SourceKitD.forPlugin = try! SourceKitD(
32-
dylib: URL(fileURLWithPath: String(cString: sourcekitdPath)),
44+
dylib: pluginPath,
3345
pluginPaths: nil,
3446
initialize: false
3547
)

Sources/SwiftSourceKitPluginCommon/DynamicallyLoadedSourceKitdD+forPlugin.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ import SwiftExtensions
1717

1818
extension SourceKitD {
1919
private static nonisolated(unsafe) var _forPlugin: SourceKitD?
20+
21+
package static var isPluginLoaded: Bool {
22+
return _forPlugin != nil
23+
}
24+
2025
package static var forPlugin: SourceKitD {
2126
get {
2227
guard let _forPlugin else {

0 commit comments

Comments
 (0)