delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/08/06/11:55:52

From: jrubin AT BIX DOT com
Date: Tue, 06 Aug 1996 03:30:44 -0400 (EDT)
Subject: __dpmi_discard_page_contents trouble
To: djgpp AT delorie DOT com
Message-id: <9608060330.memo.28627@BIX.com>

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019