From 9929a23ecdf1b221f7b93481206f3dc87ffdd308 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 9 Oct 2018 11:24:31 +0200 Subject: [PATCH 1/2] add dlerror stubs --- src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs index 7185d68efe9..63c6c1f2f2e 100644 --- a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs +++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs @@ -183,6 +183,9 @@ namespace Grpc.Core.Internal [DllImport("libdl.so")] internal static extern IntPtr dlopen(string filename, int flags); + [DllImport("libdl.so")] + internal static extern IntPtr dlerror(); + [DllImport("libdl.so")] internal static extern IntPtr dlsym(IntPtr handle, string symbol); } @@ -192,6 +195,9 @@ namespace Grpc.Core.Internal [DllImport("libSystem.dylib")] internal static extern IntPtr dlopen(string filename, int flags); + [DllImport("libSystem.dylib")] + internal static extern IntPtr dlerror(); + [DllImport("libSystem.dylib")] internal static extern IntPtr dlsym(IntPtr handle, string symbol); } @@ -208,6 +214,9 @@ namespace Grpc.Core.Internal [DllImport("__Internal")] internal static extern IntPtr dlopen(string filename, int flags); + [DllImport("__Internal")] + internal static extern IntPtr dlerror(); + [DllImport("__Internal")] internal static extern IntPtr dlsym(IntPtr handle, string symbol); } @@ -222,6 +231,9 @@ namespace Grpc.Core.Internal [DllImport("libcoreclr.so")] internal static extern IntPtr dlopen(string filename, int flags); + [DllImport("libcoreclr.so")] + internal static extern IntPtr dlerror(); + [DllImport("libcoreclr.so")] internal static extern IntPtr dlsym(IntPtr handle, string symbol); } From a959b6d7d2b6df11afe5381390fbfae6000675d3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 9 Oct 2018 11:56:57 +0200 Subject: [PATCH 2/2] Show dlerror if grpc_csharp_ext load fails --- .../Grpc.Core/Internal/UnmanagedLibrary.cs | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs index 63c6c1f2f2e..1786fc2e3f6 100644 --- a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs +++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs @@ -51,11 +51,12 @@ namespace Grpc.Core.Internal Logger.Debug("Attempting to load native library \"{0}\"", this.libraryPath); - this.handle = PlatformSpecificLoadLibrary(this.libraryPath); + this.handle = PlatformSpecificLoadLibrary(this.libraryPath, out string loadLibraryErrorDetail); if (this.handle == IntPtr.Zero) { - throw new IOException(string.Format("Error loading native library \"{0}\"", this.libraryPath)); + throw new IOException(string.Format("Error loading native library \"{0}\". {1}", + this.libraryPath, loadLibraryErrorDetail)); } } @@ -129,31 +130,44 @@ namespace Grpc.Core.Internal /// /// Loads library in a platform specific way. /// - private static IntPtr PlatformSpecificLoadLibrary(string libraryPath) + private static IntPtr PlatformSpecificLoadLibrary(string libraryPath, out string errorMsg) { if (PlatformApis.IsWindows) { + // TODO(jtattermusch): populate the error on Windows + errorMsg = null; return Windows.LoadLibrary(libraryPath); } if (PlatformApis.IsLinux) { if (PlatformApis.IsMono) { - return Mono.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY); + return LoadLibraryPosix(Mono.dlopen, Mono.dlerror, libraryPath, out errorMsg); } if (PlatformApis.IsNetCore) { - return CoreCLR.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY); + return LoadLibraryPosix(CoreCLR.dlopen, CoreCLR.dlerror, libraryPath, out errorMsg); } - return Linux.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY); + return LoadLibraryPosix(Linux.dlopen, Linux.dlerror, libraryPath, out errorMsg); } if (PlatformApis.IsMacOSX) { - return MacOSX.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY); + return LoadLibraryPosix(MacOSX.dlopen, MacOSX.dlerror, libraryPath, out errorMsg); } throw new InvalidOperationException("Unsupported platform."); } + private static IntPtr LoadLibraryPosix(Func dlopenFunc, Func dlerrorFunc, string libraryPath, out string errorMsg) + { + errorMsg = null; + IntPtr ret = dlopenFunc(libraryPath, RTLD_GLOBAL + RTLD_LAZY); + if (ret == IntPtr.Zero) + { + errorMsg = Marshal.PtrToStringAnsi(dlerrorFunc()); + } + return ret; + } + private static string FirstValidLibraryPath(string[] libraryPathAlternatives) { GrpcPreconditions.CheckArgument(libraryPathAlternatives.Length > 0, "libraryPathAlternatives cannot be empty.");