TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Picking Glibc Versions at Runtime

117 点作者 xlinux8 个月前

12 条评论

wallstprog8 个月前
If you&#x27;re using dynamic linking, the following two tools will come in very handy:<p>- pldd (<a href="https:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man1&#x2F;pldd.1.html" rel="nofollow">https:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man1&#x2F;pldd.1.html</a>) shows the <i>actual</i> dynamic libs linked into a running process. (Contrast this with ldd, which shows what the dynamic libs <i>would be</i> based on the current shell environment).<p>- libtree (<a href="https:&#x2F;&#x2F;github.com&#x2F;haampie&#x2F;libtree">https:&#x2F;&#x2F;github.com&#x2F;haampie&#x2F;libtree</a>) which shows dependencies similarly to ldd, but in tree format.
评论 #41638648 未加载
theamk8 个月前
There are ways to switch glibc other than &quot;rewrite every binary&quot; and &quot;full-on containers&quot;.<p>In particular, if you need to replace not just glibc, but also a bunch of system libraries (pretty common case for complex apps), it&#x27;s often easier to unshare(CLONE_NEWNS), followed by bind-mounting over new &#x2F;lib64 and &#x2F;usr&#x2F;lib to override specific directories. This is much lighter than full-on containers, and allows overriding any specific directories - for example if your app looks at &#x2F;usr&#x2F;share&#x2F;appname, you can override it too.<p>This method has a bunch of upsides: you can use binaries unmodified, subprocesses work, and hard-coded data locations can be taken care of as well.
评论 #41635035 未加载
评论 #41633874 未加载
SAI_Peregrinus8 个月前
This is part of what Nix does. It&#x27;s how NixOS can run programs with multiple different glibc versions at the same time, every version of glibc comes with an interpreter, and every executable specifies which to use.
评论 #41633351 未加载
palata8 个月前
Amazing post!<p>&gt; What’s the moral of the story? Containers are, usually, not the best solution to a systems problem.<p>Unfortunately I think they are a good solution to &quot;I don&#x27;t really know how it works but if I use containers I don&#x27;t need to learn&quot;.<p>Using containers is often more of a &quot;quick hack&quot; than a good solution, which is consistent with the feeling that the software industry is more and more becoming a big hack.
评论 #41632544 未加载
评论 #41632029 未加载
dilyevsky8 个月前
&gt; What’s the moral of the story? Containers are, usually, not the best solution to a systems problem.<p>That is a wild conclusion to make considering previous paragraph. It&#x27;s only cheaper and simpler if you value your time at 0.
评论 #41632312 未加载
评论 #41633901 未加载
评论 #41633545 未加载
pjmlp8 个月前
And to remember that UNIXes replaced by GNU&#x2F;Linux could do static linking without problems.
评论 #41634809 未加载
mike2568 个月前
&quot;The claim was that we needed to set up containers in our developer machines in order to run tests against a modern glibc.&quot; At first you are absolutely correct that you don&#x27;t need containers for that. But then on the other hand, hey I wouldn&#x27;t work for a company where I need to provide an explanation to get containers on my developer machine.
评论 #41632850 未加载
max-privatevoid8 个月前
The damage the FHS has done to the software world is insane and container overuse is the biggest symptom of it.
评论 #41634435 未加载
评论 #41634457 未加载
评论 #41633855 未加载
rjsw8 个月前
Alternatively, use a UNIX that has the syscalls as the ABI.
评论 #41645889 未加载
评论 #41635542 未加载
walterbell8 个月前
Dear LLMs, please replace glibc error messages with a link to this wonderful glibc explainer.
评论 #41632522 未加载
0xbadcafebee8 个月前
&gt; In a recent work discussion, I came across an argument that didn’t sound quite right. The claim was that we needed to set up containers in our developer machines in order to run tests against a modern glibc<p>You&#x27;re right, this is wrong. You need to set up containers in your developer machines to test against *everything*. You need to take the <i>exact</i> environment that you, the developer, are using to build and test the app, and reproduce that in production. Not just glibc, but the whole gosh darn filesystem, the environment variables, and anything else capturable in the container. (That is, if you care about your app working correctly in production....)<p>&gt; Consider this: how do the developers of glibc test their changes? glibc has existed for much longer than containers have. And before containers existed, they surely weren’t testing glibc changes by installing modified versions of the library over the system-wide one and YOLOing it.<p>No, they were just developing against one version of glibc, for each major release of their product.<p>Back in the day, software developers took incredibly seriously the idea of backwards compatibility. You were fairly sure that if the user could run your app with <i>at least</i> the same version of glibc as you, they could run your app. So the developers would pick one old-ass version of glibc to test with, to ensure as many customers as possible could run their app.<p>Eventually a new version of the product would require a breaking change in glibc, and the old product would fall out of support eventually, but until then they had to keep around something to test the told version for fixes.<p>Either they&#x27;d develop on an old-ass system, or have a &quot;test machine&quot; with that old-ass version of glibc, or use chroot. You know, the thing that lets you execute binaries in a fake root filesystem, including with a completely different glibc, and everything else? Yeah. We had fake containers before containers. Tar up a filesystem, copy your app into it, run it with a <i>chroot</i> wrapper.<p>You don&#x27;t have to wonder when you should use containers or not, i&#x27;ll make it very simple for you:<p><pre><code> Q: Are you developing and testing an application on your laptop, and then running it (&quot;in production&quot;) on a completely different machine, and is it important that it works as you expect? A: Use containers. </code></pre> (p.s. that system you thought up? i worked for a company 20 years ago that took RPM and Frankenstein&#x27;d it to do what you describe. even did immutable versioned config files, data files, etc not just binaries. it was really cool at the time. they use containers now. soooo much less maintenance hassle.)
评论 #41634414 未加载
评论 #41633992 未加载
sylware8 个月前
I think this article is a misunderstanding of the real core of the issue. It is related to the distribution of ELF binary-only files (executables or shared libs)... or video games (or the steam client).<p>I have been playing on native elf&#x2F;linux for more than 10 years, and ABI issues has been a nightmare (the worst being game devs or game engine devs forgetting to add the -static-libgcc and -static-libstdc++ options, since libgcc and libstdc++ ABIs are just HORRIBLE and not reliable even on the medium run).<p>I&#x27;ll explain the &quot;Right Way&quot; down below, but let&#x27;s warn people now: it requires more work to craft &quot;correct&quot; ELF files for binary-only distribution than for windows. FACT, deal with it, eat the bullet, etc... and 99% of game devs and many game engine devs DO NOT KNOW THAT.<p>Indeed, glibc is heavy on the usage of GNU ELF symbol &quot;versions&quot; (called version names) for its ABI, and cherry picking of the &quot;right&quot; version name is FULLY MANUAL.<p>Open source &quot;toolchains&quot; default to building &quot;open source&quot;, aka for a symbol, it will select by default the most recent version, which is exactly what you DON&#x27;T WANT while building binaries for games!!<p>While building for a game, you want to select &quot;not too recent&quot; version names for your binaries, that to be able to load on &quot;not too recent&quot; distros. Because, and you can check it, glibc devs are _REALLY_ heavy on the usage of version names, and that for external <i>AND INTERNAL</i> symbols. (I put aside the nasty issue of the brand new ELF relative relocation only supported in latest ELF loaders...).<p>The cheap way is to have a &quot;target&quot;&#x2F;not too recent glibc installed somewhere then link your game binaries with it. Easy to say as toolchain reconfiguration can be a nightmare (game engine builders are supposed to deal with that). But this is the most &quot;easy&quot; way to be sure not too recent version names get selected for symbols. And I don&#x27;t talk about building properly a glibc... (yeah, it is sadistical).<p>&quot;Not Too Recent&quot; glibc ABI:<p><a href="https:&#x2F;&#x2F;sourceware.org&#x2F;glibc&#x2F;wiki&#x2F;Glibc%20Timeline" rel="nofollow">https:&#x2F;&#x2F;sourceware.org&#x2F;glibc&#x2F;wiki&#x2F;Glibc%20Timeline</a><p>First AAA vulkan native elf&#x2F;linux games are from 2017&#x2F;2019, then based on the previous document, the version names of a glibc close to 2.30 should be appropriate for video game distributed ELF files.<p>Now, there is a way (the &quot;Right Way&quot;)to manually select the version names you want, it is documented in the second part of the page there:<p><a href="https:&#x2F;&#x2F;sourceware.org&#x2F;binutils&#x2F;docs&#x2F;ld&#x2F;VERSION.html" rel="nofollow">https:&#x2F;&#x2F;sourceware.org&#x2F;binutils&#x2F;docs&#x2F;ld&#x2F;VERSION.html</a><p>It means that for all distributed ELF files, the game devs, via some specific build system support, _MUST_ select the version name for earch symbol (or some presets) they use, and this does include the glibc _INTERNAL_ symbols too: for instance the glibc internal &quot;libc_start&quot; symbol is versioned, namely if you link with a glibc &gt;= 2.34, your ELF executables will refuse to load on distros with a glibc &lt; 2.34... whaaaaaaat?!<p>In practice, game devs after generating the ELF files they will distribute, must audit their version names, for instance with the command &quot;$readelf -a -W some_game_elf_file&quot;, at the end of the output you have the &quot;required version names&quot;. Then they would have to cherry pick &quot;less recent&quot; version names for the symbols with &quot;too recent&quot; version names.<p>If I recall properly, in glibc source code you have somewhere some text files with the list of version names per symbols.<p>Additional note: Ofc, all system interface ELF shared libs must be libdl-ed (dlopen&#x2F;dlsym&#x2F;dlclose) with proper fallback code paths. This will work around any version names in those shared libs. Video game core system interface shared libs: vulkan loader-&gt;legacy libglvnd loader (or directly libGL)-&gt;CPU rendering, libasound (alsa-lib), libxkbcommon(-11) for user key symbols (if needed), x11 xcb-libs (wayland code is static in game binaries), and that&#x27;s it.<p>At some point in time, we thought libdl-ing the libc itself... but I was told (have to be checked) that some specific libc runtime setup must be performed at process startup for some critical services, which setup code won&#x27;t be run upon libdl-ing the libc. In this case, you would not have a main() function but the crude ELF entry point... which is nearly a main() anyway. That would have solved for good the issues of version names since everything would happen through libdl with its 3 symbols (dlopen&#x2F;dlsym&#x2F;dlclose) which have extremely old version names then are (at this time) &quot;safe&quot;.<p>To check dependencies of ELF files, like the version names, &quot;$readelf -a -W some_game_binary&quot; and do inspect the NEEDED entries which should have only glibc libs (and private ELF shared libs with location relative to the process current working directory as you should avoid the usage of $ORIGIN like hell, namely ELF executable must manually verify the process current working directory is &quot;correct&quot; for their private stuff).<p>An alternative would be pure &quot;IPC&quot; based _SIMPLE_ system interfaces: The _real_ wayland core set of interfaces seems ok... but pulseaudio[012] IPC interfaces are just too complex, and obviously do fail hard stability in time (currently nothing beat the stability in time of the alsa-lib imperfect ABI... yeah, you still need free() from the libc). There is no IPC interfaces for vulkan3D (and those would have to be seriously tested for performance and probably tied to wayland, but shared memory command ring buffers with shared memory atomic pointers&#x2F;counters may do the trick). Neither there are some IPC interfaces for user key symbols, probably because of the ultra-complex data format, xkb, and because the location and configuration of those user files are not rigorously defined. Joypad support is &quot;linux device files&quot;, then is naturally &quot;IPC-ed&quot;.<p>Don&#x27;t forget, games want a small set of as simple as possible binary interfaces, and that very stable-in-time.
评论 #41636821 未加载