views:

2044

answers:

14

I've been asked to maintain a large C++ codebase full of memory leaks. While poking around, I found out that we have a lot of buffer overflows that lead to the leaks (how it got this bad, I don't ever want to know).

I've decided to removing the buffer overflows first. To make my bug-hunting easier, what tools can be used to check for buffer overruns?

+1  A: 

Visual Studio has a /GS compiler flag that adds buffer overflow protection. Are there any others?

MrValdez
+17  A: 

On Linux I'd use Valgrind.

diciu
Interesting. I'll see if this codebase can compile on Linux once I can't think of anything else to fix (although, I highly doubt it).Upvoted because someone else might find your answer useful.
MrValdez
It's a bit of an overkill just for buffer overflow ...
PierreBdR
Buffer overflow is a very nasty bug because the effects are not necessarily close to the cause (i.e. it can crash 500 lines later). If the stack gets smashed you'll need all the help you can get debugging. This is where Valgrind shines - it traps the overflow as soon as it happens.
diciu
There are frontends to valgrind, like kcachegrind that make it more usable.
hayalci
Valgrind might be a slight overkill for buffer overflows, but the original question mentioned the program being full of memory leaks. Valgrind should help with quite a few other memory problems as well.
Caleb Huitt - cjhuitt
+1  A: 

You can try Visual Leak Detector - I used it myself, and it is the first thing I'd recommend for mem-leak detection.

Paulius Maruška
+2  A: 

The problem with /GS is it won't actually scan for bugs. It will just alert you after the fact. It seems like you are looking for a tool which will scan your existing code for potential buffer over/under runs.

A good tool for this, and other defects, is the Microsoft PreFAST tool.

Information here

JaredPar
Missing the link to the page
crashmstr
Thanks, error in the anchor tag.
JaredPar
+7  A: 

IBM's Purify will do this, you run your app under it and it will give you a report of all errors (including other ones).

To kill memory leaks, use UMDH - run your app, take a snapshot of the memory, run it again, snapshot and then use a diff tool to see the allocations made since the first run through (note you must run your app once, and take snapshots as best you can).

gbjbaanb
Good to know that it doesn't run on Windows 7 x64.
Sorin Sbarnea
+4  A: 

Check on electric-fence, it is design just for buffer overflow ! It does not slow down the code itself (but slow down allocation/deallocation). It works and linux and windows.

It works by adding a segment with no read or write access before and after each allocated space. Trying to access this memory end up as a segmentation fault on UNIX and a memory violation (or something similar) on Windows.

PierreBdR
+2  A: 

My vote goes to Rational Purify. Extremely powerful with a price to match. Makes short work of lots of problems and can really pay for itself. Also, is available on most *nix. Not sure about Windows, though.

Available on Windows as well
Andrew Stein
+1  A: 

I'd recommend the free "leakfinder" tool on the CodeProject by Jochen Kalmbach. See my post for more details on this thread (and the other answers) on this memory leak question

John Sibly
+2  A: 

MS:

Roskoto
+6  A: 

Consider using more modern data structures as a way of avoiding buffer overflows. Reading into a std::string won't overflow, and std::vectors are much safer than arrays. I don't know what your application is, and it's possible that raw buffers are used because you need the speed, but it's more common that they are used because that's what the original programmers were comfortable with.

Searching for memory leaks with the tools mentioned is a good idea, but they may not find all potential leaks, while using standard strings and container classes can eliminate problems you didn't realize you had.

David Thornley
A: 

On Windows for memory leaks/buffer overruns and other runtime error detection you can use:

I think they worth their price if you have large projects that need cleanup.

Dan Cristoloveanu
+2  A: 

The BoundsChecker component of Compuware's Devpartner does this very well in terms of dynamic execution. For static testing, I'd recommend pc-lint and flex-lint coupled up to Riverblade's visual lint for usability and reporting. If you have been handed a new code base, I'd recommend starting out with static analysis with reasonably loose rules so you catch just the nasty stuff. As the codebase improves you can tightent the rule set.

If you need to do this on Windows Mobile / Windows CE, check out Entrek's code snitch

Another tool to consider if the code makes it into the field is AQtrace, which basically analyses crashes on user machines and sends you the details. (Just in case all that boundchecking, purifcation, linting, valgrinding etc.. misses something)

Shane MacLaughlin
A: 

Hello, why don't you tyr with BugFighter from www.bugfighter-soft.com ?

It is compiler and plattform indipendent.

You can find error on single an multidimensional arrays, for example:

int x[10]; int y[10][10][10];

int ii;

...

ii = 10;

x[ii] = 9;

y[0][ii][0] = 7;

It works also on arrays inside structs:

typedef struct ex_s { int x[10]; int y[10][10][10]; } EX;

...

EX sEX;

ii = 10;

sEX.x[ii] = 9;

sEX.y[0][ii][0] = 7;

VALGRIND

Valgrind doesn't do it, see:

http://valgrind.org/docs/manual/faq.html

5.2. Why doesn't Memcheck find the array overruns in this program?

int static[5];

int main(void) { int stack[5];

static[5] = 0; stack [5] = 0;

return 0; }

Unfortunately, Memcheck doesn't do bounds checking on static or stack arrays. We'd like to, but it's just not possible to do in a reasonable way that fits with how Memcheck works. Sorry.

PURIFY

Also Purify doesn't check static memory, it only works on intere structure, see:

http:// system.nada.kth.se/unix/software/rational/purify/html/ht_how_p_finds_memacc_errs.htm

How Purify checks statically allocated memory

In addition to detecting access errors in dynamic memory, Purify detects references beyond the boundaries of data in global variables and static variables, that is, data allocated statically at link-time as opposed to dynamically at run time.

Here is an example of data that is handled by the static checking feature:

int array[10]; main() { array[11] = 1; }

In this example, Purify reports an array bounds write (ABW) error at the assignment to array[11] because it is 4 bytes beyond the end of the array.

Purify inserts red guard zones around each variable in your program's static-data area. If the program attempts to read from or write to one of these guard zones, Purify reports an array bounds error (ABR or ABW).

Purify inserts guard zones into the data section only if all data references are to known data variables. If Purify finds a data reference that is relative to the start of the data section as opposed to a known data variable, Purify is unable to determine which variable the reference involves. In this case, Purify inserts guard zones at the beginning and end of the data section only, not between data variables.

Purify provides several command line static checking options and directives to aid in maximizing the benefits of static checking.

Notes:

*

  Purify does not detect array bounds errors between individual local (stack) variables. On Solaris, Purify inserts guard zones between stack frames, causing stack array bounds read (SBR) and stack array bounds write (SBW) errors on accesses that extend beyond all the local variables in a function. Purify detects accesses beyond the end of the stack (BSR and BSW errors) on all platforms, as well as UMR errors on all stack variables.
*

  Due to the flexibility of manipulating pointers in C and C++ programs, a pointer can accidentally access a legally allocated block of memory that is in fact beyond the block that you are attempting to access. In this case, Purify does not signal illegal memory access errors because the memory is properly allocated and initialized. Purify monitors memory accesses and the blocks of memory accessed, not pointer arithmetic. You can use the -static-checking-guardzone option to adjust the size of red zones to find these types of errors.
*

  Purify detects array bounds errors in arrays within C structures only when the access extends beyond the entire structure.

Best Regards

+1  A: 

I'm surprised no one's mentioned Application Verifier (free!) on Windows. Visual Leak Detector (mentioned in another answer) is absolutely amazing for tracking many types of memory leak, but Application Verifier is top dog for tracking memory errors like buffer overruns, double frees, and buffer use after free (plus many, many more).

Edit: And it's very, very easy to use.

280Z28