Page 1 of 1

Magic page fault

Posted: Mon Nov 07, 2005 8:31 pm
by Crazed123
After some code-cleaning and bugfixing (it needed it) my kernel heap initialization code now pagefaults while zeroing out the heap. Said code is rather too long to post here, so I've attached the source file. The fault occurs in the FillDWord() function on line 353, which should just set lwHeapPages*1024 4-byte doublewords to 0 starting at pKernelHeap (0xc1000000). Instead, it causes a page fault with this stuff from the handler:

Code: Select all

$800 pages are being used for the kernel heap.
Address in CR2: $C1400000
Page directory address: $7FFF000
Page directory entry at fault: $7BFB023
Page table entry at fault: $0
gs: $C0160018
fs: $C0160018
es: $7BF0018
ds: $FFC00018
edi: $C1400000
esi: $2CFDB
ebp: $C016CC0C
ebx: $0
edx: $200000
ecx: $100000
eax: $0
int #: $E
error code: $2
eip: $C0100F31
cs: $20
eflags: $10206
useresp: $2CFDC
ss: $C016CC20
Page Fault Exception
The strange thing is that I check the PTE just before the FillDWord() is run, and it contains the correct address, so something must be overwriting the PTE in the FillDWord(). This means that the page table is mapped somewhere into the kernel heap, I just don't understand where or why.

I wish it had taken me less than 3-4 days just to come up with this much information.

Re:Rather annoying page fault

Posted: Tue Nov 08, 2005 1:15 am
by distantvoices
Well ... that's an ok looking heap managing thing, thou I'm not that good at reading pascal.

Here are some hints what to look for:

1. are your pagetables zeroed out ere filling in? This is the source of the most sublte bugs one can ever encounter. canny, if that's the right word.

2. have you already set the pages you use for the kernel memory area to USED in some management bitmap or popped them off some stack of pages? Just in case you happen to allocate a kernel page table more than once. I've encountered this one twice in my os developer carreer.

If I were you I'd go throu the page management code and pester it with a lot of puts and printf's for the sake of it.

HTH :-)

Re:Rather annoying page fault

Posted: Wed Nov 09, 2005 5:50 pm
by Crazed123
1.I do believe line 310 of the posted source file should zero out each new page table.
2.Addding

Code: Select all

pTable:= SandboxTable(Pointer(pKPageDirectory[$304] and $FFFFF000));
for lwPage:= 0 to 1024 - 1 do
 if pTable[lwPage] and $FFFFF000 = longword(pHeapTables[1]) and $FFFFF000 then
  begin
  WriteInt(lwPage);
  WriteLn(PChar(' is equal to pHeapTables[1].'));
  end;
pTable:= UnsandboxTable(pTable);
just before trying to zeroing out the heap prints nothing. This, presumably, means that the second heap page table (the faulting one) isn't mapped anywhere. *Insert string of creative swearing here*

3.This bug only shows symptoms at all when I use more than 64MB of memory. There's got to be a reason for that.
4.When the kernel obtains a page to function as the second page table for the heap the page it recieves is initially a copy of the first page table, despite the fact that the physical addresses and page numbers are entirely different.