mtrace(3)
π mtrace(3) β the girl who's watching your mallocs π
okay bestie, so this one lives in the Library Functions Manual, and the manual page is literally called mtrace(3). it's a little library function, not a command, so it's serving libc energy. and honestly? it's giving forensic accountant for your heap. π΅οΈβοΈβ¨
πΈ NAME πΈ
mtrace, muntrace β malloc tracing. no cap, that's the whole vibe. it watches your memory allocations like a nosy bestie reading over your shoulder. π
π LIBRARY π
Standard C library β that's libc, link it with -lc. π
β¨ SYNOPSIS β¨
#include <mcheck.h>
void mtrace(void);
void muntrace(void);
two little functions, both returning void, both taking zero arguments. minimal. clean. iconic. π«Ά
π¦ DESCRIPTION π¦
so. the mtrace() function installs hook functions for the memory-allocation squad: malloc(3), realloc(3), memalign(3), and free(3). these hook functions write down tracing info about every allocation and deallocation that happens. and why do we care?? because that tracing info is how you find memory leaks and catch somebody trying to free memory that was never allocated in the first place. it's literally a receipts-keeping operation. π§Ύ
the muntrace() function does the opposite β it disables the hook functions that mtrace() installed, so no more tracing info gets recorded for the memory-allocation functions. and here's the little detail: if mtrace() never managed to install any hook functions successfully, then muntrace() just... does nothing. it's giving "nothing to cancel, nothing to cancel." π
when mtrace() gets called, it peeks at the environment variable MALLOC_TRACE, which should contain a pathname pointing at the file where the tracing info is gonna be written. if that pathname opens successfully, it gets truncated to zero length (bye bye old contents π).
and if MALLOC_TRACE isn't set at all, or the pathname it gives is invalid or just not writable? then no hook functions get installed and mtrace() has no effect. same deal in set-user-ID and set-group-ID programs: MALLOC_TRACE is ignored, and mtrace() has no effect. security said no. π«
π ATTRIBUTES π
for what all those terms even mean, go look at attributes(7). but here's the tea for this page:
mtrace(),muntrace()β Thread safety: MT-Unsafe. yeah. don't be bringing this one to a multithreaded party. π¬
π STANDARDS π
GNU. that's it, that's the standard. GNU-coded, GNU-approved. β¨
π NOTES π
in normal usage, mtrace() gets called once at the very start of the program's execution, and muntrace() is never called. that's the standard playbook, and honestly? it works.
the tracing output that shows up after you call mtrace() is textual, but it is not designed to be human readable. like, at all. don't read it raw, bestie, you'll cry. π the GNU C library ships a Perl script, mtrace(1), that interprets the trace log and turns it into something actually readable by humans. that's the one you want.
for best results, compile the traced program with debugging enabled, so line-number information actually gets recorded in the executable. no line numbers, no cute little line-number callouts. π
also, real talk: the tracing that mtrace() does incurs a performance penalty β but only if MALLOC_TRACE points to a valid, writable pathname. so if it's doing nothing, it costs nothing. slay. π
π BUGS π
the line-number information that mtrace(1) produces is not always precise. the line number references may actually point to the previous or the following (nonblank) line of source code instead of the exact one. so like. close enough, not perfect. don't @ me. π
π EXAMPLES π
okay here's a whole shell session showing off both the mtrace() function and the mtrace(1) command, on a program that has memory leaks in two different locations. very much a "let's watch it happen" moment. π
first, the program itself:
$ cat t_mtrace.c
#include <mcheck.h>
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
mtrace();
for (unsigned int j = 0; j < 2; j++)
malloc(100); /* Never freed--a memory leak */
calloc(16, 16); /* Never freed--a memory leak */
exit(EXIT_SUCCESS);
}
notice bestie: mtrace(); right at the top, then some allocations that are never freed (leaks!! π¨), then exit(EXIT_SUCCESS).
now when we run it, we see mtrace() diagnosing those leaks at two different locations:
$ cc -g t_mtrace.c -o t_mtrace
$ export MALLOC_TRACE=/tmp/t
$ ./t_mtrace
$ mtrace ./t_mtrace $MALLOC_TRACE
Memory not freed:
-----------------
Address Size Caller
0x084c9378 0x64 at /home/cecilia/t_mtrace.c:12
0x084c93e0 0x64 at /home/cecilia/t_mtrace.c:12
0x084c9448 0x100 at /home/cecilia/t_mtrace.c:16
the first two messages about unfreed memory correspond to the two malloc(3) calls inside the for loop. the final message corresponds to the calloc(3) call β which, plot twist, internally calls malloc(3) anyway. π₯
β SEE ALSO β
mtrace(1), malloc(3), malloc_hook(3), mcheck(3)
go read those too, bestie, iykyk. π
and that's the page!! this one came from Linux man-pages 6.20, dated 2026-02-08. go forth and hunt your leaks, bestie, you've got this. π«Άβ¨π
π¦ where this page comes from
- arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- π the page's license: Linux-man-pages-copyleft
- Copyright 2012, Michael Kerrisk <mtk.manpages@gmail.com>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms