Link to home
Start Free TrialLog in
Avatar of GGRUNDY
GGRUNDY

asked on

EXCEPTION_ACCESS_VIOLATION in Win32 environment

Is there a way to create a memory block in such a way that access outside the extent of that block will be guaranteed to hit a memory access (or protection) violation.

For example suppose I wanted to do some fairly heavy processing on an array of data but would prefer to let the hardware handle the bounds checking for me, can it be done?

e.g. in the following code snippet how would I go about constucting the array 'v', so that referencing element 2049 trips a hardware exception of some kind?

void DoIt()
{
  BYTE v[2048];
  while(FillBuffer(v)){
    BYTE* p = v;
    __try{
      while(true)*p++;
      }
    __except(GetExceptionCode()==EXCEPTION_ACCESS_VIOLATION?EXCEPTION_EXECUTE_HANDLER:0){
      continue;
      }
    }
  }
Avatar of jhance
jhance

The simple answer is that C++ has no such facility.  Some operating systems have hooks of some sort that permits setting of hardware breakpoints (often via a hardware DEBUGGING facility) but these things are inherently complex, platform dependent, limited in scope, and not a part of C++.
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
jkr,

Good point but....

1) VirtualProtect() is a "Window-ism" and not a general purpose (i.e. C++ as in this topic area) solution to this question.

2) I also don't think you can quite do what GGRUNDY has asked with VirtualProtect().  The need expressed seems to be to limit access to a specific area and catch any out-of-bounds access.  Virtual protect has limitation in that you can't just set a specific range as OK.  You must set "guard" blocks and HOPE that an erroneous access hits one of the guard blocks.  Other problem is that the size of areas you can protect with VirtualProtect() is limited to a PAGE.  Normally that will be no smaller than 4KBytes.  So you can setup a PAGE and 2 more pages, one on either side, for a total of 3 pages, and then catch any access to the two pages.
Well, you could implement your own 'memory allocation' functionality.

This is just a simple C example, but you could easily make it C++ and wrap it in a class.

#define POOLSIZE     (4096 * 1024)

static char          memPool[POOLSIZE];
static int          allocPoint;

void *Custom_Alloc( int size ) {
     char     *p;

     if ( allocPoint + size > POOLSIZE ) {
          //buffer overflow. Handle however you wish.
          return NULL;
     }

     p = &memPool[allocPoint];

     allocPoint += ( size + 31 ) & ~31;

     return p;
}

This, of course, does not allow freeing(deallocating) memory in the buffer. To do this, you'd have to add some code to maintain a list of pointers to allocated 'chunks' and the size of those 'chunks' and some memmove() logic to optimize the buffer usage.
>>VirtualProtect() is a "Window-ism" and not a general purpose (i.e. C++ as in this topic area)

As is "__try {} __except()" :o)

To your 2nd point - you *could*, even though I wouldn't recommend (BTW, that's the way VC++ guards against stack overflows)
Avatar of GGRUNDY

ASKER

Thanks guys, as usual I'm in your debt.

jhance is perfectly correct, but as I asked what in retrospect is a damn fool question,
I'll accept jkr's answer as he first mentioned VirtualProtect. This comes closest to what I needed and seems to be the Ms approach (AKA Creating Guard Pages). (but is probably to coarse for what I wanted).

Hmmmm. Pellep I don't quite understand how your suggestion helps with hardware rangecheking but if you or someone else can enlighten me, I'll raise some extra points for you.

Once again thanks everyone.