J
jacob navia
In a recent discussion about preconditions, I argued that testing ALL
preconditions would be unpractical. As an example of a precondition
impossible to test I presented the problem to know if a pointer
points to a really readable place in memory.
The windows API provides the function
bool IsBadReadPtr(const void *lp, size_t ucb);
This takes a pointer and a size and returns true if it is OK, zero
if it fails.
Problem is, that is only present under windows.
But after doing some research, I found the following equivalent,
written in almost standard C.
---------------------------------------------------------cut here
/* Heavily adapted from:
http://fixunix.com/linux/337646-isbadreadptr-linux.html */
#include <setjmp.h>
#include <signal.h>
static int PtrTestInstalled;
static jmp_buf PtrTestJmpBuf;
static void PtrTestHandler(int nSig)
{
if (PtrTestInstalled)
longjmp(PtrTestJmpBuf, 1);
}
int IsBadReadPtr(void* lp, size_t ObjectSize)
{
size_t i;
volatile unsigned char c;
int r = 1;
void (* PrevHandler)(int);
PtrTestInstalled = 1;
if (setjmp(PtrTestJmpBuf)) {
r = 0;
goto Ret;
}
PrevHandler = signal(SIGSEGV, PtrTestHandler);
for (i = 0; i < ObjectSize; i ++)
c = ((unsigned char*)lp);
Ret:
PtrTestInstalled = 0;
signal(SIGSEGV, PrevHandler);
return r;
}
--------------------------------------------------------cut here
This looks like a promising stuff. The only non-standard
thing here is the SIGSEGV constant. That constant is not
in the standard but defined under windows, linux, and
most Unix variants.
Does anybody see any potentially non-standard stuff here?
Thanks
preconditions would be unpractical. As an example of a precondition
impossible to test I presented the problem to know if a pointer
points to a really readable place in memory.
The windows API provides the function
bool IsBadReadPtr(const void *lp, size_t ucb);
This takes a pointer and a size and returns true if it is OK, zero
if it fails.
Problem is, that is only present under windows.
But after doing some research, I found the following equivalent,
written in almost standard C.
---------------------------------------------------------cut here
/* Heavily adapted from:
http://fixunix.com/linux/337646-isbadreadptr-linux.html */
#include <setjmp.h>
#include <signal.h>
static int PtrTestInstalled;
static jmp_buf PtrTestJmpBuf;
static void PtrTestHandler(int nSig)
{
if (PtrTestInstalled)
longjmp(PtrTestJmpBuf, 1);
}
int IsBadReadPtr(void* lp, size_t ObjectSize)
{
size_t i;
volatile unsigned char c;
int r = 1;
void (* PrevHandler)(int);
PtrTestInstalled = 1;
if (setjmp(PtrTestJmpBuf)) {
r = 0;
goto Ret;
}
PrevHandler = signal(SIGSEGV, PtrTestHandler);
for (i = 0; i < ObjectSize; i ++)
c = ((unsigned char*)lp);
Ret:
PtrTestInstalled = 0;
signal(SIGSEGV, PrevHandler);
return r;
}
--------------------------------------------------------cut here
This looks like a promising stuff. The only non-standard
thing here is the SIGSEGV constant. That constant is not
in the standard but defined under windows, linux, and
most Unix variants.
Does anybody see any potentially non-standard stuff here?
Thanks