Hacker News new | ask | show | jobs
by mitchs 1216 days ago
Neat. I had made something similar for work a while back, but as a LD_PRELOAD library that intercepted calls to malloc and friends. It would add extra space to every allocation so it could add a pointer at the end that would point into a leaf node of a call graph backtrace tree it maintained. Each node in the tree had lifetime allocated/freed block counts and bytes by code site. The cool part about it was that it barely affected the performance of the application.

It made its own socket and thread to listen on it. It would just dump a snapshot of tree to anything that connected. I also had some tooling that would let you diff two snapshots, since it was helpful to see if particular stimuli cause persistent extra allocations. While finding the largest outstanding delta between allocated and free bytes was great for finding leaks, sorting by lifetime count of blocks allocated was also fun. I remember some little puzzle game I enjoyed playing at the time would allocate and free tens of thousands of blocks as you dragged a line around for a second.

There was a tricky chicken and egg problems with LD_PRELOAD wrapping one of the allocation functions, because it was used internally by dlsym, which I was using to retrieve pointers to the proper function implementations. (calloc if I recall correctly.) I hacked around it by making my library allocate bytes out of a static char array for the calloc call that would happen while dlsym-ing for calloc. Debugging this was a nightmare, since it would break so early in the process's lifetime that GDB breakpoints weren't functioning. Tracking in a second process seems like a way simpler idea, and probably doesn't have too much of an impact on performance.

1 comments

If $JOB will let you throw it on GitHub, I'll try it!