Purify it !

Posted by – April 1, 2010

What a wierd title. Or may be not. Depending of your experience, you may or may not know these life-saver tools, when strange things happen to your program and you have absolutely no clue about what the hell is going on. No starting point to look at. It sometimes happens, sometimes not, as if the computer was an organic lifeform. Here enters purify like programs (‘valgrind’ on linux, ‘purify’ or ‘bound checker’ on Windows) , which adds realtime checks around almost every kind dynamically allocated memory block to detect the root of evils: buffer overflows.

You may think: “well that’s cool but i use PureBasic, and barely never dynamically allocated memory block, as all is managed by natives libraries”. You are right. But may be you use pointers, or even OS calls. And this is where things got a bit more complicated, as pointers is the ultimate power in programming. And as all power, it has to be used wisely. Are don’t get me wrong: you will use them wisely. Until something is changed in your code which impacts that and suddenly the pointer gets crazy, without any notification. On a big program, it could be very long to isolate the bug. I have some ‘souvenirs’ of very vicious cases which took me several days to fix. And as PureBasic executables uses a custom debugger format, it is not compatiable with any of the purifier tools. Too bad. Until now.

Before going further in the details, let’s try to really understand how a purifier works. Basically, it puts ‘cookies’ around every potientally dangerous code items: variables, arrays, strings, dynamically allocated memory block. What’s a cookie ? It’s just a predefined value (usually 32 bits), often something funny like $BADBEEF or $BADF00D. At every executed line, the purifier (which holds a list of all the installed cookies address) will check them, and if one is broken will stop. That means than something has erased this area which should never have been erased. Ever. That’s a bit like a code integrity check. As we could imagine, the bigger your program is, the slower the purifier will be. And it can be very very slow, that’s why it’s possible to tune it to check only some kind of data, and at which rate.

Consider this code:

Procedure a()

a.l = 10

*CrazyPointer.Long = @a
*CrazyPointer+1
*CrazyPointer\l = 152  ; stack corruption

EndProcedure
a()

This is an obvious error. But it does go unnoticed when running in standard release/debug mode. On some more retricrive OS, it could even crash. If you activate the purifier it catch it immediately and report a stack corruption. Let’s try another less obvious one:

*LocalDrive = AllocateMemory(#MAX_PATH)
GetModuleFileName_(0, *LocalDrive, #MAX_PATH)

This snippet uses Windows API, and get back the executable name. So far so good. Now what happen if you change the program mode from ASCII to Unicode ? You end up with a buffer which is twice smaller as requested, and chances are high than you will be hit with a nasty buffer overflow. Again the purifier will detect it as the ‘cookie’ put at the end of the allocated memory block will be overwritten.

And there is quite some cases where it can happen: a structure too small to recieve the expected data, wrong associated structure to a pointer, pointer manipulation error, wrong API call, etc. For most of them, the purifier will catch the error. There are some limitations tough: threaded program could report wrong line and  if a pointer is really filled with a random value, it won’t be noticed by it (but probably by the debugger as IMA – Invalid Memory Access).

The purifier is now available in PureBasic 4.50 !

Leave a Reply