2

I've written a debugger using ptrace(2) that is mainly for auditing system calls and redirecting standard IO of a child process. I would also like to detect memory leaks using this debugger.

I thought that it might be as easy as counting references to the system call brk(2), but it isn't. Unfortunately (or fortunately), Linux seems to call brk(2) at the end of the program regardless of whether or not the memory was properly freed.

I've seen this in a program that calls malloc(3) and free(3) and a program that just calls malloc(3) - they both have equal counts of brk(2) calls by the time the program has called exit_group(2), which is happens on return (perhaps I could be interpreting those results incorrectly?).

Or, perhaps exit_group(2) isn't equivalent to 'return' from main, and I should be setting a different break point for auditing the call count of brk(2).

I found a similar question here, but I still haven't found an answer.

I understand that Valgrind is a perfect tool for this, but it would cause considerable overhead.

Does anyone have helpful information on detecting memory leaks with ptrace(2)? Is possible with ptrace(2)? Is there a more practical way? Is there an API for memory debugging child processes?

Edit:

If there's other functions involved with allocate memory, I would count those too. On the page for malloc, it says that mmap(2) is also used in memory allocation. So, I would be counting that too.

Community
  • 1
  • 1
tay10r
  • 4,234
  • 2
  • 24
  • 44
  • 2
    brk() doesn't get called with malloc. I believe it is called in order to give space to the process (aka, brk() is what gives you the process address space). I think that malloc calls then chunk this brked region, and that is why you can't just count calls to brk(). – KrisSodroski May 30 '13 at 17:47
  • Just a note -- at process termination, the OS frees all the memory for the process. This may be the calls at the end that you're seeing. So you might want to look for a place before `exit_group()` to check for these calls. – Dan Fego May 30 '13 at 17:47
  • @DanFego, I know and I wrote that in my question. – tay10r May 30 '13 at 17:50
  • @Magn3s1um, I read that malloc will either call brk(2) or mmap(2) here, http://linux.die.net/man/3/malloc. Could you explain that a little more to me? – tay10r May 30 '13 at 17:51
  • 1
    Real malloc() implementations often maintain an available local pool to satisfy small requests from, so they don't have to go to the OS for more memory in every single case. – Chris Stratton May 30 '13 at 17:52
  • @TaylorFlores No, it says that brk allocates more memory to/from the heap, not that malloc is calling this function necessarily (though it probably does if there isn't enough room in the program break). – KrisSodroski May 30 '13 at 17:54
  • @Magn3s1um, are you saying that it may not call brk(2) and instead it may call mmap(2)? - that I understand, I would do something different for calls to mmap. If that is otherwise not your point, you may need to clarify it a little more to me. Edit: Or are you getting at what Chris Stratton has said? - that I did not know and is a good point. – tay10r May 30 '13 at 18:05
  • @TaylorFlores: Memory is complicated because it is both on the file system and in RAM at the same time. Your program image is actually residing on the hard drive in page files (swap space), or in the kernel's memory region which handles pages. Thinking about it this way, the first time the program starts, it allocates some heap space using brk(). After that, it most likely uses mmap to map the pages in kernel memory into ram, so that you can access that heap allocated space. If it runs out, malloc executes brk() again to increase this program break region. Clearer? – KrisSodroski May 30 '13 at 18:09
  • At least on linux, malloc is implemented on top of mmap(/dev/zero ... MAP_PRIVATE) This can be verified by running any process under strace – wildplasser May 30 '13 at 18:10
  • @Magn3s1um, yeah that's clear, thanks that's helpful – tay10r May 30 '13 at 18:37

1 Answers1

1

Use gdb's heap extension. It will do what you want. IF you want to use it programatically, just pipe the results to your application to do post processing:

https://fedorahosted.org/gdb-heap/

KrisSodroski
  • 2,796
  • 3
  • 24
  • 39
  • looks useful, but I don't think it would be that practical for my use. I would like to avoid running a separate process. Perhaps if I used some of the source code it would help, I'm just horrible at looking at other peoples code – tay10r May 30 '13 at 18:12