Using dtrace to profile your program on Mac OSX.
wget https://github.com/brendangregg/FlameGraph/archive/master.zip
unzip master.zip
mv FlameGraph-master FlameGraph
wget https://raw.githubusercontent.com/siddontang/gprof2dot/master/gprof2dot.py
chmod +x gprof2dot.py
Refer to https://github.com/brendangregg/FlameGraph#dtrace
# cat dtrace_cpu.sh
dtrace -x ustackframes=100 -n 'profile-97 /pid == $target/ { @[ustack()] = count(); } tick-60s { exit(0); }' -p $1 -o
out.user_stacks
dtrace_cpu.sh 12345
./stackcollapse.pl < out.user_stacks | ./FlameGraph/flamegraph.pl > user.svg
gprof2dot.py -f dtrace out.user_stacks | dot -Tpng -o output.png
# Notice: sometimes, the dtrace outputs format may be latin-1, and gprof2dot will fail to parse it.
# To solve this problem, you should use iconv to convert to UTF-8 explicitly.
# TODO: add an encoding flag to tell gprof2dot how to decode the profile file.
iconv -f ISO-8859-1 -t UTF-8 out.user_stacks | gprof2dot.py -f dtrace
# cat mem_trace.d
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option aggrate=100us
#pragma D option bufpolicy=fill
#pragma D option bufsize=100m
// rjem is only for jemalloc.
/*
pid$1::_rjem_mallocx:entry
{
self->trace = 1;
self->size = arg0;
}
pid$1::_rjem_mallocx:return
/self->trace == 1/
{
@stacks[ustack(10)] = count();
self->trace = 0;
self->size = 0;
}
pid$1::_rjem_rallocx:entry
{
self->trace = 1;
self->size = arg0;
}
pid$1::_rjem_rallocx:return
/self->trace == 1/
{
@stacks[ustack(10)] = count();
self->trace = 0;
self->size = 0;
}
*/
pid$1::malloc:entry
{
self->trace = 1;
self->size = arg0;
}
pid$1::malloc:return
/self->trace == 1/
{
@stacks[ustack(10)] = count();
self->trace = 0;
self->size = 0;
}
profile:::tick-10s
{
exit(0);
}
END
{
printa(@stacks);
}
sudo ./mem_trace.d $1 > out.mem_stacks
iconv -f ISO-8859-1 -t UTF-8 out.mem_stacks| ./gprof2dot.py -f dtrace | dot -Tsvg -o mem_graph.svg
./FlameGraph/stackcollapse.pl < out.mem_stacks | ./FlameGraph/flamegraph.pl --color=mem > mem.svg