And apparently, the answer is: I compile with my own allocator. This way I can not only log all allocations, I can also ignore deallocations to make sure no two data structures share a memory location. Rather smelly code but it works.
https://github.com/palant/pfp-cli/commit/23c3cea5716257dfa0548a795ea5457d47b8b0ca
Well, I have a dilemma: reading a password from stdin via usual I/O leaves that password in memory, due to a libc buffer I think. Reading the password properly via rpassword does not but it isn’t compatible with integration tests (the ones searching memory for secrets). Heh…