Consider: > 0x7fac5ec0b000 to 0x7fac5ed9a000, len = 0x18f000, offset = 0 > r--p /usr/lib/libstdc++.so.6.0.25 > 0x7fac5ec94000 to 0x7fac5ed8a000, len = 0xf6000, offset = 0x89000 > ---p /usr/lib/libstdc++.so.6.0.25
0x7fac5ec94000 - 0x89000 = 0x7fac5ec0b000 This is just taking away the 'r' bit from part of the first mapping. We can ignore it in perf and perfparser. > 0x7fac5ec94000 to 0x7fac5ed4c000, len = 0xb8000, offset = 0x89000 > r-xp /usr/lib/libstdc++.so.6.0.25 Same thing, but adding the 'r' and 'x' bits. > 0x7fac5ed4c000 to 0x7fac5ed89000, len = 0x3d000, offset = 0x141000 > r--p /usr/lib/libstdc++.so.6.0.25 0x7fac5ed4c000 - 0x141000 = 0x7fac5ec0b000 This is re-adding the 'r' bit for a different range, again without changing the contents. > 0x7fac5ed8a000 to 0x7fac5ed97000, len = 0xd000, offset = 0x17e000 > rw-p /usr/lib/libstdc++.so.6.0.25 0x7fac5ed8a000 - 0x17e000 = 0x7fac5ec0c000 Strange, what is this? Note that the 'rw', though. It probably doesn't contain any executable code. In effect, perfparser and perf should then truncate the original mapping and never report this one to libdw, just like we do in perfparser now (for different reasons). So, what about the following algorithing, which can be done entirely outside of elfutils: If we get an mmap with a pgoff, check if the same file is already mapped at the "virtual" start address of the file (start - pgoff), and if it is, ignore the mmap. That should deal with the first 3 overlaps here. The last one is really mapping a different part of the file, but as the mapping is not executable and read-write we should really never get a sample from it. We might actually check the permission bits before reporting things to dwfl so that a few broken samples don't destroy the memory map. However, that partially contradicts the above. We'd need to OR up all the permissions from different mmaps covering the same file at the same base address to get an approximation for it, or we need a different data structure. best, Ulf