Dynamic linking
21–30 of 249 posts
Re: Dynamic linking
#22Earlier quoted context omitted.
Run htop or similar, sort by "shared memory" column and see how much more memory you'd need per process if shared linking did not exist. I think the author's using a wrong method to make a point. Dynamic linking feels out of place for most long-running server-side apps (typical SaaS workload). One can argue that in a mostly CLI-environment there's also not much benefit. But even an empty Ubuntu desktop runs ~400 proc…
Go executables are statically linked. It makes deployment a breeze. I think you overestimate how much saving you get from dynamically linking libc. Each executable uses only a small portion of libc, so the average savings is going to be in the handful of kilobytes per executable.
Re: Dynamic linking
#23In particular, static linking for C has two serious problems:
1. symbol collisions -> accidental interposition (and crashes);
2. you have to flatten the dependency tree into a topological sort at the final link-edit.
Both of these are related, and they are disastrous. They are also related to the lack of namespaces in C.
Besides fixing these issues, the C dynamic linking universe also enables things like:
- run-time code injection via LD_PRELOAD and intended interposition
- run-time code loading/injection via dlopen(3)
- audit (sotruss)
- reflection
- filters (which allow one to move parts of libraries contents to other libraries without forcing re-links and without forcing built systems to change to add new -lfoo arguments to link-edits)
- use of dladdr(3) to find an object's install location, and then that to find related assets' install locations relative to the first, which then yields code that can be relocated at deploy time (sure, "don't do that" is a great answer, but if you statically-link then you think you can, and now you just can't have assets to load at run-time)
- use of weak symbols to detect whether a process has some library loaded
and others.
C with those features is a far superior language -- a different language, really -- to C without them.
(EDIT: A lot of the semantics of ELF could be brought to static linking. Static link archives could have a .o that has metadata like depedencies, "rpaths", exported/protected symbols, interposer symbols, etc. The link-editor would write and consume that metadata. However, it's 2020, and the static link ecosystem is stuck in 1980 because no one has bothered, and no one has bothered because dynamic linking is pretty awesome. Still, it could be done, and once in a while I think I ought to do it to help save people from themselves who want static linking.)
> Do your installed programs share dynamic libraries?
> Findings: not really
> Over half of your libraries are used by fewer than 0.1% of your executables.
The C library most certainly gets shared, as well as libm and such. The rest, it's true, not so much, but it does depend on what you're measuring. Are you measuring C++ apps? Yeah, C++ monomorphization leads to essentially static linking. Are you measuring Java apps with no significant JNI usage? You won't find much outside the libraries the JVM uses.
> Is loading dynamically linked programs faster?
> Findings: definitely not
Dynamically-linked programs will load faster when their dependencies are already loaded in memory, and slower otherwise. The biggest win here is the C library.
> Will security vulnerabilities in libraries that have been statically linked cause large or unmanagable updates?
> Findings: not really
Correct. But, being able to update libc or some such and not have to worry about updating consumers you might not even know about is a very nice feature.
Re: Dynamic linking
#24I have little memory of the details of the story, and I'm not 100% sure it's true, but it's a much more satisfying and reasonable argument for dynamic linking than performance/space.
Of course, the more modern solution would probably be a good package manager -- if its trivial to recompile things, and track what needs to be recompiled, then dynamic linking seems to gain little, but bring in a lot of its own headaches (as we know today)
Re: Dynamic linking
#25Earlier quoted context omitted.
Run htop or similar, sort by "shared memory" column and see how much more memory you'd need per process if shared linking did not exist. I think the author's using a wrong method to make a point. Dynamic linking feels out of place for most long-running server-side apps (typical SaaS workload). One can argue that in a mostly CLI-environment there's also not much benefit. But even an empty Ubuntu desktop runs ~400 proc…
That is an extremely misleading figure. Shared memory is page-aligned entire libraries dropped into RAM. Statically linking would, as the article shows, only use on average about 4% of the symbols available from the libraries, and the majority of this would not end up in RAM with your statically linked binary. And if you used a more selective approach, dynamically linking to no more than perhaps a dozen high-impact l…
Come on.
You did not actually measure the figure GP mentioned and which you are disputing. Your methodology and assumption — that 4% external symbol use translates into 4% size used — is a plausible guess, but you haven't supported it with data.
Even if you had measured the figure you're accusing GP of ignoring, the tone of your remark is just aggressively condescending and inappropriate. Tone it down.
To address your other claims:
> Shared memory is page-aligned entire libraries dropped into RAM.
There is a good reason to page- or superpage-align code generally; it burns some virtual memory but reduces TLB overhead and therefore misses / invalidations, which are very costly. You would want to do the same with executable code in a static-linked binary.
> the majority of [the small fraction of static linked library used] would not end up in RAM with your statically linked binary.
Huh? Why do you claim that?
> And if you used a more selective approach, dynamically linking to no more than perhaps a dozen high-impact libraries and statically linking the rest, you'd get a lot of the benefits and few of the drawbacks.
I think that claim is plausible! But it wasn't an option presented on your blog post, nor was it discussed by GP. Prior to that comment, discussion was only around 100% vs 0% dynamic linking.
Re: Dynamic linking
#26Earlier quoted context omitted.
Run htop or similar, sort by "shared memory" column and see how much more memory you'd need per process if shared linking did not exist. I think the author's using a wrong method to make a point. Dynamic linking feels out of place for most long-running server-side apps (typical SaaS workload). One can argue that in a mostly CLI-environment there's also not much benefit. But even an empty Ubuntu desktop runs ~400 proc…
Go executables are statically linked. It makes deployment a breeze. I think you overestimate how much saving you get from dynamically linking libc. Each executable uses only a small portion of libc, so the average savings is going to be in the handful of kilobytes per executable.
test.c:
int main(int argc, char **argv) {
printf("hello world\n");
return 0;
}
Dynamic linking (glibc): $ gcc -O2 -Wl,--strip-all test.c
$ ls -sh a.out
8.0K a.out
Static linking (glibc): $ gcc -O2 --static -Wl,--strip-all test.c
$ ls -l a.out
760K a.out
Static linking (musl): $ musl-gcc --static -O2 -Wl,--strip-all test.c
$ ls -sh a.out
8.0K a.outRe: Dynamic linking
#27Suckless has a project to get a fully static compiled Linux environment. Unfortunately I don't know how far that have come
I don't think stali has seen any activity in several years. As far as I know, the only completely statically linked Linux distribution that is actively developed is my own project (inspired by stali), oasis: https://github.com/oasislinux/oasis
Re: Dynamic linking
#28First, this analysis was done on Arch Linux, a source-based distribution. Since you know at compile time what your environment is, I would expect the benefits to be smaller. And of course, this means you're willing to do a lot of recompiles. I'd like to see analysis done on more traditional (& common) binary distros.
Second, the arguments seem a little cherry-picked. "Over half of your libraries are used by fewer than 0.1% of your executables." is cute. But modern systems have a lot of executables, so 0.1% > 1, so that still matters, and what about the other half.
Finally, we're already having serious problems getting containers to upgrade when a security vulnerability is found. Requiring recompilation of all transitive users is not likely to win any update speed contests. If it's completely automated then it would work, but any rocks in the process will leave people endlessly vulnerable. See the Android ecosystem, etc.
Re: Dynamic linking
#29Re: Dynamic linking
#30A better way to do this analysis would be to build a Linux distribution with everything statically linked and compare to the normal version with dynamic linking, looking at disk space used, startup time, memory used, and time to launch specific applications both cold and hot.
That was an apples-to-apples comparison of pre- and post-process model unification performance, and it was a win.
Now, this was back in... I want to say 2003 or 2004 -- before S10 shipped. And it's possible that the same experiment today would not have the same result.
I'm not sure how easy it would be to construct a distro with only dynamically-linked executables (at least for core libraries, like the C library) and then the same distro with only statically-linked executables. The S10 work was done by Roger Faulkner (RIP) and it was a huge change.