I just finished fixing a problem that ended up being a write through a NULL pointer. It took longer than usual for me to figure out since the platforms I'm used to always fault hard when such a thing happens, so detecting them is trivial.
Is there any way to place a particular variable at address 0, so I could do some basic detection that there was such a problem?
It's trivial to read that address, but if any random variable is located there, then there's no way to determine what are valid and invalid writes to that address.
If it is easy to detect dereferencing a NULL pointer, it would be included in the compiler don't you think?
So, a simple solution is to write a class that wraps your pointer. This way you will know for sure if you doing something to the pointer.
You're obviously not understanding the problem. I know a compile time solution is impossible, that's not what I want. If I can force a particular variable to live at zero, then I can monitor it for changes. It's not used for anything else, it's just a canary.
As for 'wrapping my pointer', well, that's pretty much impossible since pointers are used everywhere, not just in my code. It's a crapton of work to do for every pointer I control, when monitoring a single location for errant writes would be way easier and more reliable.
Canary - early warning that something badly wrong has happened. An archaic reference to the use of birds in the coal-mines to warn of explosive gasses.
If I can force a particular variable to live at zero, then I absolutely know what it's value should be (whatever I put there). If it changes unexpectedly, then bam I know I have a wild pointer. After that it's just divide-and-conquer to find the culprit.
These sorts of things are highly dependent on what processor you are using. Can you tell us please?
If it is the Uno, then you can find the relevant information in the processor's data sheet on page 11 section 6.4 General Purpose Register File.
It shows that this address is mapped to General purpose working register R0 of the processor's instruction set. So storing a variable in that location would mess up what ever code the compiler was trying to run. Or at best the register would constantly be changing and over written by the compiler's code.
Note this is a Harvard architecture processor where the data space and the program space are separate so you would not be vectoring through this point anyway. In the vector table vector 0 is the reset vector which includes External Pin, Power-on Reset, Brown-out Reset and Watchdog System Reset. So changing that would screw up any reset action.
1, Not all microcontrollers / systems map address 0 to the first byte of physical RAM (Arduino UNO does not)
2, If they do, you can read from / write to that location using a NULL pointer you created yourself (can do some serious damage though).
3, I can see no reason why you cannot check if a pointer is NULL before you use it. Extra work is not a good excuse if your code stops working without those checks
4, Harder to find errors (in case you interact with firmwares /RTOS): use a (hardware) debugger. They can trigger on null pointer references in most cases.
Best of luck,
As it turns out, for the Mega 2650 (which info I should have originally included, sorry), there is no RAM at data address zero. Instead the CPU registers are mapped there.
So, detecting null pointer writes isn't possible using a sentinel.
This might sound silly, but why don't you check the pointer before using it?
E.g. malloc will return NULL if it can't allocate the requested memory.
And after freeing the memory, it only requires one line of extra code to set the pointer to NULL so it can be checked again.
Note that I'm not promoting dynamic memory usage, it's just an example.
Or is this in a poorly written 3rd party library?