shared libraries and dynamic linking
good
- easy update: no re-linking after a new library release (bugs can be fixed for all programs at once)
- save space in ram: pages can be shared resulting small runtime memory footprint
- save space on disk: referencing common code without storing it in the executable file image
- security: loading lib code at random address can prevent certain attacks
- changing the binding of symbols without recompiling is possible (many applications: profiling, debugging, testing, plugins,..)
bad
- complex implementation: locating libraries, runtime symbol lookups, address relocation..
- complex mental model: execution depends on external files, settings, environment, symbol versioning, the semantics is slightly different from unshared libs..
- portability problem: different platforms might use different version and/or settings of the lib (so vendor will ship his version defeating most pros)
- update disaster: bugs can be introduced into all programs at once
- update disaster: abi changes cause problems (versioning is needed)
- update disaster: semantic changes of the library can cause even bigger problems (different programs will assume different behaviour from the same shared lib)
- expensive process: exec is slow due to large part of the linking is done at loadtime (mapping the linker in the process, relocation, symbol lookup, position independent code overhead)
- waste of space: dynamic libs are a bit bigger than static ones (because of the symbol lookup table)
- waste of space: entire lib is loaded into memory even if only a subset is used
- security problem: a huge loader increases the amout of trusted code in the system
- adding code at runtime (dynamic loading) can be done without imitating unshared lib semantics (with dynamic linking the loading of additional code is automatic based on metadata in the executable, so the complexity is implicit and uncontrollable)
- code instrumentation and plugin systems can be implemented without dynamic linking as well
alternative solutions
- modular design when communication and context switch are not an issue: separate processes with simple interface (network transparent, reliable, secure..)
- modular design when efficiency is needed: simple dynamic loading? (mmap + runtime symbol binding +..) or static linking (most efficient, but no loadtime/runtime code change)
- security fix in common code: recompile or binary patch every affected program?
stuff
2009.11.01 - nsz