[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