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

Albert Chin egenix-users at mlists.thewrittenword.com
Thu Jan 12 01:10:28 CET 2006


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.

-- 
albert chin (china at thewrittenword.com)
-------------- next part --------------
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;
 }
 


More information about the egenix-users mailing list