From: Erik Berglund Newsgroups: comp.os.msdos.djgpp Subject: gcc page fault Lines: 178 Message-ID: Date: Mon, 24 Jan 2000 18:38:49 GMT NNTP-Posting-Host: 194.237.157.206 X-Complaints-To: abuse AT telia DOT com X-Trace: newsb.telia.net 948739129 194.237.157.206 (Mon, 24 Jan 2000 19:38:49 CET) NNTP-Posting-Date: Mon, 24 Jan 2000 19:38:49 CET Organization: Telia Internet To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com I was wondering if anyone could help me find a mysterious problem in gcc 2.95.2: Page fault at eip=0017651f, error=0004 eax=00e45840 ebx=00392604 ecx=00392604 edx=00fd53330 esi=003935fc edi=00391610 ebp=003303b0 esp=003303a4 program=C:\DJGPP\BIN\CC1.EXE cs: sel=00a7 base=81043000 limit=fffeffff ds: sel=00af base=81043000 limit=fffeffff es: sel=00af base=81043000 limit=fffeffff fs: sel=0087 base=0001e3e0 limit=0000ffff gs: sel=00bf base=00000000 limit=0010ffff ss: sel=00af base=81043000 limit=fffeffff App stack: [00332000..001b2000] Exceptn stack: [001a2818..001a08d8] Call frame traceback EIPs: 0x0017651f 0x17651f _free+0x77 0x00174474 0x174474 0x000dc172 0xdc172 0x000ce040 0xce040 0x0000b182 0xb182 0x001627fc 0x1627fc 0x0014edf2 0x14edf2 0x00009b41 0x9b41 0x0000d9cf 0xd9cf 0x0017589a 0x17589a I used objdump on cc1.exe and found that the failing address is _free+0x77. It seems to be in the first call to the "merge" function, and it happens when a for-loop is initialized: for (bp=freelist[bu]; bp; bpp=&(bp->next), bp=bp->next) <---page fault bp=freelist[bu] gives page fault because "bu" has a very high value (bu=edi=0x00391610). bu comes from b2bucket, so I think something goes wrong there. The error seems to be data-dependent, it doesn't show up everytime, only when I run a special sequence of programs, and only in a Win3.11 DOS box. With plain DOS, everything works fine. Now, I have a work-around for this problem and that is to disable Virtual Memory either in Windows or with _CRT0_FLAG_LOCK_MEMORY in gcc. Then everything works fine again. Thanks in advance for any ideas -- Erik Berglund erik2 DOT berglund AT telia DOT com >From malloc.c (version 2.02): static inline int size2bucket(unsigned size) { int rv=0; size>>=2; while (size) { rv++; size>>=1; } return rv; } static inline int b2bucket(BLOCK *b) { if (b->bucket == -1) b->bucket = size2bucket(b->size); return b->bucket; } static inline BLOCK * merge(BLOCK *a, BLOCK *b, BLOCK *c) { int bu; BLOCK *bp, **bpp; #if DEBUG printf(" merge %d/%08x + %d/%08x = %d\n", a->size, a, b->size, b, a->size+b->size+8); #endif CHECK(a); CHECK(b); CHECK(c); if (c == slop) { #if DEBUG printf(" snipping slop %d/%08x\n", slop->size, slop); #endif slop = 0; } bu = b2bucket(c); #if DEBUG printf("bucket for %d/%08x is %d\n", c->size, c, bu); #endif bpp = freelist+bu; for (bp=freelist[bu]; bp; bpp=&(bp->next), bp=bp->next) <---page fault { #if DEBUG printf(" %08x", bp); #endif if (bp == c) { #if DEBUG printf("\n snipping %d/%08x from freelist[%d]\n", bp->size, bp, bu); #endif *bpp = bp->next; break; } } CHECK(c); a->size += b->size + 8; a->bucket = -1; ENDSZ(a) = a->size; CHECK(a); return a; } void free(void *ptr) { int b; BLOCK *block; if (ptr == 0) return; block = (BLOCK *)((char *)ptr-4); #if NUMSMALL if (block->size < SMALL) { block->next = smallblocks[block->size/ALIGN]; smallblocks[block->size/ALIGN] = block; return; } #endif block->size &= ~1; ENDSZ(block) &= ~1; block->bucket = -1; #if DEBUG printf("free(%d/%08x)\n", block->size, block); #endif CHECK(block); if (! (AFTER(block)->size & 1)) { CHECK(AFTER(block)); } if (! (BEFSZ(block) & 1)) { CHECK(BEFORE(block)); block = merge(BEFORE(block), block, BEFORE(block)); } CHECK(block); if (! (AFTER(block)->size & 1)) { CHECK(AFTER(block)); block = merge(block, AFTER(block), AFTER(block)); } CHECK(block); b = b2bucket(block); block->next = freelist[b]; freelist[b] = block; CHECK(block); }