Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to run on Musl libc, "can't get libdl.so" #601

Closed
PureTryOut opened this issue Sep 12, 2021 · 24 comments
Closed

Unable to run on Musl libc, "can't get libdl.so" #601

PureTryOut opened this issue Sep 12, 2021 · 24 comments

Comments

@PureTryOut
Copy link

I've been trying to get MangoHud to run on Musl libc systems to use with FOSS games compiled for this libc, but so far I've been unable to do so.

> mangohud --dlsym target/debug/leafish
can't get libdl.so

I'm not sure what this "libdl.so" is, but I'm assuming it's a glibc thing? MangoHud compiles fine with Musl however, so not sure what's up.

@flightlessmango
Copy link
Owner

flightlessmango commented Sep 13, 2021

Yes I believe it's part of libc. We (at least partly) use it for dlopen so we can load libraries at runtime

From the musl manual
Additional files libm.a, librt.a, libpthread.a, libcrypt.a, libutil.a, libxnet.a, libresolv.a, and libdl.a are provided in $(libdir) as empty library archives. They contain no code, but are present to satisfy the POSIX requirement that options of the form -lm, -lpthread, etc. be accepted by the c99 compiler.

@PureTryOut
Copy link
Author

Shit, so I guess that means it won't work. At least till they actually implement it rather than just being empty files...

@magiruuvelvet
Copy link

magiruuvelvet commented Sep 13, 2021

How about just replacing libdl with libc when calling dlopen() in the source code? The functions are there, just the filename is different. musl libc can't be detected using compiler macros though, so a build-time check would be needed if adjusting the source.

EDIT: As alternative a symlink to libc.so called libdl.so should work too.

@PureTryOut
Copy link
Author

musl libc can't be detected using compiler macros though

Well, indirectly it can.

#if defined(__LINUX__) && !defined(__GLIBC_)

That basically comes down to Musl. Well and I suppose uclibc, but who uses that on a platform where they would want to use MangoHud? 🤔

@XRevan86
Copy link

glibc 2.34+ also moved dlopen and dlsym to libc.so, so I'd imagine the solution would be something like this:

--- a/src/real_dlsym.cpp
+++ b/src/real_dlsym.cpp
@@ -19,10 +19,17 @@ void get_real_functions()
 {
     eh_obj_t libdl;
 
+#if !defined(__GLIBC_) || __GLIBC_PREREQ(2, 34)
+    if (eh_find_obj(&libdl, "*libc.so*")) {
+        fprintf(stderr, "can't get libc.so\n");
+        exit(1);
+    }
+#else
     if (eh_find_obj(&libdl, "*libdl.so*")) {
         fprintf(stderr, "can't get libdl.so\n");
         exit(1);
     }
+#endif
 
     if (eh_find_sym(&libdl, "dlopen", (void **) &__dlopen)) {
         fprintf(stderr, "can't get dlopen()\n");

@jackun
Copy link
Collaborator

jackun commented Sep 27, 2021

I think it still needs libdl path for compatibility. Does ced84ec help?

@PureTryOut
Copy link
Author

PureTryOut commented Sep 27, 2021

It sadly does not.

> mangohud --dlsym target/release/leafish
MANGOHUD: Cannot find libdl.so and libc.so

However /lib/libc.musl-x86_64.so.1 exists, so not sure why it can't find it.

EDIT: Oh wait, it searches for *libc.so* while in this case it should be *libc*.so*

@jackun
Copy link
Collaborator

jackun commented Sep 27, 2021

😩 Ah yes, but probably libc.*.so* so it doesn't load libcrypto or something instead.

@PureTryOut
Copy link
Author

I just modified your commit to do just that and I get the same result sadly.

However checking eh_find_obj() it has a comment:

/* This function uses glibc-specific dl_iterate_phdr().
        Another way could be parsing /proc/self/exe or using
        pmap() on Solaris or *BSD */

So I assume this will never work on Musl?

@jackun
Copy link
Collaborator

jackun commented Oct 1, 2021

Try 2: https://github.com/flightlessmango/MangoHud/tree/dlsym_fs
Helps any? Glibc 2.34 seemed to work at least.

e: dl_iterate_phdr probably still blocks?

@kerossin
Copy link

kerossin commented Oct 1, 2021

Try 2: https://github.com/flightlessmango/MangoHud/tree/dlsym_fs Helps any? Glibc 2.34 seemed to work at least.

e: dl_iterate_phdr probably still blocks?

Hi,

I'm on openSUSE Tumbleweed (2.34-1.2 currently) and I was getting can't get libdl.so when trying to run MangoHud with --dlsym. Using the libraries compiled from the dlsym_fs branch seem to have fixed it.

@PureTryOut
Copy link
Author

@jackun I'd love to try but sadly that branch fails to compile for me (before I only compiled latest release, 2.6.5):

./src/overlay.cpp: In function 'void render_mpris_metadata(overlay_params&, mutexed_metadata&, uint64_t)':
../src/overlay.cpp:355:33: error: expected unqualified-id before '::' token
  355 |             catch (const fmt::v7::format_error& err)
      |                                 ^~
../src/overlay.cpp:355:33: error: expected ')' before '::' token
  355 |             catch (const fmt::v7::format_error& err)
      |                   ~             ^~
      |                                 )
../src/overlay.cpp:355:33: error: expected '{' before '::' token
  355 |             catch (const fmt::v7::format_error& err)
      |                                 ^~
../src/overlay.cpp:355:35: error: '::format_error' has not been declared; did you mean 'fmt::v8::format_error'?
  355 |             catch (const fmt::v7::format_error& err)
      |                                   ^~~~~~~~~~~~
      |                                   fmt::v8::format_error
In file included from /usr/include/spdlog/fmt/fmt.h:26,
                 from /usr/include/spdlog/common.h:36,
                 from /usr/include/spdlog/spdlog.h:12,
                 from ../src/overlay.cpp:6:
/usr/include/fmt/format.h:748:15: note: 'fmt::v8::format_error' declared here
  748 | class FMT_API format_error : public std::runtime_error {
      |               ^~~~~~~~~~~~
../src/overlay.cpp:355:49: error: 'err' was not declared in this scope; did you mean 'spdlog::level::err'?
  355 |             catch (const fmt::v7::format_error& err)
      |                                                 ^~~
      |                                                 spdlog::level::err
In file included from /usr/include/spdlog/spdlog.h:12,
                 from ../src/overlay.cpp:6:
/usr/include/spdlog/common.h:167:5: note: 'spdlog::level::err' declared here
  167 |     err = SPDLOG_LEVEL_ERROR,
      |     ^~~

@jackun
Copy link
Collaborator

jackun commented Oct 1, 2021

For some reason it is using system fmt v8, spdlog 1.8.5 needs v7.

@PureTryOut
Copy link
Author

This is spdlog 1.9.2 from the system, which pulls in it's own fmt. Is that too new for mangohud?

@jackun
Copy link
Collaborator

jackun commented Oct 1, 2021

Ah, nevermind. It's my own function, try changing v7 to v8 to const fmt::format_error& err at line 355 in src/overlay.cpp.

@PureTryOut
Copy link
Author

That worked, getting close.

../src/overlay_params.cpp: In function 'void parse_overlay_config(overlay_params*, const char*)':
../src/overlay_params.cpp:776:72: error: 'getpid' was not declared in this scope
  776 |          HUDElements.gamemode_bol = dbusmgr::dbus_mgr.gamemode_enabled(getpid());
      |                                                                        ^~~~~~

@jackun
Copy link
Collaborator

jackun commented Oct 1, 2021

Pull again but dl_iterate_phdr is borked, doesn't list libc.so though it is in /proc/../map_files, on Void at least 😩

@PureTryOut
Copy link
Author

⋊> ~/D/G/l/Leafish on main ◦ mangohud --dlsym target/release/leafish                                         10:55:15
MANGOHUD: Can't get dlopen() and dlsym()

@akien-mga
Copy link
Contributor

See #693. I had the same issue with mangohud v0.6.5 with glibc, and updating to v0.6.6-1 solved it.

@kibasnowpaw
Copy link

See #693. I had the same issue with mangohud v0.6.5 with glibc, and updating to v0.6.6-1 solved it.

yeah v0.6.6-1 Fix it.
https://github.com/flightlessmango/MangoHud/releases/tag/v0.6.6-1

@CordBlaster
Copy link

This problem exists in Ubuntu 22.04 (jammy jellyfish). This bug is probably related: https://bugs.launchpad.net/ubuntu/+source/mangohud/+bug/1993862

@maribu
Copy link

maribu commented May 2, 2023

In https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/46458 I'm trying to package this for Alpine.

With the following patch applied, it almost works:

--- a/src/meson.build
+++ b/src/meson.build
@@ -3,10 +3,10 @@
 # Needs prefix for configure_file()
 if get_option('append_libdir_mangohud')
   libdir_mangohud = join_paths(get_option('prefix'), get_option('libdir'), 'mangohud')
-  ld_libdir_mangohud = get_option('prefix') + '/\$LIB/mangohud/'
+  ld_libdir_mangohud = join_paths(get_option('prefix'), get_option('libdir'), 'mangohud') + '/'
 else
   libdir_mangohud = join_paths(get_option('prefix'), get_option('libdir'))
-  ld_libdir_mangohud = get_option('prefix') + '/\$LIB/'
+  ld_libdir_mangohud = join_paths(get_option('prefix'), get_option('libdir')) + '/'
 endif
 
 conf_data = configuration_data()
--- a/src/real_dlsym.cpp
+++ b/src/real_dlsym.cpp
@@ -26,6 +26,7 @@
 #endif
         "*libc.so*",
         "*libc.*.so*",
+        "*ld-musl-*.so*",
     };
 
     for (size_t i = 0; i < sizeof(libs) / sizeof(*libs); i++)

However, this check fails (for both obj->strtab and obj->symtab):

	/* This is here to catch b0rken headers (vdso) */
	if ((eh_check_addr(obj, (const void *) obj->strtab)) |
	    (eh_check_addr(obj, (const void *) obj->symtab)))
		return ENOTSUP;

So, for OpenGL no luck yet, but with Vulkan it works fine with Alpine/musl.

Has anyone an idea why obj->strtab and obj->symtab are holding invalid addresses on Alpine/musl?

@apprehensions
Copy link
Contributor

Has anyone an idea why obj->strtab and obj->symtab are holding invalid addresses on Alpine/musl?

I was looking to use MangoHud on Alpine, but unfortunately this is still a problem, even on 0.6.9.

Void Linux has MangoHud packaged for musl, maybe it works for them as they dont include such a patch for dlsym.

Johnnynator added a commit to Johnnynator/MangoHud that referenced this issue Sep 28, 2023
elf(5) documents it this way, GLIBC diverts from this documentation

partial fix for flightlessmango#601
Johnnynator added a commit to Johnnynator/MangoHud that referenced this issue Sep 28, 2023
@Johnnynator
Copy link
Contributor

Johnnynator commented Sep 28, 2023

Has anyone an idea why obj->strtab and obj->symtab are holding invalid addresses on Alpine/musl?

See elf(5)

       d_ptr  This member represents program virtual addresses.  When
              interpreting these addresses, the actual address should be
              computed based on the original file value and memory base
              address.  Files do not contain relocation entries to fixup
              these addresses.

The way I'm reading this, is that d_ptr is supposed to only hold an offset. Adding obj->addr to all of them does fix the code for musl. Glibc implements this different than documented in elf(5).

Fix for this is available in #1133

Johnnynator added a commit to Johnnynator/MangoHud that referenced this issue Jan 15, 2024
elf(5) documents it this way, GLIBC diverts from this documentation

partial fix for flightlessmango#601
Johnnynator added a commit to Johnnynator/MangoHud that referenced this issue Jan 15, 2024
flightlessmango pushed a commit that referenced this issue Jan 15, 2024
elf(5) documents it this way, GLIBC diverts from this documentation

partial fix for #601
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests