Mail Archives: djgpp/1996/08/06/11:55:52
I'm experimenting with using guard pages before and after
critical data structures, but I am encountering
behaviour I don't understand.
Below is a test program that statically allocates an array and
calls __dpmi_discard_page_contents to delete one page of
address space in the middle of the array.
[ Yeah, I know I could just mark it read only;
I'm experimenting (and finding bugs) ;) ]
The program then writes to each byte before and after the
non-existant page (which should succeed, and does) and then
writes to the first byte of the bad page.
Writing to the non-existant page DOES NOT cause a page fault.
The stubbed version (a.exe) crashes somewhere in _exit.
The unstubbed version (go32-v2 a.out) does not crash.
compiled with gcc -g -Wall test.c
Results of "a.exe" - page fault occurs during program exit.
c:\scheme\jsc\runtime>a.exe
wrote to legal pages
shouldn't get here
Page fault cr2=0000c37c at eip=132a; flags=3046
eax=00df0001 ebx=000000af ecx=00000000 edx=0000e600 esi=00001000 edi=10000000
ebp=00000000 esp=00000400 cs=a7 ds=af es=8f fs=0 gs=0 ss=8f error=0006
eip = 132a is in _exit=1270 (according to gdb a.out; info functions)
cr2 = c37c is between _stub_info=b614 and __387_load_hook=e620
Results of "go32-v2 a.out" - no page fault
c:\scheme\jsc\runtime>go32-v2 a.out
wrote to legal pages
shouldn't get here
------ test.c ------
#include <stdio.h>
#include <dpmi.h>
#define ROUND_UP(x) ((4095+(int)x)&~4095)
char foo[4096*3];
int main(void)
{
int status;
__dpmi_meminfo dpmi;
char *p;
char *page = (char *)ROUND_UP(foo);
/* delete one page of address space */
dpmi.address = (int)page;
dpmi.size = 1;
status = __dpmi_discard_page_contents(&dpmi);
if (status) {
printf("dpmi error = %d\n",status);
exit(status);
}
/* write to legal pages */
for (p = foo; p<page; ++p) {
*p = 0;
}
for (p = page+4096; p<foo+sizeof(foo); ++p) {
*p = 0;
}
printf ("wrote to legal pages\n");
/* write to illegal page */
*page = 0;
printf ("shouldn't get here\n");
exit(0);
}
- Raw text -