Playing with strace, it appears to me that ld.so.cache and libc.so.6 are opened and mapped to memory for almost every process. At least those processes that I experimented with. Doesn't this mean that these processes are mapped into process memory many many many times?

Sure, these files are pretty small, but isn't that a little wasteful of memory?

The strace output shows that these are being mmap'ed with MAP_PRIVATE set, which makes it copy-on-write, but there still appears to be a new mapping for every process.

My questions:

  1. Have I properly understood what is happening? That is, is there really a new copy of these files mapped into memory on every process that needs them (which appears to be every single one)?
  2. Is there some type of memory-sharing going on? That is, since the mapping is copy-on-write, are lots of processes looking at the same physical memory locations?
  • Memory mapping practically always uses memory sharing. – Barmar Dec 27 '18 at 23:18
  1. Yes, every process gets its own mapping of the libraries it needs.

  2. Yes, most of the data is shared, so every process “sees” the same physical memory (at different linear addresses), assuming the same version of each file is shared.

You can see the various mappings by looking at the maps file inside each process’ /proc/ directory; for libc you’ll see entries such as

7f1014062000-7f10141f7000 r-xp 00000000 fd:0d 1444681                    /lib/x86_64-linux-gnu/libc-2.24.so
7f10141f7000-7f10143f7000 ---p 00195000 fd:0d 1444681                    /lib/x86_64-linux-gnu/libc-2.24.so
7f10143f7000-7f10143fb000 r--p 00195000 fd:0d 1444681                    /lib/x86_64-linux-gnu/libc-2.24.so
7f10143fb000-7f10143fd000 rw-p 00199000 fd:0d 1444681                    /lib/x86_64-linux-gnu/libc-2.24.so


7f4d7a8ec000-7f4d7aa81000 r-xp 00000000 fd:0d 1444681                    /lib/x86_64-linux-gnu/libc-2.24.so
7f4d7aa81000-7f4d7ac81000 ---p 00195000 fd:0d 1444681                    /lib/x86_64-linux-gnu/libc-2.24.so
7f4d7ac81000-7f4d7ac85000 r--p 00195000 fd:0d 1444681                    /lib/x86_64-linux-gnu/libc-2.24.so
7f4d7ac85000-7f4d7ac87000 rw-p 00199000 fd:0d 1444681                    /lib/x86_64-linux-gnu/libc-2.24.so

The read-only, executable mapping corresponds to the shared executable code in the library; the read-only mapping gives access to the shared, read-only data in the library; and the read-write mapping is a private mapping for variables in the library. As you can see above, the linear addresses are different (thanks to address-space layout randomisation, and different load orders); the underlying physical addresses for the shared parts are the same, once they’re loaded into memory (since the mappings map the underlying files, not shared memory directly).

  • Great answer. Especially the edit to include the info on maps in /proc/. Much appreciated. Thanks. – smolloy Dec 27 '18 at 21:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.