- Dangling pointers (using a pointer to a previously freed space)
- Buffer overflows (writing beyond the space allocated to an object – very typical with strings)
- Heap metadata overwrites (out-of-bounds write to the heap metadata area)
- Uninitialized reads (read from unallocated memory, or allocated but not yet initialized)
- Invalid frees (trying to free a space not allocated)
- Double frees (self-explanatory)
To try DieHard, I downloaded it from github and compiled it. Then I used the demo example to see what the differences were between compiling with or without DieHard.
- Download DieHard according to instructions (or previous post)
- First we will run the demo program without DieHard. Enter the demo directory
- Compile disaster.cpp (this file represents has lots of memory errors)
g++ disaster.cpp -o disaster
- Run the executable
- The output should show some errors. For example, I obtained the following output:
disaster(11054,0x7fff76091000) malloc: *** error for object 0x7fff50d52944: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug Abort trap: 6
- Prepare to compile and run with DieHard according to DieHard/README.md. For example for OS X:
export DYLD_INSERT_LIBRARIES=/path/to/libdiehard.dylib export DYLD_FORCE_FLAT_NAMESPACE=
- Now compiling and running the executable
g++ disaster.cpp -o disaster ./disaster
We obtain some output as follows:
Use DieHard now. Stop memory errors. '7654321' should NOT equal '1234567'. str1 = 'Use DieHard now. Stop memory errors.'
And this is the output expected.
Although as programmers we should prevent the errors in disaster.cpp to occur, DieHard is a great way to prevent these errors causing the program to crash.
What other things can I do with this example?
- How would you correct the program so that it doesn’t have any memory errors?
- Use it with other programs.