{"record":{"id":"4fec23fe2a8ef6b7","repo":"AvaloniaUI/Avalonia","slug":"unable-to-load-librarypath-via-dlopen","errorCode":null,"errorMessage":"Unable to load {libraryPath} via dlopen","messagePattern":"Unable to load (.+?) via dlopen","errorType":"exception","errorClass":"DllNotFoundException","httpStatus":null,"severity":"error","filePath":"samples/XEmbedSample/HarfbuzzWorkaround.cs","lineNumber":56,"sourceCode":"    private const int RTLD_NOW = 2;\n    private const int RTLD_DEEPBIND = 8;\n    \n    public static void Apply()\n    {\n        if (RuntimeInformation.RuntimeIdentifier.Contains(\"musl\"))\n            throw new PlatformNotSupportedException(\"musl doesn't support RTLD_DEEPBIND\");\n        \n        var libraryPathBytes = Marshal.AllocHGlobal(4096);\n        var handle = NativeLibrary.Load(\"libHarfBuzzSharp\", typeof(HarfBuzzSharp.Blob).Assembly, null);\n        dlinfo(handle, RTLD_DI_ORIGIN, libraryPathBytes);\n        var libraryOrigin = Marshal.PtrToStringUTF8(libraryPathBytes) ?? string.Empty;\n        Marshal.FreeHGlobal(libraryPathBytes);\n        var libraryPath = Path.Combine(libraryOrigin, \"libHarfBuzzSharp.so\");\n        \n        NativeLibrary.Free(handle);\n        var forceLoadedHandle = dlopen(libraryPath, RTLD_NOW | RTLD_DEEPBIND);\n        if (forceLoadedHandle == IntPtr.Zero)\n            throw new DllNotFoundException($\"Unable to load {libraryPath} via dlopen\");\n        \n        NativeLibrary.SetDllImportResolver(typeof(HarfBuzzSharp.Blob).Assembly, (name, assembly, searchPath) =>\n        {\n            if (name.Contains(\"HarfBuzzSharp\"))\n                return dlopen(libraryPath, RTLD_NOW | RTLD_DEEPBIND);\n            return NativeLibrary.Load(name, assembly, searchPath);\n        });\n        \n    }\n}\n","sourceCodeStart":38,"sourceCodeEnd":67,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/samples/XEmbedSample/HarfbuzzWorkaround.cs#L38-L67","documentation":"After resolving libHarfBuzzSharp's directory via dlinfo(RTLD_DI_ORIGIN), the workaround dlopen()s the full path with RTLD_NOW|RTLD_DEEPBIND. A zero return means the loader could not open the file. The message string still literally contains '{libraryPath}' (not interpolated), so it is a second bug — the path is never printed.","triggerScenarios":"dlopen returning IntPtr.Zero: the resolved library path does not exist, the file is the wrong architecture (e.g. x64 vs arm64), library is not readable (permissions), or a dependency is missing (libstdc++, libfontconfig). Happens when the RID-packaged native lib is absent from the expected directory.","commonSituations":"Publishing self-contained with the wrong RID; trimming removing the native HarfBuzzSharp binary; mismatched libHarfBuzzSharp.so ABI; missing system fonts/fontconfig on the host.","solutions":["Verify libHarfBuzzSharp.so exists at the resolved libraryOrigin and is readable (note the message bug — print dlerror() instead).","Ensure the published RID matches the runtime (linux-x64 vs linux-arm64 vs linux-musl-x64).","Install missing system dependencies (fontconfig, libstdc++).","Call dlerror() after a zero return and include its message for the real cause."],"exampleFix":"// before\nvar forceLoadedHandle = dlopen(libraryPath, RTLD_NOW | RTLD_DEEPBIND);\nif (forceLoadedHandle == IntPtr.Zero)\n    throw new DllNotFoundException($\"Unable to load {libraryPath} via dlopen\");\n\n// after (interpolate the path AND surface dlerror)\nvar forceLoadedHandle = dlopen(libraryPath, RTLD_NOW | RTLD_DEEPBIND);\nif (forceLoadedHandle == IntPtr.Zero)\n{\n    var err = Marshal.PtrToStringAnsi(dlerror()) ?? \"unknown\";\n    throw new DllNotFoundException($\"Unable to load '{libraryPath}' via dlopen: {err}\");\n}","handlingStrategy":"try-catch","validationCode":"// confirm the native lib is present and loadable\nif (!File.Exists(libraryPath)) return; // missing binary for this RID","typeGuard":"static bool LibExists(string path) => File.Exists(path) && NativeLibrary.TryLoad(path, out _);","tryCatchPattern":"try { HarfbuzzWorkaround.Apply(); }\ncatch (DllNotFoundException ex)\n{ _logger.LogError(\"HarfBuzz native load failed; ensure RID-matched lib exists. {Msg}\", ex.Message); }","preventionTips":["Publish with the correct RID (linux-x64 vs linux-musl-x64 vs linux-arm64).","Print dlerror() in the message to reveal the loader's reason.","Install host deps: fontconfig, libstdc++."],"tags":["linux","dlopen","harfbuzz","native-libs","rid","sample","message-bug"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}