Thursday, September 23, 2010

finding mem leaks with valgrind

I had been playing around with CinMonty for a couple weeks now and noticed a fairly big memory leak when I played back or rendered MPEG-PS or the AVC files from my Canon 5D(actually, H264/PCM audio). It must be stated that though I took some programming in school, I'm no C programmer. Handy with the shell, but not a C programmer. In any case, I found it interesting to try and find a memory leak in Cinelerra Monty using valgrind, a profiler/instrumenter/error detector of C programs.

Starting Valgrind
Valgrind is executed at the command line with the name of the program that valgrind will analyze. You can start valgrind with plenty of options, but I started with a few common arguments:
-check for leaks
-log to a file
-log unlimited errors

The command line looks like this:
[mule@ogre 2010_09_22]$ valgrind --leak-check=full --log-file=memLeakCinMonty.txt --error-limit=no cinelerra
Cinelerra 2.1CV
(C) 2006 Heroine Virtual Ltd.
(C) 2006-2010 The CinelerraCV Community
Internal ffmpeg 0.6+fixes
Compiled on Sat Sep 18 14:04:36 EDT 2010

Cinelerra is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under

certain conditions. There is absolutely no warranty for Cinelerra.
FFMPEG::init_picture failed
FFMPEG::init_picture failed
FFMPEG::init_picture failed

I'm not sure what the init_picture failed error messages are, but they occur when I playback or render MPEG-PS or H264 video. This may have something to do with the memory leak.

When running cinlerra under valgrind, the performance of Cinelerra grinds to a halt. Perhaps that's why Julian Seward (the original designer and author of Valgrind) called it valGRIND. However, performance is not so bad that you can't get usable data out of the program. For instance, valgrind shows me the following interesting overlap in memcpy:
==23140== Thread 36:

==23140== Source and destination overlap in memcpy(0x3ce5e1b0, 0x3ce7e1b0, 526848) ==23140== at 0x4A06A3A: memcpy (mc_replace_strmem.c:497)
==23140== by 0x569092: FileBase::update_pcm_history(long) (filebase.C:105)
==23140== by 0x5872F5: FileFFMPEG::read_samples(double*, long) (fileffmpeg.C:648) ==23140== by 0x56ACAA: File::read_samples(double*, long, long, float*) (file.C:1042) ==23140== by 0x500CAE: AModule::render(double*, long, int, int, int, int) (amodule.C:258)
==23140== by 0x658543: VirtualANode::read_data(double*, long, long, long) (virtualanode.C:161)

==23140== by 0x658820: VirtualANode::render_as_module(double**, double*, long, long, long) (virtualanode.C:238)
==23140== by 0x65897A: VirtualANode::render(double*, long, long, long) (virtualanode.C:178)
==23140== by 0x6576F7: VirtualAConsole::process_buffer(long, long, int, long) (virtualaconsole.C:134)
==23140== by 0x502B06: ARender::process_buffer(long, long) (arender.C:232)
==23140== by 0x502969: ARender::run() (arender.C:325)
==23140== by 0x51B4425: Thread::entrypoint(void*) (thread.C:69)

It's good that valgrind found something. Now to fix it! I've handed this info off to Monty. Hopefully he will be able to replicate my problem and fix it.
the mule

No comments: