[egenix-users] SIGBUS from mx/BeeBase/mxBeeBase/btr.c on HP-UX, Alpha, IRIX, Solaris

M.-A. Lemburg mal at egenix.com
Fri Jan 13 15:27:47 CET 2006


Albert Chin wrote:
> On Wed, Jan 11, 2006 at 10:35:24PM +0100, M.-A. Lemburg wrote:
>> The btr.* code was not written by myself and there's a lot
>> of pointer voodoo going on in there, so this will be hard
>> to fix if it's indeed an alignment problem.
> 
> The attached patch works. Thanks to Gary Vaughan for the idea. It can
> probably be cleaned up a little more (3rd arg to memcpy()).
> 
> mx/BeeBase/mxBeeBase/test.py doesn't exercise all of the code but the
> test suite now passes on all problematic platforms.

Thanks for the patch.

We'll see if we can come up with a cleaner way to do this
and maybe force the alignment somehow, so that the number
of changes necessary is limited.

> ------------------------------------------------------------------------
> 
> Index: mx/BeeBase/mxBeeBase/btr.c
> ===================================================================
> --- mx/BeeBase/mxBeeBase/btr.c.orig	2001-06-24 06:54:25.000000000 -0500
> +++ mx/BeeBase/mxBeeBase/btr.c	2006-01-12 00:51:46.355167000 -0600
> @@ -78,10 +78,10 @@
>  #define eAdr(p) *(bRecAddr *)(p)
>  
>  /* based on k = &[key,rec,childGE] */
> -#define childLT(k) bAdr((char *)k - sizeof(bIdxAddr))
> +#define childLT(k) ((char *)k - sizeof(bIdxAddr))
>  #define key(k) (k)
> -#define rec(k) eAdr((char *)(k) + h->keySize)
> -#define childGE(k) bAdr((char *)(k) + h->keySize + sizeof(bRecAddr))
> +#define rec(k) ((char *)(k) + h->keySize)
> +#define childGE(k) ((char *)(k) + h->keySize + sizeof(bRecAddr))
>  
>  /* based on b = &bBuffer */
>  #define leaf(b) b->p->leaf
> @@ -239,6 +239,7 @@
>  {
>      unsigned int i;
>      bKey *k;
> +    bIdxAddr val;
>  
>      if (!buf) {
>          DPRINTF("\n%s: buf empty\n", msg);
> @@ -247,13 +248,16 @@
>      k = key(fkey(buf));
>      DPRINTF("\n%s: buf[%04x], ct=%d, leaf=%d", 
>          msg, buf->adr, ct(buf), leaf(buf));
> -    if (childLT(k)) DPRINTF(", LT(%04x)", childLT(k));
> +    memcpy(&val, childLT(k), sizeof(bIdxAddr));
> +    if (val) DPRINTF(", LT(%04x)", val);
>      if (leaf(buf)) DPRINTF(", prev(%04x), next(%04x)", prev(buf), next(buf));
>      DPRINTF("\n");
>      for (i = 0; i < ct(buf); i++) {
> +        memcpy(&val, rec(k), sizeof(bRecAddr));
>          DPRINTF("  key %3d: %08x rec(%08x)",
> -          i, *(int *)key(k), rec(k));
> -        if (childGE(k)) DPRINTF(" GE(%04x)", childGE(k));
> +          i, *(int *)key(k), val);
> +        memcpy(&val, childGE(k), sizeof(bIdxAddr));
> +        if (val) DPRINTF(" GE(%04x)", val);
>          DPRINTF("\n");
>          k += ks(1);
>      }
> @@ -281,6 +285,7 @@
>      bError rc;                /* return code */
>      bKey *k;
>      unsigned int i;
> +    bIdxAddr val;
>  
>      if ((rc = readDisk(h, adr, &buf)) != 0) {
>          report(rc);
> @@ -289,8 +294,10 @@
>      dumpBuf(h, msg, buf);
>      k = fkey(buf);
>      for (i = 0; i < ct(buf); i++) {
> -        if (childLT(k)) dumpNode(h, msg, childLT(k));
> -        if (childGE(k)) dumpNode(h, msg, childGE(k));
> +        memcpy(&val, childLT(k), sizeof(bIdxAddr));
> +        if (val) dumpNode(h, msg, val);
> +        memcpy(&val, childGE(k), sizeof(bIdxAddr));
> +        if (val) dumpNode(h, msg, val);
>          k += ks(1);
>      }
>      return 0;
> @@ -317,6 +324,7 @@
>      char p[3*MAX_SECTOR_SIZE];
>      bBuffer *cbuf, bufx;
>      bBuffer *buf = &bufx;
> +    bIdxAddr val;
>  
>      if (h->sectorSize > MAX_SECTOR_SIZE) {
>  	DPRINTF("sectorSize exceeds MAX_SECTOR_SIZE; aborting check\n");
> @@ -334,9 +342,10 @@
>      DPRINTF("\n");
>      if (ct(buf)) {
>          if (!leaf(buf)) {
> -            DPRINTF("level %d: recursing on buf[%04x] LT\n", level, childLT(fkey(buf)));
> -            if ((rc = readDisk(h, childLT(fkey(buf)), &cbuf)) != 0) {
> -                DPRINTF("unable to read buffer %04x\n", childLT(fkey(buf)));
> +            memcpy(&val, childLT(fkey(buf)), sizeof(bIdxAddr));
> +            DPRINTF("level %d: recursing on buf[%04x] LT\n", level, val);
> +            if ((rc = readDisk(h, val, &cbuf)) != 0) {
> +                DPRINTF("unable to read buffer %04x\n", val);
>                  return -1;
>              }
>              if (*(unsigned int *)key(lkey(cbuf)) > *(unsigned int *)key(fkey(buf))) {
> @@ -346,9 +355,10 @@
>              _validateTree(h, cbuf, visited, level+1);
>              k = fkey(buf);
>              for (i = 0; i < ct(buf); i++) {
> -                DPRINTF("level %d: recursing on buf[%04x] GE[%d]\n", level, key(childGE(k)), i);
> -                if ((rc = readDisk(h, childGE(k), &cbuf)) != 0) {
> -                    DPRINTF("unable to read buffer %04x\n", childGE(k));
> +                memcpy(&val, childGE(k), sizeof(bIdxAddr));
> +                DPRINTF("level %d: recursing on buf[%04x] GE[%d]\n", level, val, i);
> +                if ((rc = readDisk(h, val, &cbuf)) != 0) {
> +                    DPRINTF("unable to read buffer %04x\n", val);
>                      return -1;
>                  }
>                  if (*(unsigned int *)key(fkey(cbuf)) < *(unsigned int *)key(k)) {
> @@ -410,6 +420,7 @@
>      int lb;                     /* lower-bound of binary search */
>      int ub;                     /* upper-bound of binary search */
>      bool foundDup;              /* true if found a duplicate key */
> +    bRecAddr val;
>  
>      /* Test for empty buffer */
>      if (ct(buf) == 0) {
> @@ -442,10 +453,11 @@
>                      break;
>                  case MODE_MATCH:
>                      /* rec's must also match */
> -                    if (rec < rec(*mkey)) {
> +                    memcpy(&val, rec(*mkey), sizeof(bRecAddr));
> +                    if (rec < val) {
>                          ub = m - 1;
>                          cc = CC_LT;
> -                    } else if (rec > rec(*mkey)) {
> +                    } else if (rec > val) {
>                          lb = m + 1;
>                          cc = CC_GT;
>                      } else {
> @@ -486,7 +498,7 @@
>      root = &h->root;
>      gbuf = &h->gbuf;
>      memcpy(fkey(root), fkey(gbuf), ks(ct(gbuf)));
> -    childLT(fkey(root)) = childLT(fkey(gbuf));
> +    memcpy(childLT(fkey(root)), childLT(fkey(gbuf)), sizeof(bIdxAddr));
>      ct(root) = ct(gbuf);
>      leaf(root) = leaf(gbuf);
>      return bErrOk;
> @@ -513,6 +525,7 @@
>      int extra;                  /* extra counts */
>      int ct;
>      int i;
> +    bIdxAddr z = 0;
>  
>      /*
>       * input:
> @@ -638,28 +651,28 @@
>          /* update LT pointer and parent nodes */
>          if (leaf(gbuf)) {
>              /* update LT, tmp[i] */
> -            childLT(fkey(tmp[i])) = 0;
> +            memcpy(childLT(fkey(tmp[i])), &z, sizeof(bIdxAddr));
>  
>              /* update parent */
>              if (i == 0) {
> -                childLT(pkey) = tmp[i]->adr;
> +                memcpy(childLT(pkey), &tmp[i]->adr, sizeof(bIdxAddr));
>              } else {
>                  memcpy(pkey, gkey, ks(1));
> -                childGE(pkey) = tmp[i]->adr;
> +                memcpy(childGE(pkey), &tmp[i]->adr, sizeof (bIdxAddr));
>                  pkey += ks(1);
>              }
>          } else {
>              if (i == 0) {
>                  /* update LT, tmp[0] */
> -                childLT(fkey(tmp[i])) = childLT(gkey);
> +                memcpy(childLT(fkey(tmp[i])), childLT(gkey), sizeof(bIdxAddr));
>                  /* update LT, parent */
> -                childLT(pkey) = tmp[i]->adr;
> +                memcpy(childLT(pkey), &tmp[i]->adr, sizeof(bIdxAddr));
>              } else {
>                  /* update LT, tmp[i] */
> -                childLT(fkey(tmp[i])) = childGE(gkey);
> +                memcpy(childLT(fkey(tmp[i])), childGE(gkey), sizeof(bIdxAddr));
>                  /* update parent key */
>                  memcpy(pkey, gkey, ks(1));
> -                childGE(pkey) = tmp[i]->adr;
> +                memcpy(childGE(pkey), &tmp[i]->adr, sizeof(bIdxAddr));
>                  gkey += ks(1);
>                  pkey += ks(1);
>                  ct(tmp[i])--;
> @@ -708,6 +721,7 @@
>      bError rc;                /* return code */
>      bBuffer *gbuf;
>      bKey *gkey;
> +    bIdxAddr val;
>  
>      /*
>       * input:
> @@ -728,16 +742,19 @@
>      /* find 3 adjacent buffers */
>      if (*pkey == lkey(pbuf))
>          *pkey -= ks(1);
> -    if ((rc = readDisk(h, childLT(*pkey), &tmp[0])) != 0) return rc;
> -    if ((rc = readDisk(h, childGE(*pkey), &tmp[1])) != 0) return rc;
> -    if ((rc = readDisk(h, childGE(*pkey + ks(1)), &tmp[2])) != 0) return rc;
> +    memcpy(&val, childLT(*pkey), sizeof(bIdxAddr));
> +    if ((rc = readDisk(h, val, &tmp[0])) != 0) return rc;
> +    memcpy(&val, childGE(*pkey), sizeof(bIdxAddr));
> +    if ((rc = readDisk(h, val, &tmp[1])) != 0) return rc;
> +    memcpy(&val, childGE(*pkey + ks(1)), sizeof(bIdxAddr));
> +    if ((rc = readDisk(h, val, &tmp[2])) != 0) return rc;
>  
>      /* gather nodes to gbuf */
>      gbuf = &h->gbuf;
>      gkey = fkey(gbuf);
>  
>      /* tmp[0] */
> -    childLT(gkey) = childLT(fkey(tmp[0]));
> +    memcpy(childLT(gkey), childLT(fkey(tmp[0])), sizeof(bIdxAddr));
>      memcpy(gkey, fkey(tmp[0]), ks(ct(tmp[0])));
>      gkey += ks(ct(tmp[0]));
>      ct(gbuf) = ct(tmp[0]);
> @@ -745,7 +762,7 @@
>      /* tmp[1] */
>      if (!leaf(tmp[1])) {
>          memcpy(gkey, *pkey, ks(1));
> -        childGE(gkey) = childLT(fkey(tmp[1]));
> +        memcpy(childGE(gkey), childLT(fkey(tmp[1])), sizeof(bIdxAddr));
>          ct(gbuf)++;
>          gkey += ks(1);
>      }
> @@ -756,7 +773,7 @@
>      /* tmp[2] */
>      if (!leaf(tmp[2])) {
>          memcpy(gkey, *pkey+ks(1), ks(1));
> -        childGE(gkey) = childLT(fkey(tmp[2]));
> +        memcpy(childGE(gkey), childLT(fkey(tmp[2])), sizeof(bIdxAddr));
>          ct(gbuf)++;
>          gkey += ks(1);
>      }
> @@ -949,7 +966,7 @@
>  	    
>              if ((cc=search(h, buf, key, 0, &mkey, MODE_FIRST)) == CC_EQ) {
>                  if (rec) 
> -		    *rec = rec(mkey);
> +		    memcpy(rec, rec(mkey), sizeof(bRecAddr));
>                  c->buffer = buf; 
>  		c->key = mkey;
>                  return bErrOk;
> @@ -960,10 +977,16 @@
>              }
>          } else {
>              if (search(h, buf, key, 0, &mkey, MODE_FIRST) == CC_LT) {
> -                if ((rc = readDisk(h, childLT(mkey), &buf)) != 0) 
> +                bIdxAddr val;
> +
> +                memcpy(&val, childLT(mkey), sizeof(bIdxAddr));
> +                if ((rc = readDisk(h, val, &buf)) != 0) 
>  		    return rc;
>              } else {
> -                if ((rc = readDisk(h, childGE(mkey), &buf)) != 0) 
> +                bIdxAddr val;
> +
> +                memcpy(&val, childGE(mkey), sizeof(bIdxAddr));
> +                if ((rc = readDisk(h, val, &buf)) != 0) 
>  		    return rc;
>              }
>          }
> @@ -986,6 +1009,7 @@
>      bIdxAddr lastGE = 0;        /* last childGE traversed */
>      unsigned int lastGEkey = 0; /* last childGE key traversed */
>      int height;                 /* height of tree */
> +    bRecAddr z = 0;
>  
>      root = &h->root;
>      lastGEvalid = false;
> @@ -1033,8 +1057,8 @@
>  
>              /* insert new key */
>              memcpy(key(mkey), key, h->keySize);
> -            rec(mkey) = rec;
> -            childGE(mkey) = 0;
> +            memcpy(rec(mkey), &rec, sizeof(bRecAddr));
> +            memcpy(childGE(mkey), &z, sizeof(bRecAddr));
>              ct(buf)++;
>              if ((rc = writeDisk(h, buf)) != 0) return rc;
>  
> @@ -1045,7 +1069,7 @@
>                  if ((rc = readDisk(h, lastGE, &tbuf)) != 0) return rc;
>                  tkey = fkey(tbuf) + lastGEkey;
>                  memcpy(key(tkey), key, h->keySize);
> -                rec(tkey) = rec;
> +                memcpy(rec(tkey), &rec, sizeof(bRecAddr));
>                  if ((rc = writeDisk(h, tbuf)) != 0) return rc;
>              }
>              h->nKeysIns++;
> @@ -1059,9 +1083,15 @@
>            
>              /* read child */
>              if ((cc = search(h, buf, key, rec, &mkey, MODE_MATCH)) == CC_LT) {
> -                if ((rc = readDisk(h, childLT(mkey), &cbuf)) != 0) return rc;
> +                bIdxAddr val;
> +
> +                memcpy(&val, childLT(mkey), sizeof(bIdxAddr));
> +                if ((rc = readDisk(h, val, &cbuf)) != 0) return rc;
>              } else {
> -                if ((rc = readDisk(h, childGE(mkey), &cbuf)) != 0) return rc;
> +                bIdxAddr val;
> +
> +                memcpy(&val, childGE(mkey), sizeof(bIdxAddr));
> +                if ((rc = readDisk(h, val, &cbuf)) != 0) return rc;
>              }
>  
>              /* check for room in child */
> @@ -1073,10 +1103,16 @@
>  
>                  /* read child */
>                  if ((cc = search(h, buf, key, rec, &mkey, MODE_MATCH)) == CC_LT) {
> -                    if ((rc = readDisk(h, childLT(mkey), &cbuf)) != 0) 
> +                    bIdxAddr val;
> +
> +                    memcpy(&val, childLT(mkey), sizeof(bIdxAddr));
> +                    if ((rc = readDisk(h, val, &cbuf)) != 0) 
>  			return rc;
>                  } else {
> -                    if ((rc = readDisk(h, childGE(mkey), &cbuf)) != 0) 
> +                    bIdxAddr val;
> +
> +                    memcpy(&val, childGE(mkey), sizeof(bIdxAddr));
> +                    if ((rc = readDisk(h, val, &cbuf)) != 0) 
>  			return rc;
>                  }
>              }
> @@ -1122,7 +1158,7 @@
>  		return bErrKeyNotFound;
>  
>              /* update record */
> -            rec(mkey) = rec;
> +            memcpy(rec(mkey), &rec, sizeof(bRecAddr));
>              if ((rc = writeDisk(h, buf)) != 0) return rc;
>  
>              h->nKeysUpd++;
> @@ -1133,14 +1169,20 @@
>  
>              /* read child */
>              if ((cc = search(h, buf, key, rec, &mkey, MODE_MATCH)) == CC_LT) {
> -                if ((rc = readDisk(h, childLT(mkey), &cbuf)) != 0) return rc;
> +                bIdxAddr val;
> +
> +                memcpy(&val, childLT(mkey), sizeof(bIdxAddr));
> +                if ((rc = readDisk(h, val, &cbuf)) != 0) return rc;
>              } else {
> -                if ((rc = readDisk(h, childGE(mkey), &cbuf)) != 0) return rc;
> +                bIdxAddr val;
> +
> +                memcpy(&val, childGE(mkey), sizeof(bIdxAddr));
> +                if ((rc = readDisk(h, val, &cbuf)) != 0) return rc;
>              }
>  
>              if (cc == CC_EQ) {
>  		/* update internal key copy too */
> -		rec(mkey) = rec;
> +		memcpy(rec(mkey), &rec, sizeof(bRecAddr));
>              }
>              buf = cbuf;
>          }
> @@ -1183,7 +1225,7 @@
>  
>              /* set mkey to point to deletion point */
>              if (search(h, buf, key, *rec, &mkey, MODE_MATCH) == CC_EQ)
> -                *rec = rec(mkey);
> +                memcpy(rec, rec(mkey), sizeof(bRecAddr));
>              else
>                  return bErrKeyNotFound;
>  
> @@ -1201,7 +1243,7 @@
>                  if ((rc = readDisk(h, lastGE, &tbuf)) != 0) return rc;
>                  tkey = fkey(tbuf) + lastGEkey;
>                  memcpy(key(tkey), mkey, h->keySize);
> -                rec(tkey) = rec(mkey);
> +                memcpy(rec(tkey), rec(mkey), sizeof(bRecAddr));
>                  if ((rc = writeDisk(h, tbuf)) != 0) return rc;
>              }
>              h->nKeysDel++;
> @@ -1209,12 +1251,15 @@
>          } else {
>              /* internal node, descend to child */
>              bBuffer *cbuf;      /* child buf */
> -          
> +            bIdxAddr val;
> +
>              /* read child */
>              if ((cc = search(h, buf, key, *rec, &mkey, MODE_MATCH)) == CC_LT) {
> -                if ((rc = readDisk(h, childLT(mkey), &cbuf)) != 0) return rc;
> +                memcpy(&val, childLT(mkey), sizeof(bIdxAddr));
> +                if ((rc = readDisk(h, val, &cbuf)) != 0) return rc;
>              } else {
> -                if ((rc = readDisk(h, childGE(mkey), &cbuf)) != 0) return rc;
> +                memcpy(&val, childGE(mkey), sizeof(bIdxAddr));
> +                if ((rc = readDisk(h, val, &cbuf)) != 0) return rc;
>              }
>  
>              /* check for room to delete */
> @@ -1237,10 +1282,14 @@
>  
>                  /* read child */
>                  if ((cc = search(h, buf, key, *rec, &mkey, MODE_MATCH)) == CC_LT) {
> -                    if ((rc = readDisk(h, childLT(mkey), &cbuf)) != 0) 
> +                    bIdxAddr val;
> +                    memcpy(&val, childLT(mkey), sizeof(bIdxAddr));
> +                    if ((rc = readDisk(h, val, &cbuf)) != 0) 
>  			return rc;
>                  } else {
> -                    if ((rc = readDisk(h, childGE(mkey), &cbuf)) != 0) 
> +                    bIdxAddr val;
> +                    memcpy(&val, childGE(mkey), sizeof(bIdxAddr));
> +                    if ((rc = readDisk(h, val, &cbuf)) != 0) 
>  			return rc;
>                  }
>              }
> @@ -1272,14 +1321,16 @@
>  {
>      bError rc;                /* return code */
>      bBuffer *buf;               /* buffer */
> +    bIdxAddr val;
>  
>      buf = &h->root;
>      while (!leaf(buf)) {
> -        if ((rc = readDisk(h, childLT(fkey(buf)), &buf)) != 0) return rc;
> +        memcpy(&val, childLT(fkey(buf)), sizeof(bIdxAddr));
> +        if ((rc = readDisk(h, val, &buf)) != 0) return rc;
>      }
>      if (ct(buf) == 0) return bErrKeyNotFound;
>      if (key) memcpy(key, key(fkey(buf)), h->keySize);
> -    if (rec) *rec = rec(fkey(buf));
> +    if (rec) memcpy(rec, rec(fkey(buf)), sizeof(bRecAddr));
>      c->buffer = buf; c->key = fkey(buf);
>      return bErrOk;
>  }
> @@ -1291,14 +1342,16 @@
>  {
>      bError rc;                /* return code */
>      bBuffer *buf;               /* buffer */
> +    bIdxAddr val;
>  
>      buf = &h->root;
>      while (!leaf(buf)) {
> -        if ((rc = readDisk(h, childGE(lkey(buf)), &buf)) != 0) return rc;
> +        memcpy(&val, childGE(lkey(buf)), sizeof(bIdxAddr));
> +        if ((rc = readDisk(h, val, &buf)) != 0) return rc;
>      }
>      if (ct(buf) == 0) return bErrKeyNotFound;
>      if (key) memcpy(key, key(lkey(buf)), h->keySize);
> -    if (rec) *rec = rec(lkey(buf));
> +    if (rec) memcpy(rec, rec(lkey(buf)), sizeof(bRecAddr));
>      c->buffer = buf; c->key = lkey(buf);
>      return bErrOk;
>  }
> @@ -1328,7 +1381,7 @@
>          nkey = c->key + ks(1);
>      }
>      if (key) memcpy(key, key(nkey), h->keySize);
> -    if (rec) *rec = rec(nkey);
> +    if (rec) memcpy(rec, rec(nkey), sizeof(bRecAddr));
>      c->buffer = buf; c->key = nkey;
>      return bErrOk;
>  }
> @@ -1360,7 +1413,7 @@
>          pkey = c->key - ks(1);
>      }
>      if (key) memcpy(key, key(pkey), h->keySize);
> -    if (rec) *rec = rec(pkey);
> +    if (rec) memcpy(rec, rec(pkey), sizeof(bRecAddr));
>      c->buffer = buf; c->key = pkey;
>      return bErrOk;
>  }
> @@ -1373,7 +1426,7 @@
>      if (c->buffer == NULL || !c->buffer->valid)
>  	return bErrBufferInvalid;
>      if (key) memcpy(key, key(c->key), h->keySize);
> -    if (rec) *rec = rec(c->key);
> +    if (rec) memcpy(rec, rec(c->key), sizeof(bRecAddr));
>      return bErrOk;
>  }
>  
> 
> 
> ------------------------------------------------------------------------
> 
> 
> _______________________________________________________________________
> eGenix.com User Mailing List                     http://www.egenix.com/
> https://www.egenix.com/mailman/listinfo/egenix-users

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source  (#1, Jan 13 2006)
>>> Python/Zope Consulting and Support ...        http://www.egenix.com/
>>> mxODBC.Zope.Database.Adapter ...             http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ...        http://python.egenix.com/
________________________________________________________________________

::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,FreeBSD for free ! ::::



More information about the egenix-users mailing list