I want to understand how does memory leak checkers identify if a free has been called for a given malloc.
malloc can easily be identified by brk system calls, so if i am writing a profiler and do a single stepping on a process which breaks at system calls i can easily understand that malloc has been done.
How can i find if a free has been called for this malloc?
Below is the output from strace. This code has free, how can we tell if free was invoked by checking this strace –
read(0, "13608\n", 4096) = 6
brk(0) = 0x8cc6000
brk(0x8ce7000) = 0x8ce7000
write(1, "File name - /proc/13608/maps\n", 29) = 29
open("/proc/13608/maps", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x55559000
read(3, "00349000-00363000 r-xp 00000000 "..., 4096) = 1046
write(1, "ptr1-ffd1f49a\n", 14) = 14
write(1, "ptr2-ffd1f4a8\n", 14) = 14
write(1, "Buffer read - 00349000-00363000 "..., 102) = 102
write(1, "\n", 1) = 1
write(1, "ptr1-ffd1f49a\n", 14) = 14
write(1, "ptr2-ffd1f4aa\n", 14) = 14
write(1, "Buffer read - 00367000-004a6000 "..., 104) = 104
write(1, "\n", 1) = 1
write(1, "ptr1-ffd1f49a\n", 14) = 14
write(1, "ptr2-ffd1f4bd\n", 14) = 14
write(1, "Buffer read - 08048000-08049000 "..., 123) = 123
write(1, "\n", 1) = 1
write(1, "ptr1-ffd1f49a\n", 14) = 14
write(1, "ptr2-ffd1f4a1\n", 14) = 14
write(1, "Buffer read - ffad8000-ffaf1000 "..., 95) = 95
write(1, "\n", 1) = 1
write(1, "ptr1-ffd1f479\n", 14) = 14
write(1, "ptr2-ffd1f479\n", 14) = 14
write(1, "Buffer read - ffffe000-fffff000 "..., 55) = 55
write(1, "\n", 1) = 1
read(3, "", 4096) = 0
close(3) = 0
munmap(0x55559000, 4096) = 0
write(1, "Starting Address - 00349000\n", 28) = 28
write(1, "Ending Address - 00363000\n", 26) = 26
write(1, "Permissions - r-xp\n", 19) = 19
write(1, "Offset - 00000000\n", 18) = 18
write(1, "PathName - </lib/ld-2.5.so>\n", 28) = 28
write(1, "\n", 1) = 1
write(1, "\n", 1) = 1
write(1, "Starting Address - 00367000\n", 28) = 28
write(1, "Ending Address - 004a6000\n", 26) = 26
write(1, "Permissions - r-xp\n", 19) = 19
write(1, "Offset - 00000000\n", 18) = 18
write(1, "PathName - </lib/libc-2.5.so>\n", 30) = 30
write(1, "\n", 1) = 1
write(1, "\n", 1) = 1
write(1, "Starting Address - 08048000\n", 28) = 28
write(1, "Ending Address - 08049000\n", 26) = 26
write(1, "Permissions - r-xp\n", 19) = 19
write(1, "Offset - 00000000\n", 18) = 18
write(1, "PathName - </fs_user/samirba/myP"..., 49) = 49
write(1, "\n", 1) = 1
write(1, "\n", 1) = 1
write(1, "Starting Address - ffad8000\n", 28) = 28
write(1, "Ending Address - ffaf1000\n", 26) = 26
write(1, "Permissions - rw-p\n", 19) = 19
write(1, "Offset - 7ffffffe6000\n", 22) = 22
write(1, "PathName - <[stack]>\n", 21) = 21
write(1, "\n", 1) = 1
write(1, "\n", 1) = 1
write(1, "Starting Address - ffffe000\n", 28) = 28
write(1, "Ending Address - fffff000\n", 26) = 26
write(1, "Permissions - r-xp\n", 19) = 19
write(1, "Offset - ffffe000\n", 18) = 18
write(1, "PathName - <EMPTY>\n", 19) = 19
write(1, "\n", 1) = 1
write(1, "\n", 1) = 1
exit_group(0) = ?
There is no one to one relationship between a malloc call and a system call.
Typically, a malloc library will get big blocks from the OS
using e.g. brk system call or mmap system call.
Then these big block(s) will be cut in smaller blocks to serve
successive malloc calls. A free will usually not cause a system call
(e.g. munmap) to be called.
So, you cannot really track malloc and free at system call level.
Valgrind can track the memory leaks because it intercepts (and replaces)
malloc, free, …
The Valgrind replacements functions are maintaining a list of allocated blocks.
Real leaks (i.e. memory which cannot be reached anymore, i.e. all pointers to it
have been lost/erased) are found by Valgrind using a scan of all the active
memory.