For tracking down memory leaks and other performance issues, the ease and flexibility of Valgrind may make up for slow runtimes. Memory and performance problems plague most of us, but tools are available that can help. One of the best, most powerful and easiest to use is Valgrind. One thing stands out when you use Valgrind–you do not need to recompile, relink or modify your source code. Also have a look at KCacheGrid and Alleyoop which work with valgrind.
Although I wonder, from experience, if it’s memory checking is fully accurate. It often gives possibly lost blocks…
If you’re using c, you might as well use mtrace to just check for leaks.
Valgrind is nice for finding where your program is seg faulting itself too.
Awesome program..
Although, with leaks, even confirmed, it doesn’t say where the pointer to the block was lost, just says where you allocated it. Anybody know how to change that?
When Valgrind is mistaken about leaks, you can suppress it complaining. This is essential for OpenSSL, for example. Valgrind reports many bogus leaks about it.
Example of openssl.supp:
http://cvs.gnome.org/viewcvs/xmlsec/tests/openssl.supp?rev=1.4&view…
is better done by other means, such as using PC Lint, or other equivalent tools for the given language. Other than automated tools, having experienced, competent programmers do a code review will also catch a lot of things before needing such a tool. Also, if you follow certain coding standards, much of this whole mess can be avoided.
Where Valgrind would be most useful for checking for memory errors is when using libraries you don’t have the source code for. Also, doing the cache usage analysis is something that is likely best done by something like Valgrind, though I suspect there’s some application that can do a static analysis of cache usage by looking at the source code, assuming support for the appropriate language.
Valgrind is now one of those indespensible tools. At one point, I spent two weeks trying to hunt down a stupid memory leak that was clobbering my program. I was suggested to try downloading valgrind on IRC, and had the leak nailed 48 hours later.
When will it be usable on the amd64? I’ve been itching for a good memory debugger.
It sounds very much like you’ve never worked on large software projects. When you experience spurious, rare, random crashes on an application with, say, 1 million lines of code, how does code review help you?
And how does a static analysis help you with cache usage? For most non-trivial applications, it’s simply impossible to do, since a static analysis doesn’t even see the input data.
Valgrind is an awesome tool. It’s one of these tools that one uses as a last resort, or just to get that warm fuzzy. Code reviews and sticking to good coding practices is valuable, but it’s complementary to valgrind.
In fact, I have worked on very large embedded applications for controlling CNC machines and press brakes.
While it might not be as easy to do static analysis of cache usage, most applications don’t have that issue as the most vital performance problem. If you’re working on a game or a codec, then it becomes truly important to squeeze every bit of speed out of it. In cases such as those, however, you might not be able to truly run software at a speed fast enough to ever achieve the results you need, due to such things as timing out and having to switch to something else, causing failures. You definitely can’t run machine control software as slow as Valgrind would make it run and expect anything less than disaster.
I’d suggest you look at Gimpel PC Lint, which does some great analysis of C/C++ code, and will likely find most of the errors that lead to random crashes due to memory errors. It isn’t a complete solution, of course, but neither is Valgrind a complete solution. Almost all random crashes caused by your own code will be something PC Lint will warn against, and almost all the other ones will fall to the eyes of someone that knows what they are doing in a code review (best with 3-5 people). If you use PC Lint (or the equivalent for your language) most things will be caught, and that analysis is much faster than debugger time, and much faster than running the application at a small fraction of normal speed. Most memory errors are a result of careless design and/or implementation where ownership and responsibilities are not understood or enforced.
In C++, there are certain things the compiler will do for/to you that can cause unexpected behavior. I ran into a situation where the CNC machine software I was working on didn’t shut down cleanly, because of a dangling pointer. With all the warnings turned on in the compiler, no warnings were emitted. The company I worked for (I inherited that problem code to work on) had a rather ugly solution: instead of worrying about shutting it down cleanly, they had another process terminate it, so no error message would appear. What was the source of the problem? Nothing Valgrind would have ever found, and it would have taken way too long to run it to be practical, and maybe not even possible before time constraints caused failure: it was a case of the compiler providing a default operator =() which allowed a shallow copy of a data structure in one case early on in the initialization to occur. Applying good coding standards (and enforcing them via a code review with no mercy) would have solved that problem long before it was a real problem and released into the world at large. If they had followed the coding standard of always either explicitly defining operator=() to work correctly or to declare one private, that would have avoided a HUGE amount of debugger time.
Another thing that allows large programs to be properly tested is structuring it in such a way that you can do proper unit tests from the bottom and going up, without having to run the entire application. That CNC software was an example of something that wasn’t structured properly to allow that, and a huge amount of software is also guilty of such design flaws that make proper testing impossible, due to the cyclic dependencies. For a great book that goes into these issues, get yourself a copy of “Large-Scale C++ Design” by John Lakos. The press brake software I was assigned primary design and code review duties was properly structured, and far less debug time was needed in development up to the time I was there, and testing was far easier. Constant code review was done on it, using both PC Lint (useful to catch things that a tired person wouldn’t notice) and myself to catch other things, such as potential race conditions or threading issues. The most useful time for code review is during development, as the code is written, and before you hand it over to SQA for testing (you do have testers other than yourself, right? ).
If you don’t follow good practices such as code review and designing for testability and coding standards appropriate to your language, then you are left wondering what’s going on, and something like Valgrind may appear to be the best option for catching errors. Almost all crashing errors are the result of stupid careless mistakes that will be caught by code review and running something like PC Lint. Setting pointers to 0 after releasing them and setting them to a known value at the start may seem excessive and wasteful of code and CPU cycles, but the reliability that results is priceless if you value development time.
The question becomes: what do you want to spend your time doing, adding functionality and optimizing things for time once everything works while achieving fairly stable progress, or getting experience with the debugger and other tools and being stuck at some point for a long period of time? The turtle and the hare fable comes to mind…