delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2000/01/24/14:16:38

Message-ID: <MAPI.Id.0016.00333138303633303030303930303082@MAPI.to.RFC822>
X-MSMail-Priority: Normal
X-Priority: 3
To: djgpp AT delorie DOT com
Cc: erik2 DOT berglund AT telia DOT com
MIME-Version: 1.0
From: "Erik Berglund" <erik2 DOT berglund AT telia DOT com>
Subject: gcc page fault
Date: (Inget eller ogiltigt datum.)
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);
}


- Raw text -


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