--_000_MN2PR06MB55017A7261FA27380778753BAFEA0MN2PR06MB5501namp_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable
<repost since the previous message came as 64 encoded, apologies>
Hello Howard,
we are not able to reproduce the issue consistently so test code is not ava= ilable at this time, and I do believe this issue will be present in the lat= est code as well since Myk also reported the same.. Attaching analysis fro= m our side, hope it helps.
The call stack what we have seen is,
#0 0x0011b62e in mdb_cursor_put (mc=3D0xffe52d18, key=3D0xffe52e74, dat= a=3D0xffe52e6c, flags=3D0) at mdb.c:6688
#1 0x0011c8ec in mdb_put (txn=3D0xdc13f008, dbi=3D2, key=3D0xffe52e74, = data=3D0xffe52e6c, flags=3D0) at mdb.c:8771
#2 0x00b792b8 in LMDB::LMDBContext::createSession (this=3D0x80ca418, si= d=3D0x8297be4 "sidebf3708f0fd9fcb8e062529da47adf51402dfc4600000000+") at lm= dbint.cc:460
#3 0x08053564 in updateLMDB (request=3D..., forward=3D@0xffe5315f) at s= essionserver.cc:1075
#4 processRequestWithoutResponse (request=3D..., forward=3D@0xffe5315f)= at sessionserver.cc:1160
#5 0x08056a80 in processRequest (this=3D0x80b2ac0, fd=3D33) at sessions= erver.cc:1189
#6 readFromSock (this=3D0x80b2ac0, fd=3D33) at sessionserver.cc:1342
#7 SockHandler::ioReady (this=3D0x80b2ac0, fd=3D33) at sessionserver.cc= :1455
#8 0x00ba2592 in runCoreDispatcher (default_t=3D<value optimized out>, = flags=3D-1) at fds.cc:889
#9 0x00ba2ff7 in DSEvntFds::runDispatcher () at fds.cc:945
#10 0x080559c6 in main () at sessionserver.cc:1739
Here it is helpful to examine frames #0 and #1 in detail in relation to the= relevant source code /libraries/liblmdb/mdb.c.
Frame #1
#1 0x0011c8ec in mdb_put (txn=3D0xdc13f008, dbi=3D2, key=3D0xffe52e74, dat= a=3D0xffe52e6c, flags=3D0) at mdb.c:8771
mc =3D {mc_next =3D 0x0, mc_backup =3D 0x0, mc_xcursor =3D 0x0, mc_= txn =3D 0xdc13f008, mc_dbi =3D 2, mc_db =3D 0xdc13f088, mc_dbx =3D 0xe12150= 38, mc_dbflag =3D 0xdc1cf09a "\033", '\032' <repeats 51 times>, mc_snum =3D= 0, mc_top =3D 0, mc_flags =3D 0, mc_pg =3D {0x0, 0x80b2ac0, 0xffe52d68, 0x= 28afce, 0xdc13f008, 0x80ce9b0, 0xffe52dc8, 0x4c5ff4, 0x2b, 0x80b2ac0, 0xffe= 52d98, 0x49209a, 0x2b, 0x4c5ff4, 0x2121cb, 0x21576c, 0x8297d34, 0x3497af, 0= x21576c, 0x21316a, 0x8297d34, 0x80ac7b0, 0x1e, 0x46eed6, 0x2b, 0x0, 0x80ce9= b0, 0x4c5ff4, 0x80ac7b0, 0x8297d34, 0xffe52df8, 0x46fb96}, mc_ki =3D {0, 20= 89, 51120, 2058, 30, 0, 16796, 17, 11760, 65509, 3, 0, 32040, 2089, 30, 0, = 0, 0, 0, 0, 3, 0, 24564, 76, 51120, 2058, 10944, 2059, 11800, 65509, 64758,= 70}} <--------
mx =3D {mx_cursor =3D {mc_next =3D 0x38, mc_backup =3D 0x3, mc_xcur= sor =3D 0x0, mc_txn =3D 0x0, mc_dbi =3D 0, mc_db =3D 0x28, mc_dbx =3D 0x0, = mc_dbflag =3D 0x0, mc_snum =3D 3, mc_top =3D 0, mc_flags =3D 17, mc_pg =3D = {0x3a93d8, 0x10, 0x0, 0x18, 0x3a93a0, 0x0, 0x3a93d0, 0x289abe, 0x3a93a0, 0x= ffe52d3f, 0xffe52c68, 0x28afce, 0xffe52dbc, 0xffe52db4, 0x3, 0x4c5ff4, 0x11= , 0x36c99b, 0x6e, 0x77, 0x7c, 0x5b, 0x38, 0x289abe, 0x0, 0x0, 0x0, 0x28, 0x= 0, 0x0, 0x3, 0x10}, mc_ki =3D {37848, 58, 51611, 54, 110, 0, 119, 0, 124, 0= , 91, 0, 58, 0, 39614, 40, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 2, 0, 18, 0, 136= , 0}}, mx_db =3D {md_pad =3D 3838936, md_flags =3D 51611, md_depth =3D 54, = md_branch_pages =3D 110, md_leaf_pages =3D 119, md_overflow_pages =3D 124, = md_entries =3D 91, md_root =3D 56}, mx_dbx =3D {md_name =3D {mv_size =3D 6,= mv_data =3D 0x0}, md_cmp =3D 0, md_dcmp =3D 0, md_rel =3D 0x40, md_relctx = =3D 0x0}, mx_dbflag =3D 0 '\000'}
rc =3D 0
And source code for mdb_put() is from mdb.c
int
mdb_put(MDB_txn *txn, MDB_dbi dbi,
MDB_val *key, MDB_val *data, unsigned int flags) {
MDB_cursor mc;
MDB_xcursor mx;
int rc;
if (!key || !data || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL;
if (flags & ~(MDB_NOOVERWRITE|MDB_NODUPDATA|MDB_RESERVE|MDB= _APPEND|MDB_APPENDDUP))
return EINVAL;
if (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED))
return (txn->mt_flags & MDB_TXN_RDONLY) ? E= ACCES : MDB_BAD_TXN;
mdb_cursor_init(&mc, txn, dbi, &mx); <-------- see source c= ode below
mc.mc_next =3D txn->mt_cursors[dbi];
txn->mt_cursors[dbi] =3D &mc;
rc =3D mdb_cursor_put(&mc, key, data, flags); <-------- see= Frame #0
txn->mt_cursors[dbi] =3D mc.mc_next;
return rc;
}
Source Code For mdb_cursor_init() From mdb.c
/** Initialize a cursor for a given transaction and database. */ static voi= d mdb_cursor_init(MDB_cursor *mc, MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *m= x) {
mc->mc_next =3D NULL;
mc->mc_backup =3D NULL;
mc->mc_dbi =3D dbi;
mc->mc_txn =3D txn;
mc->mc_db =3D &txn->mt_dbs[dbi];
mc->mc_dbx =3D &txn->mt_dbxs[dbi];
mc->mc_dbflag =3D &txn->mt_dbflags[dbi];
mc->mc_snum =3D 0; <--------
mc->mc_top =3D 0; <--------
mc->mc_pg[0] =3D 0; <--------
mc->mc_ki[0] =3D 0;
mc->mc_flags =3D 0;
if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT) {
mdb_tassert(txn, mx !=3D NULL);
mc->mc_xcursor =3D mx;
mdb_xcursor_init0(mc);
} else {
mc->mc_xcursor =3D NULL;
}
if (*mc->mc_dbflag & DB_STALE) { <-------- false *mc->mc_db= flag =3D 27, DB_STALE =3D 0x02 /**< Named-DB record is old= er than txnID */
mdb_page_search(mc, NULL, MDB_PS_ROOTONLY);
}
}
From this we know that when mdb_cursor_put() is called, the following value=
s remain assigned:
mc->mc_snum =3D 0; <--------
mc->mc_top =3D 0; <--------
mc->mc_pg[0] =3D 0; <--------
and its noted these two values still have their initial values at the time = of the segmentation fault.
(gdb) fr 0
#0 0x0011b62e in mdb_cursor_put (mc=3D0xffe52d18, key=3D0xffe52e74, data=3D= 0xffe52e6c, flags=3D0) at mdb.c:6688
6688 in mdb.c
(gdb) p mc->mc_top
$1 =3D 0
(gdb) p mc->mc_pg[mc->mc_top]
$19 =3D (MDB_page *) 0x0
Let us consider how the path taken through mdb_cursor_put() could account f= or these null variable values which result in a segmentation fault.
Frame #0
#0 0x0011b62e in mdb_cursor_put (mc=3D0xffe52d18, key=3D0xffe52e74, data= =3D0xffe52e6c, flags=3D0) at mdb.c:6688 <-------- flags =3D 0
env =3D 0x80ce9b0
leaf =3D <value optimized out>
fp =3D <value optimized out>
mp =3D 0x38
sub_root =3D 0x0
fp_flags =3D <value optimized out>
xdata =3D {mv_size =3D 3838880, mv_data =3D 0xdc1cf09a}
rdata =3D 0xffe52e6c
dkey =3D {mv_size =3D 0, mv_data =3D 0x3a93cc}
olddata =3D {mv_size =3D 22, mv_data =3D 0x36c820}
dummy =3D {md_pad =3D 22, md_flags =3D 11128, md_depth =3D 65509, m= d_branch_pages =3D 16, md_leaf_pages =3D 1507329, md_overflow_pages =3D 0, = md_entries =3D 3838928, md_root =3D 3833844}
do_sub =3D 0
insert_key =3D -30798 <-------- #define MDB_NOTFOUND (-307= 98)
insert_data =3D -30798 <-------- #define MDB_NOTFOUND (-3079= 8)
mcount =3D 0
dcount =3D 0
nospill =3D 0 <--------
nsize =3D <value optimized out>
rc =3D 0
rc2 =3D <value optimized out>
nflags =3D 0 <--------
__func__ =3D "mdb_cursor_put"
We know that mc->mc_top and mc->mc_pg[0] were initialized to 0 in mdb_curso= r_init(). As my annotations of the source code below suggest, careful analy= sis reveals that the paths actually taken through mdb_cursor_put() do not m= odify these assignments.
Excerpted Source Code For mdb_cursor_put() From mdb.c
int
mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
unsigned int flags)
{
MDB_env *env;
MDB_node *leaf =3D NULL;
MDB_page *fp, *mp, *sub_root =3D NULL;
uint16_t fp_flags;
MDB_val xdata, *rdata, dkey, o= lddata;
MDB_db dummy;
int do_sub =3D 0, insert_key, insert_data;
unsigned int mcount =3D 0, dcount =3D 0, nospill;
size_t nsize;
int rc, rc2;
unsigned int nflags;
DKBUF;
if (mc =3D=3D NULL || key =3D=3D NULL)
return EINVAL;
env =3D mc->mc_txn->mt_env;
/* Check this first so counter will always be zero on any
* early failures.
*/
if (flags & MDB_MULTIPLE) {
dcount =3D data[1].mv_size;
data[1].mv_size =3D 0;
if (!F_ISSET(mc->mc_db->md_flags, MDB_DUPFI= XED))
return MDB_INCOMPATIBLE;
}
nospill =3D flags & MDB_NOSPILL;
flags &=3D ~MDB_NOSPILL;
if (mc->mc_txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED)= )
return (mc->mc_txn->mt_flags & MDB_TXN_RDON= LY) ? EACCES : MDB_BAD_TXN;
if (key->mv_size-1 >=3D ENV_MAXKEY(env))
return MDB_BAD_VALSIZE;
#if SIZE_MAX > MAXDATASIZE
if (data->mv_size > ((mc->mc_db->md_flags & MDB_DUPSORT) ? = ENV_MAXKEY(env) : MAXDATASIZE))
return MDB_BAD_VALSIZE;
#else
if ((mc->mc_db->md_flags & MDB_DUPSORT) && data->mv_size > = ENV_MAXKEY(env))
return MDB_BAD_VALSIZE;
#endif
DPRINTF(("=3D=3D> put db %d key [%s], size %"Z"u, data size= %"Z"u",
DDBI(mc), DKEY(key), key ? key->mv_size : 0= , data->mv_size));
dkey.mv_size =3D 0;
if (flags =3D=3D MDB_CURRENT) { <-------- false flags =3D 0
if (!(mc->mc_flags & C_INITIALIZED))
return EINVAL;
rc =3D MDB_SUCCESS;
} else if (mc->mc_db->md_root =3D=3D P_INVALID) { <--------= false, mc->mc_db->md_root =3D 68
/* new database, cursor has nothing to poin= t to */
mc->mc_snum =3D 0;
mc->mc_top =3D 0;
mc->mc_flags &=3D ~C_INITIALIZED;
rc =3D MDB_NO_ROOT;
} else { <-------- executed
int exact =3D 0;
MDB_val d2;
if (flags & MDB_APPEND) { <-------- false f= lags =3D 0
MDB_val k2;
rc =3D mdb_cursor_last(mc, = &k2, &d2);
if (rc =3D=3D 0) {
rc =3D mc->= mc_dbx->md_cmp(key, &k2);
if (rc > 0)= {
= rc =3D MDB_NOTFOUND;
= mc->mc_ki[mc->mc_top]++;
} else {
= /* new key is <=3D last key */
= rc =3D MDB_KEYEXIST;
}
}
} else {<-------- executed
rc =3D mdb_cursor_set(mc, k= ey, &d2, MDB_SET, &exact); <-------- returns -30798 which is MDB_NOTFOUND
}<-------- executed
if ((flags & MDB_NOOVERWRITE) && rc =3D=3D = 0) { <-------- false flags =3D 0
DPRINTF(("duplicate key [%s= ]", DKEY(key)));
*data =3D d2;
return MDB_KEYEXIST;
}
if (rc && rc !=3D MDB_NOTFOUND) <-------- f= alse rc =3D MDB_NOTFOUND
return rc;
}<-------- executed
if (mc->mc_flags & C_DEL)
mc->mc_flags ^=3D C_DEL;
/* Cursor is positioned, check for room in the dirty list *= /
if (!nospill) { <-------- true
if (flags & MDB_MULTIPLE) {
rdata =3D &xdata;
xdata.mv_size =3D data->mv_= size * dcount;
} else {
rdata =3D data; <-------- e= xecuted
}
if ((rc2 =3D mdb_page_spill(mc, key, rdata)= )) <-------- returned 0 or would have returned
return rc2;
}<-------- executed
if (rc =3D=3D MDB_NO_ROOT) { <-------- false
MDB_page *np;
/* new database, write a root leaf page */
DPUTS("allocating new root leaf page");
if ((rc2 =3D mdb_page_new(mc, P_LEAF, 1, &n= p))) {
return rc2;
}
mdb_cursor_push(mc, np);
mc->mc_db->md_root =3D np->mp_pgno;
mc->mc_db->md_depth++;
*mc->mc_dbflag |=3D DB_DIRTY;
if ((mc->mc_db->md_flags & (MDB_DUPSORT|MDB= _DUPFIXED))
=3D=3D MDB_DUPFIXED)
np->mp_flags |=3D P_LEAF2;
mc->mc_flags |=3D C_INITIALIZED;
} else {
/* make sure all cursor pages are writable = */
rc2 =3D mdb_cursor_touch(mc); <-------- is = this called and returns 0 because it does not return
if (rc2)
return rc2;
} <-------- executed
insert_key =3D insert_data =3D rc; <-------- rc =3D -30798 = or MDB_NOTFOUND!
if (insert_key) { <-------- true
/* The key does not exist */
DPRINTF(("inserting key at index %i", mc->m= c_ki[mc->mc_top]));
if ((mc->mc_db->md_flags & MDB_DUPSORT) &&
LEAFSIZE(key, data) > env->= me_nodemax) <-------- false since mc->mc_db->md_flags =3D 0
{
/* Too big for a node, inse= rt in sub-DB. Set up an empty
* "old sub-page" for prep_s= ubDB to expand to a full page.
*/
fp_flags =3D P_LEAF|P_DIRTY= ;
fp =3D env->me_pbuf;
fp->mp_pad =3D data->mv_siz= e; /* used if MDB_DUPFIXED */
fp->mp_lower =3D fp->mp_upp= er =3D (PAGEHDRSZ-PAGEBASE);
olddata.mv_size =3D PAGEHDR= SZ;
goto prep_subDB;
} <-------- this was not executed, and the = very long external else contingency below should be skipped!
} else {
/* there's only a key anyway, so this is a = no-op */
if (IS_LEAF2(mc->mc_pg[mc->mc_top])) {
char *ptr;
unsigned int ksize =3D mc->= mc_db->md_pad;
if (key->mv_size !=3D ksize= )
return MDB_= BAD_VALSIZE;
ptr =3D LEAF2KEY(mc->mc_pg[= mc->mc_top], mc->mc_ki[mc->mc_top], ksize);
memcpy(ptr, key->mv_data, k= size);
fix_parent:
/* if overwriting slot 0 of= leaf, need to
* update branch key if ther= e is a parent page
*/
if (mc->mc_top && !mc->mc_k= i[mc->mc_top]) {
unsigned sh= ort dtop =3D 1;
mc->mc_top-= -;
/* slot 0 i= s always an empty key, find real slot */
while (mc->= mc_top && !mc->mc_ki[mc->mc_top]) {
= mc->mc_top--;
= dtop++;
}
if (mc->mc_= ki[mc->mc_top])
= rc2 =3D mdb_update_key(mc, key);
else
= rc2 =3D MDB_SUCCESS;
mc->mc_top = +=3D dtop;
if (rc2)
= return rc2;
}
return MDB_SUCCESS;
}
more:
leaf =3D NODEPTR(mc->mc_pg[mc->mc_top], mc-=
mc_ki[mc->mc_top]);
olddata.mv_size =3D NODEDSZ(leaf);
olddata.mv_data =3D NODEDATA(leaf);
/* DB has dups? */
if (F_ISSET(mc->mc_db->md_flags, MDB_DUPSOR= T)) {
/* Prepare (sub-)page/sub-D= B to accept the new item,
* if needed. fp: old sub-p= age or a header faking
* it. mp: new (sub-)page. = offset: growth in page
* size. xdata: node data w= ith new page or DB.
*/
unsigned i, off= set =3D 0;
mp =3D fp =3D xdata.mv_data= =3D env->me_pbuf;
mp->mp_pgno =3D mc->mc_pg[m= c->mc_top]->mp_pgno;
/* Was a single item before= , must convert now */
if (!F_ISSET(leaf->mn_flags= , F_DUPDATA)) {
MDB_cmp_fun= c *dcmp;
/* Just ove= rwrite the current item */
if (flags = =3D=3D MDB_CURRENT)
= goto current;
dcmp =3D mc= ->mc_dbx->md_dcmp;
#if UINT_MAX < SIZE_MAX
if (dcmp = =3D=3D mdb_cmp_int && olddata.mv_size =3D=3D sizeof(size_t))
= dcmp =3D mdb_cmp_clong;
#endif
/* does dat= a match? */
if (!dcmp(d= ata, &olddata)) {
= if (flags & (MDB_NODUPDATA|MDB_APPENDDUP))
= return MDB_KEYEXIST;
= /* overwrite it */
= goto current;
}
/* Back up = original data item */
dkey.mv_siz= e =3D olddata.mv_size;
dkey.mv_dat= a =3D memcpy(fp+1, olddata.mv_data, olddata.mv_size);
/* Make sub= -page header for the dup items, with dummy body */
fp->mp_flag= s =3D P_LEAF|P_DIRTY|P_SUBP;
fp->mp_lowe= r =3D (PAGEHDRSZ-PAGEBASE);
xdata.mv_si= ze =3D PAGEHDRSZ + dkey.mv_size + data->mv_size;
if (mc->mc_= db->md_flags & MDB_DUPFIXED) {
= fp->mp_flags |=3D P_LEAF2;
= fp->mp_pad =3D data->mv_size;
= xdata.mv_size +=3D 2 * data->mv_size; /* leave space for 2 more *= /
} else {
= xdata.mv_size +=3D 2 * (sizeof(indx_t) + NODESIZE) +
= (dkey.mv_size & 1) + (data->mv_size & 1);
}
fp->mp_uppe= r =3D xdata.mv_size - PAGEBASE;
olddata.mv_= size =3D xdata.mv_size; /* pretend olddata is fp */
} else if (leaf->mn_flags &= F_SUBDATA) {
/* Data is = on sub-DB, just store it */
flags |=3D = F_DUPDATA|F_SUBDATA;
goto put_su= b;
} else {
/* Data is = on sub-page */
fp =3D oldd= ata.mv_data;
switch (fla= gs) {
default:
= if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
= offset =3D EVEN(NODESIZE + sizeof(indx_t) +
= data->mv_size);
= break;
= }
= offset =3D fp->mp_pad;
= if (SIZELEFT(fp) < offset) {
= offset *=3D 4; /* space for 4 more */
= break;
= }
= /* FALLTHRU: Big enough MDB_DUPFIXED sub-page */
case MDB_CU= RRENT:
= fp->mp_flags |=3D P_DIRTY;
= COPY_PGNO(fp->mp_pgno, mp->mp_pgno);
= mc->mc_xcursor->mx_cursor.mc_pg[0] =3D fp;
= flags |=3D F_DUPDATA;
= goto put_sub;
}
xdata.mv_si= ze =3D olddata.mv_size + offset;
}
fp_flags =3D fp->mp_flags;
if (NODESIZE + NODEKSZ(leaf= ) + xdata.mv_size > env->me_nodemax) {
= /* Too big for a sub-page, convert to sub-DB */
= fp_flags &=3D ~P_SUBP;
prep_subDB:
= if (mc->mc_db->md_flags & MDB_DUPFIXED) {
= fp_flags |=3D P_LEAF2;
= dummy.md_pad =3D fp->mp_pad;
= dummy.md_flags =3D MDB_DUPFIXED;
= if (mc->mc_db->md_flags & MDB_INTEGERDUP)
= dummy.md_flags |=3D MDB_INTEGERKEY;
= } else {
= dummy.md_pad =3D 0;
= dummy.md_flags =3D 0;
= }
= dummy.md_depth =3D 1;
= dummy.md_branch_pages =3D 0;
= dummy.md_leaf_pages =3D 1;
= dummy.md_overflow_pages =3D 0;
= dummy.md_entries =3D NUMKEYS(fp);
= xdata.mv_size =3D sizeof(MDB_db);
= xdata.mv_data =3D &dummy;
= if ((rc =3D mdb_page_alloc(mc, 1, &mp)))
= return rc;
= offset =3D env->me_psize - olddata.mv_size;
= flags |=3D F_DUPDATA|F_SUBDATA;
= dummy.md_root =3D mp->mp_pgno;
= sub_root =3D mp;
}
if (mp !=3D fp) {
mp->mp_flag= s =3D fp_flags | P_DIRTY;
mp->mp_pad = =3D fp->mp_pad;
mp->mp_lowe= r =3D fp->mp_lower;
mp->mp_uppe= r =3D fp->mp_upper + offset;
if (fp_flag= s & P_LEAF2) {
= memcpy(METADATA(mp), METADATA(fp), NUMKEYS(fp) * fp->mp_pad);
} else {
= memcpy((char *)mp + mp->mp_upper + PAGEBASE, (char *)fp + fp->mp_upper= + PAGEBASE,
= olddata.mv_size - fp->mp_upper - PAGEBASE);
= for (i=3D0; i<NUMKEYS(fp); i++)
= mp->mp_ptrs[i] =3D fp->mp_ptrs[i] + offset;
}
}
rdata =3D &xdata;
flags |=3D F_DUPDATA;
do_sub =3D 1;
if (!insert_key)
mdb_node_de= l(mc, 0);
goto new_sub;
}
current:
/* LMDB passes F_SUBDATA in 'flags' to writ= e a DB record */
if ((leaf->mn_flags ^ flags) & F_SUBDATA)
return MDB_INCOMPATIBLE;
/* overflow page overwrites need special ha= ndling */
if (F_ISSET(leaf->mn_flags, F_BIGDATA)) { <= -------- is this taken?
MDB_page *omp;
pgno_t pg;
int level, ovpages, dpages = =3D OVPAGES(data->mv_size, env->me_psize);
memcpy(&pg, olddata.mv_data= , sizeof(pg));
if ((rc2 =3D mdb_page_get(m= c->mc_txn, pg, &omp, &level)) !=3D 0)
return rc2;
ovpages =3D omp->mp_pages;
/* Is the ov page large eno= ugh? */
if (ovpages >=3D dpages) {
if (!(omp->mp_flags & P_D= IRTY) &&
(level ||= (env->me_flags & MDB_WRITEMAP)))
{
rc =3D mdb_= page_unspill(mc->mc_txn, omp, &omp); <-------- is this taken?
if (rc)
= return rc;
level =3D 0= ; /* dirty in this txn or clean */
}
/* Is it dirty? */
if (omp->mp_flags & P_DIR= TY) {
/* yes, ove= rwrite it. Note in this case we don't
* bother to= try shrinking the page if the new data
* is smalle= r than the overflow threshold.
*/
if (level >= 1) {
= /* It is writable only in a parent txn */
= size_t sz =3D (size_t) env->me_psize * ovpages, off;
= MDB_page *np =3D mdb_page_malloc(mc->mc_txn, ovpages);
= MDB_ID2 id2;
= if (!np)
= return ENOMEM;
= id2.mid =3D pg;
= id2.mptr =3D np;
= /* Note - this page is already counted in parent's dirty_room */
= rc2 =3D mdb_mid2l_insert(mc->mc_txn->mt_u.dirty_list, &id2);
= mdb_cassert(mc, rc2 =3D=3D 0);
= if (!(flags & MDB_RESERVE)) {
= /* Copy end of page, adjusting alignment so
= * compiler may copy words instead of bytes.
= */
= off =3D (PAGEHDRSZ + data->mv_size) & -sizeof(size_t);
= memcpy((size_t *)((char *)np + off),
= (size_t *)((char *)omp + off), sz - of= f);
= sz =3D PAGEHDRSZ;
= }
= memcpy(np, omp, sz); /* Copy beginning of page */
= omp =3D np;
}
SETDSZ(leaf= , data->mv_size);
if (F_ISSET= (flags, MDB_RESERVE))
= data->mv_data =3D METADATA(omp);
else
= memcpy(METADATA(omp), data->mv_data, data->mv_size);
return MDB_= SUCCESS;
}
}
if ((rc2 =3D mdb_ovpage_fre= e(mc, omp)) !=3D MDB_SUCCESS)
return rc2;
} else if (data->mv_size =3D=3D olddata.mv_= size) {
/* same size, just replace = it. Note that we could
* also reuse this node if t= he new data is smaller,
* but instead we opt to shr= ink the node in that case.
*/
if (F_ISSET(flags, MDB_RESE= RVE))
data->mv_da= ta =3D olddata.mv_data;
else if (!(mc->mc_flags & C= _SUB))
memcpy(oldd= ata.mv_data, data->mv_data, data->mv_size);
else {
memcpy(NODE= KEY(leaf), key->mv_data, key->mv_size);
goto fix_pa= rent;
}
return MDB_SUCCESS;
}
mdb_node_del(mc, 0);
} <-------- This entire else contingency was likely skipped= !!
rdata =3D data;
new_sub:
nflags =3D flags & NODE_ADD_FLAGS;
nsize =3D IS_LEAF2(mc->mc_pg[mc->mc_top]) ? key->mv_size : = mdb_leaf_size(env, key, rdata); <-------- SEGV
...
This may be an identifiable bug in mdb_cursor_put() as It does not safely h= andle the case when the noted call to mdb_cursor_set() returns MDB_NOTFOUND= (-30798)!
It explicitly fails to preemptively exit by returning an error in this case= .
The value of -30798 is in turn assigned to insert_key, which is therefore n= on-null in the condition of the subsequent if statement.
insert_key =3D insert_data =3D rc; <-------- insert_key =3D= -30798 or MDB_NOTFOUND!
if (insert_key) { <-------- true
/* The key does not exist */
DPRINTF(("inserting key at index %i", mc->m= c_ki[mc->mc_top]));
if ((mc->mc_db->md_flags & MDB_DUPSORT) &&
LEAFSIZE(key, data) > env->= me_nodemax) <-------- false since mc->mc_db->md_flags =3D 0
{
/* Too big for a node, inse= rt in sub-DB. Set up an empty
* "old sub-page" for prep_s= ubDB to expand to a full page.
*/
fp_flags =3D P_LEAF|P_DIRTY= ;
fp =3D env->me_pbuf;
fp->mp_pad =3D data->mv_siz= e; /* used if MDB_DUPFIXED */
fp->mp_lower =3D fp->mp_upp= er =3D (PAGEHDRSZ-PAGEBASE);
olddata.mv_size =3D PAGEHDR= SZ;
goto prep_subDB;
} <-------- this was not executed, and the = very long else contingency below is skipped!
} else {
Since mc->mc_db->md_flags =3D 0, the contingency in the embedded if stateme= nt fails.
The segmentation fault occurs due to the call of IS_LEAF2 on the null point= er mc->mc_pg[0].
rdata =3D data;
new_sub:
nflags =3D flags & NODE_ADD_FLAGS;
nsize =3D IS_LEAF2(mc->mc_pg[mc->mc_top]) ? key->mv_size : = mdb_leaf_size(env, key, rdata); <-------- SEGV
Regards, Robins.
--_000_MN2PR06MB55017A7261FA27380778753BAFEA0MN2PR06MB5501namp_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable
<html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-micr= osoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:word" = xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xmlns=3D"http:= //www.w3.org/TR/REC-html40"> <head> <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dus-ascii"=
<meta name=3D"Generator" content=3D"Microsoft Word 15 (filtered medium)"> <style><!-- /* Font Definitions */ @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4;} @font-face {font-family:Consolas; panose-1:2 11 6 9 2 2 4 3 2 4;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {margin:0in; margin-bottom:.0001pt; font-size:11.0pt; font-family:"Calibri",sans-serif;} a:link, span.MsoHyperlink {mso-style-priority:99; color:#0563C1; text-decoration:underline;} a:visited, span.MsoHyperlinkFollowed {mso-style-priority:99; color:#954F72; text-decoration:underline;} p.MsoPlainText, li.MsoPlainText, div.MsoPlainText {mso-style-priority:99; mso-style-link:"Plain Text Char"; margin:0in; margin-bottom:.0001pt; font-size:11.0pt; font-family:"Calibri",sans-serif;} span.EmailStyle17 {mso-style-type:personal-compose; font-family:"Calibri",sans-serif; color:windowtext;} span.PlainTextChar {mso-style-name:"Plain Text Char"; mso-style-priority:99; mso-style-link:"Plain Text"; font-family:"Calibri",sans-serif;} .MsoChpDefault {mso-style-type:export-only; font-family:"Calibri",sans-serif;} @page WordSection1 {size:8.5in 11.0in; margin:1.0in 1.0in 1.0in 1.0in;} div.WordSection1 {page:WordSection1;} --></style><!--[if gte mso 9]><xml> <o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" /> </xml><![endif]--><!--[if gte mso 9]><xml> <o:shapelayout v:ext=3D"edit"> <o:idmap v:ext=3D"edit" data=3D"1" /> </o:shapelayout></xml><![endif]--> </head> <body lang=3D"EN-US" link=3D"#0563C1" vlink=3D"#954F72"> <div class=3D"WordSection1"> <p class=3D"MsoPlainText"><repost since the previous message came as 64 = encoded, apologies><o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">Hello Howard,<o:p></o:p></p> <p class=3D"MsoPlainText">we are not able to reproduce the issue consistent= ly so test code is not available at this time, and I do believe this issue = will be present in the latest code as well since Myk also reported the same= .. Attaching analysis from our side, hope it helps.<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">The call stack what we have seen is,<o:p></o:p></= p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> #0 0x0011b62e in mdb_cursor_pu= t (mc=3D0xffe52d18, key=3D0xffe52e74, data=3D0xffe52e6c, flags=3D0) at mdb.= c:6688<o:p></o:p></p> <p class=3D"MsoPlainText"> #1 0x0011c8ec in mdb_put (txn= =3D0xdc13f008, dbi=3D2, key=3D0xffe52e74, data=3D0xffe52e6c, flags=3D0) at = mdb.c:8771<o:p></o:p></p> <p class=3D"MsoPlainText"> #2 0x00b792b8 in LMDB::LMDBCon= text::createSession (this=3D0x80ca418, sid=3D0x8297be4 "sidebf3708f0fd= 9fcb8e062529da47adf51402dfc4600000000+") at lmdbint.cc:460<o:p></o= :p></p> <p class=3D"MsoPlainText"> #3 0x08053564 in updateLMDB (r= equest=3D..., forward=3D@0xffe5315f) at sessionserver.cc:1075<o:p></o:p></p=
<p class=3D"MsoPlainText"> #4 processRequestWithoutRespon= se (request=3D..., forward=3D@0xffe5315f) at sessionserver.cc:1160<o:p></o:= p></p> <p class=3D"MsoPlainText"> #5 0x08056a80 in processReques= t (this=3D0x80b2ac0, fd=3D33) at sessionserver.cc:1189<o:p></o:p></p> <p class=3D"MsoPlainText"> #6 readFromSock (this=3D0x80b2= ac0, fd=3D33) at sessionserver.cc:1342<o:p></o:p></p> <p class=3D"MsoPlainText"> #7 SockHandler::ioReady (this= =3D0x80b2ac0, fd=3D33) at sessionserver.cc:1455<o:p></o:p></p> <p class=3D"MsoPlainText"> #8 0x00ba2592 in runCoreDispat= cher (default_t=3D<value optimized out>, flags=3D-1) at fds.cc:889<o:= p></o:p></p> <p class=3D"MsoPlainText"> #9 0x00ba2ff7 in DSEvntFds::ru= nDispatcher () at fds.cc:945<o:p></o:p></p> <p class=3D"MsoPlainText"> #10 0x080559c6 in main () at s= essionserver.cc:1739<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">Here it is helpful to examine frames #0 and #1 in= detail in relation to the relevant source code /libraries/liblmdb/mdb.c.<o= :p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">Frame #1<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">#1 0x0011c8ec in mdb_put (txn=3D0xdc13f008,= dbi=3D2, key=3D0xffe52e74, data=3D0xffe52e6c, flags=3D0) at mdb.c:8771<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> mc =3D= {mc_next =3D 0x0, mc_backup =3D 0x0, mc_xcursor =3D 0x0, mc_txn =3D 0xdc13= f008, mc_dbi =3D 2, mc_db =3D 0xdc13f088, mc_dbx =3D 0xe1215038, mc_dbflag = =3D 0xdc1cf09a "\033", '\032' <repeats 51 times>, mc_snum = =3D 0, mc_top =3D 0, mc_flags =3D 0, mc_pg =3D {0x0, 0x80b2ac0, 0xffe52d68, 0x28afce, 0xdc13f008, 0x80ce9b0, 0x= ffe52dc8, 0x4c5ff4, 0x2b, 0x80b2ac0, 0xffe52d98, 0x49209a, 0x2b, 0x4c5ff4, = 0x2121cb, 0x21576c, 0x8297d34, 0x3497af, 0x21576c, 0x21316a, 0x8297d34, 0x8= 0ac7b0, 0x1e, 0x46eed6, 0x2b, 0x0, 0x80ce9b0, 0x4c5ff4, 0x80ac7b0, 0x8297d34, 0xffe52df8, 0x46fb96}, mc_ki = =3D {0, 2089, 51120, 2058, 30, 0, 16796, 17, 11760, 65509, 3, 0, 32040, 208= 9, 30, 0, 0, 0, 0, 0, 3, 0, 24564, 76, 51120, 2058, 10944, 2059, 11800, 655= 09, 64758, 70}} <--------<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; <o:p></o:p></p> <p class=3D"MsoPlainText"> mx =3D= {mx_cursor =3D {mc_next =3D 0x38, mc_backup =3D 0x3, mc_xcursor =3D 0x0, m= c_txn =3D 0x0, mc_dbi =3D 0, mc_db =3D 0x28, mc_dbx =3D 0x0, mc_dbflag =3D = 0x0, mc_snum =3D 3, mc_top =3D 0, mc_flags =3D 17, mc_pg =3D {0x3a93d8, 0x1= 0, 0x0, 0x18, 0x3a93a0, 0x0, 0x3a93d0, 0x289abe, 0x3a93a0, 0xffe52d3f, 0xffe52c68, 0x28afce, 0xffe= 52dbc, 0xffe52db4, 0x3, 0x4c5ff4, 0x11, 0x36c99b, 0x6e, 0x77, 0x7c, 0x5b, 0= x38, 0x289abe, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x3, 0x10}, mc_ki =3D {37848,= 58, 51611, 54, 110, 0, 119, 0, 124, 0, 91, 0, 58, 0, 39614, 40, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 2, 0, 18, 0, 1= 36, 0}}, mx_db =3D {md_pad =3D 3838936, md_flags =3D 51611, md_depth =3D 54= , md_branch_pages =3D 110, md_leaf_pages =3D 119, md_overflow_pages =3D 124= , md_entries =3D 91, md_root =3D 56}, mx_dbx =3D {md_name =3D {mv_size =3D 6, mv_data =3D 0x0}, md_cmp =3D 0, md_dcmp =3D 0, md_rel = =3D 0x40, md_relctx =3D 0x0}, mx_dbflag =3D 0 '\000'}<o:p></o:p></p> <p class=3D"MsoPlainText"> rc =3D= 0 <o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">And source code for mdb_put() is from mdb.c<o:p><= /o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">int<o:p></o:p></p> <p class=3D"MsoPlainText">mdb_put(MDB_txn *txn, MDB_dbi dbi,<o:p></o:p></p> <p class=3D"MsoPlainText"> MDB_val *key, MDB_val *data, u= nsigned int flags) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; MDB_cursor mc;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; MDB_xcursor mx;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; int rc;<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (!key || !data || !TXN_DBI_EXI= ST(txn, dbi, DB_USRVALID))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; return EINVA= L;<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (flags & ~(MDB_NOOVERWRITE= |MDB_NODUPDATA|MDB_RESERVE|MDB_APPEND|MDB_APPENDDUP))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; return EINVA= L;<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (txn->mt_flags & (MDB_T= XN_RDONLY|MDB_TXN_BLOCKED))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; return (txn-= >mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mdb_cursor_init(&mc, txn, dbi= , &mx); <-------- see source code below<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mc.mc_next =3D txn->mt_cursors= [dbi];<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; txn->mt_cursors[dbi] =3D &= mc;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; rc =3D mdb_cursor_put(&mc, ke= y, data, flags); <-------- see Frame #0<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; txn->mt_cursors[dbi] =3D mc.mc= _next;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; return rc;<o:p></o:p></p> <p class=3D"MsoPlainText">}<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">Source Code For mdb_cursor_init() From mdb.c<o:p>= </o:p></p> <p class=3D"MsoPlainText">/** Initialize a cursor for a given transaction a= nd database. */ static void mdb_cursor_init(MDB_cursor *mc, MDB_txn *txn, M= DB_dbi dbi, MDB_xcursor *mx) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_next =3D NULL;<o:p></o:= p></p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_backup =3D NULL;<o:p></= o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_dbi =3D dbi;<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_txn =3D txn;<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_db =3D &txn->mt_= dbs[dbi];<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_dbx =3D &txn->mt= _dbxs[dbi];<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_dbflag =3D &txn->= ;mt_dbflags[dbi];<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_snum =3D 0; <-------= - <o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_top =3D 0; <--------= <o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_pg[0] =3D 0; <------= -- <o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_ki[0] =3D 0;<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_flags =3D 0;<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; if (txn->mt_dbs[dbi].md_flags = & MDB_DUPSORT) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mdb_tassert(= txn, mx !=3D NULL);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mc->mc_xc= ursor =3D mx;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mdb_xcursor_= init0(mc);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; } else {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mc->mc_xc= ursor =3D NULL;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (*mc->mc_dbflag & DB_ST= ALE) { <-------- false *mc->mc_dbflag =3D 27, DB_STALE =3D 0x02 = &nb= sp; /**< Named-DB record is older than txnID */<o:p></= o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mdb_page_sea= rch(mc, NULL, MDB_PS_ROOTONLY); <o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; }<o:p></o:p></p> <p class=3D"MsoPlainText">}<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">From this we know that when mdb_cursor_put() is c= alled, the following values remain assigned:<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_snum =3D 0; <--------<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_top =3D 0; <--------= <o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; mc->mc_pg[0] =3D 0; <------= -- <o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">and its noted these two values still have their i= nitial values at the time of the segmentation fault.<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">(gdb) fr 0<o:p></o:p></p> <p class=3D"MsoPlainText">#0 0x0011b62e in mdb_cursor_put (mc=3D0xffe52d18,= key=3D0xffe52e74, data=3D0xffe52e6c, flags=3D0) at mdb.c:6688<o:p></o:p></= p> <p class=3D"MsoPlainText">6688 in mdb.c<o:p></o:p></p> <p class=3D"MsoPlainText">(gdb) p mc->mc_top<o:p></o:p></p> <p class=3D"MsoPlainText">$1 =3D 0<o:p></o:p></p> <p class=3D"MsoPlainText">(gdb) p mc->mc_pg[mc->mc_top]<o:p></o:p></p=
<p class=3D"MsoPlainText">$19 =3D (MDB_page *) 0x0<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">Let us consider how the path taken through mdb_cu= rsor_put() could account for these null variable values which result in a s= egmentation fault.<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">Frame #0<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">#0 0x0011b62e in mdb_cursor_put (mc=3D0xffe= 52d18, key=3D0xffe52e74, data=3D0xffe52e6c, flags=3D0) at mdb.c:6688 <--= ------ flags =3D 0<o:p></o:p></p> <p class=3D"MsoPlainText"> env = =3D 0x80ce9b0<o:p></o:p></p> <p class=3D"MsoPlainText"> leaf = =3D <value optimized out><o:p></o:p></p> <p class=3D"MsoPlainText"> fp =3D= <value optimized out><o:p></o:p></p> <p class=3D"MsoPlainText"> mp =3D= 0x38<o:p></o:p></p> <p class=3D"MsoPlainText"> sub_ro= ot =3D 0x0 <o:p></o:p></p> <p class=3D"MsoPlainText"> f= p_flags =3D <value optimized out><o:p></o:p></p> <p class=3D"MsoPlainText"> xdata = =3D {mv_size =3D 3838880, mv_data =3D 0xdc1cf09a}<o:p></o:p></p> <p class=3D"MsoPlainText"> rdata = =3D 0xffe52e6c<o:p></o:p></p> <p class=3D"MsoPlainText"> dkey = =3D {mv_size =3D 0, mv_data =3D 0x3a93cc}<o:p></o:p></p> <p class=3D"MsoPlainText"> olddat= a =3D {mv_size =3D 22, mv_data =3D 0x36c820}<o:p></o:p></p> <p class=3D"MsoPlainText"> dummy = =3D {md_pad =3D 22, md_flags =3D 11128, md_depth =3D 65509, md_branch_pages= =3D 16, md_leaf_pages =3D 1507329, md_overflow_pages =3D 0, md_entries =3D= 3838928, md_root =3D 3833844}<o:p></o:p></p> <p class=3D"MsoPlainText"> do_sub= =3D 0<o:p></o:p></p> <p class=3D"MsoPlainText"> insert= _key =3D -30798 <-------- #define MDB_NOTFOUND &n= bsp; (-30798)<o:p></o:p></p> <p class=3D"MsoPlainText"> insert= _data =3D -30798 <-------- #define MDB_NOTFOUND &= nbsp; (-30798)<o:p></o:p></p> <p class=3D"MsoPlainText"> mcount= =3D 0<o:p></o:p></p> <p class=3D"MsoPlainText"> dcount= =3D 0<o:p></o:p></p> <p class=3D"MsoPlainText"> nospil= l =3D 0 <--------<o:p></o:p></p> <p class=3D"MsoPlainText"> nsize = =3D <value optimized out><o:p></o:p></p> <p class=3D"MsoPlainText"> rc =3D= 0 <o:p></o:p></p> <p class=3D"MsoPlainText"> r= c2 =3D <value optimized out><o:p></o:p></p> <p class=3D"MsoPlainText"> nflags= =3D 0 <--------<o:p></o:p></p> <p class=3D"MsoPlainText"> __func= __ =3D "mdb_cursor_put" = <o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">We know that mc->mc_top and mc->mc_pg[0] we= re initialized to 0 in mdb_cursor_init(). As my annotations of the source c= ode below suggest, careful analysis reveals that the paths actually taken t= hrough mdb_cursor_put() do not modify these assignments.<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">Excerpted Source Code For mdb_cursor_put() From m= db.c<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">int<o:p></o:p></p> <p class=3D"MsoPlainText">mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_= val *data,<o:p></o:p></p> <p class=3D"MsoPlainText"> unsigned int flags)<o:p></o:p>= </p> <p class=3D"MsoPlainText">{<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; MDB_env &n= bsp;  = ; *env;<o:p></o= :p></p> <p class=3D"MsoPlainText"> &= nbsp; MDB_node &= nbsp; *leaf =3D NULL;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; MDB_page &= nbsp; *fp, *mp, *sub_root =3D NULL;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; uint16_t &= nbsp; fp_flags;<o:p><= /o:p></p> <p class=3D"MsoPlainText"> &= nbsp; MDB_val &n= bsp;  = ; x= data, *rdata, dkey, olddata;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; MDB_db dummy;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; int do_sub =3D 0, insert_key, ins= ert_data;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; unsigned int mcount =3D 0, dcount= =3D 0, nospill;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; size_t nsize;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; int rc, rc2;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; unsigned int nflags;<o:p></o:p></= p> <p class=3D"MsoPlainText"> &= nbsp; DKBUF;<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (mc =3D=3D NULL || key =3D=3D = NULL)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; return EINVA= L;<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; env =3D mc->mc_txn->mt_env;= <o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; /* Check this first so counter wi= ll always be zero on any<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; * early failures.<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (flags & MDB_MULTIPLE) {<o= :p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; dcount =3D d= ata[1].mv_size;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; data[1].mv_s= ize =3D 0;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if (!F_ISSET= (mc->mc_db->md_flags, MDB_DUPFIXED))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; return MDB_INCOMPATIBLE;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; }<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; nospill =3D flags & MDB_NOSPI= LL;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; flags &=3D ~MDB_NOSPILL;<o:p>= </o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (mc->mc_txn->mt_flags &a= mp; (MDB_TXN_RDONLY|MDB_TXN_BLOCKED))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; return (mc-&= gt;mc_txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;<o:p></= o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (key->mv_size-1 >=3D ENV= _MAXKEY(env))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; return MDB_B= AD_VALSIZE;<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">#if SIZE_MAX > MAXDATASIZE<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (data->mv_size > ((mc-&g= t;mc_db->md_flags & MDB_DUPSORT) ? ENV_MAXKEY(env) : MAXDATASIZE))<o= :p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; return MDB_B= AD_VALSIZE;<o:p></o:p></p> <p class=3D"MsoPlainText">#else<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if ((mc->mc_db->md_flags &a= mp; MDB_DUPSORT) && data->mv_size > ENV_MAXKEY(env))<o:p></o:= p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; return MDB_B= AD_VALSIZE;<o:p></o:p></p> <p class=3D"MsoPlainText">#endif<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; DPRINTF(("=3D=3D> put db = %d key [%s], size %"Z"u, data size %"Z"u",<o:p></o= :p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; DDBI(mc), DK= EY(key), key ? key->mv_size : 0, data->mv_size));<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; dkey.mv_size =3D 0;<o:p></o:p></p=
<p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (flags =3D=3D MDB_CURRENT) { &= lt;-------- false flags =3D 0<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if (!(mc->= ;mc_flags & C_INITIALIZED))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; = &nb= sp; return EINVAL;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; rc =3D MDB_S= UCCESS;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; } else if (mc->mc_db->md_ro= ot =3D=3D P_INVALID) { <-------- false, mc->mc_db->md_root =3D 68<= o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; /* new datab= ase, cursor has nothing to point to */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mc->mc_sn= um =3D 0;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mc->mc_to= p =3D 0;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mc->mc_fl= ags &=3D ~C_INITIALIZED;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; rc =3D MDB_N= O_ROOT; <o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; } else { <-------- executed<o:= p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; int exact = =3D 0;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; MDB_val d2;<= o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if (flags &a= mp; MDB_APPEND) { <-------- false flags =3D 0<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; MDB_val k2;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; rc =3D mdb_cursor_last(mc, &k2, &d2);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (rc =3D=3D 0) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; rc =3D mc->mc_dbx->md_cmp(key, &k2)= ;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; if (rc > 0) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; rc =3D MDB_NOTFOUND;<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; mc->mc_ki[mc->mc_t= op]++;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; } else {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* new key is <=3D la= st key */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; rc =3D MDB_KEYEXIST;<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; } else {<= -------- executed<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; rc =3D mdb_cursor_set(mc, key, &d2, MDB_SET, &exact); <= -------- returns -30798 which is MDB_NOTFOUND<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; }<-------= - executed<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if ((flags &= amp; MDB_NOOVERWRITE) && rc =3D=3D 0) { <-------- false flags = =3D 0<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; DPRINTF(("duplicate key [%s]", DKEY(key)));<o:p></o:p></= p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; *data =3D d2;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; return MDB_KEYEXIST;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; }<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if (rc &= & rc !=3D MDB_NOTFOUND) <-------- false rc =3D MDB_NOTFOUND<o:p></o:= p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; return rc;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; }<-------- executed<o:p></o:p>= </p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (mc->mc_flags & C_DEL)<= o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mc->mc_fl= ags ^=3D C_DEL;<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; /* Cursor is positioned, check fo= r room in the dirty list */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (!nospill) { <-------- true= <o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if (flags &a= mp; MDB_MULTIPLE) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; rdata =3D &xdata;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; xdata.mv_size =3D data->mv_size * dcount;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; } else {<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; rdata =3D data; <-------- executed<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; }<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if ((rc2 =3D= mdb_page_spill(mc, key, rdata))) <-------- returned 0 or would have ret= urned<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; return rc2;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; }<-------- executed<o:p></o:p>= </p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (rc =3D=3D MDB_NO_ROOT) { <= -------- false <o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; MDB_page *np= ;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; /* new datab= ase, write a root leaf page */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; DPUTS("= allocating new root leaf page");<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if ((rc2 =3D= mdb_page_new(mc, P_LEAF, 1, &np))) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; return rc2;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; }<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mdb_cursor_p= ush(mc, np);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mc->mc_db= ->md_root =3D np->mp_pgno;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mc->mc_db= ->md_depth++;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; *mc->mc_d= bflag |=3D DB_DIRTY;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if ((mc->= mc_db->md_flags & (MDB_DUPSORT|MDB_DUPFIXED))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; =3D=3D MDB_DUPFIXED)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; np->mp_flags |=3D P_LEAF2;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mc->mc_fl= ags |=3D C_INITIALIZED;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; } else {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; /* make sure= all cursor pages are writable */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; rc2 =3D mdb_= cursor_touch(mc); <-------- is this called and returns 0 because it does= not return<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if (rc2)<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; return rc2;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; } <-------- executed<o:p></o:p=
</p>
<p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; insert_key =3D insert_data =3D rc= ; <-------- rc =3D -30798 or MDB_NOTFOUND!<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (insert_key) { <-------- tr= ue<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; /* The key d= oes not exist */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; DPRINTF((&qu= ot;inserting key at index %i", mc->mc_ki[mc->mc_top]));<o:p></o:= p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if ((mc->= mc_db->md_flags & MDB_DUPSORT) &&<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; LEAFSIZE(key, data) > env->me_nodemax) <-------- false si= nce mc->mc_db->md_flags =3D 0<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; {<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* Too big for a node, insert in sub-DB. Set up an empty<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; * "old sub-page" for prep_subDB to expand to a full page= .<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp_flags =3D P_LEAF|P_DIRTY;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp =3D env->me_pbuf;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp->mp_pad =3D data->mv_size; /* used if MDB_DUPFIXED */<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp->mp_lower =3D fp->mp_upper =3D (PAGEHDRSZ-PAGEBASE);<o:p>= </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; olddata.mv_size =3D PAGEHDRSZ;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; goto prep_subDB;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; } <------= -- this was not executed, and the very long external else contingency below= should be skipped!<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; } else {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; /* there's o= nly a key anyway, so this is a no-op */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if (IS_LEAF2= (mc->mc_pg[mc->mc_top])) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; char *ptr;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; unsigned int ksize =3D mc->mc_db->md_pad;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (key->mv_size !=3D ksize)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; return MDB_BAD_VALSIZE;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; ptr =3D LEAF2KEY(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->= mc_top], ksize);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; memcpy(ptr, key->mv_data, ksize);<o:p></o:p></p> <p class=3D"MsoPlainText">fix_parent:<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* if overwriting slot 0 of leaf, need to<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; * update branch key if there is a parent page<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (mc->mc_top && !mc->mc_ki[mc->mc_top]) {<o:p><= /o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; unsigned short dtop =3D 1;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; mc->mc_top--;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; /* slot 0 is always an empty key, find real s= lot */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; while (mc->mc_top && !mc->mc_ki= [mc->mc_top]) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; mc->mc_top--;<o:p></o= :p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; dtop++;<o:p></o:= p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; if (mc->mc_ki[mc->mc_top])<o:p></o:p></= p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; rc2 =3D mdb_update_key(m= c, key);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; else<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; rc2 =3D MDB_SUCCESS;<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; mc->mc_top +=3D dtop;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; if (rc2)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; return rc2;<o:p></o:p></= p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; return MDB_SUCCESS;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; }<o:p></o:p>= </p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">more:<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; leaf =3D NOD= EPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);<o:p></o:p><= /p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; olddata.mv_s= ize =3D NODEDSZ(leaf);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; olddata.mv_d= ata =3D NODEDATA(leaf);<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; /* DB has du= ps? */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if (F_ISSET(= mc->mc_db->md_flags, MDB_DUPSORT)) { <o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* Prepare (sub-)page/sub-DB to accept the new item,<o:p></o:p></p=
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; * if needed. fp: old sub-page or a header faking<o:p></o:p><= /p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; * it. mp: new (sub-)page. offset: growth in page<o:p><= /o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; * size. xdata: node data with new page or DB.<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; unsigned &nbs= p; i, offset =3D 0;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; mp =3D fp =3D xdata.mv_data =3D env->me_pbuf;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; mp->mp_pgno =3D mc->mc_pg[mc->mc_top]->mp_pgno;<o:p></= o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* Was a single item before, must convert now */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; MDB_cmp_func *dcmp;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; /* Just overwrite the current item */<o:p></o= :p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; if (flags =3D=3D MDB_CURRENT)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; goto current;<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; dcmp =3D mc->mc_dbx->md_dcmp;<o:p></o:p=
</p>
<p class=3D"MsoPlainText">#if UINT_MAX < SIZE_MAX<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; if (dcmp =3D=3D mdb_cmp_int && olddat= a.mv_size =3D=3D sizeof(size_t))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; dcmp =3D mdb_cmp_clong;<= o:p></o:p></p> <p class=3D"MsoPlainText">#endif<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; /* does data match? */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; if (!dcmp(data, &olddata)) {<o:p></o:p></= p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (flags & (MDB_NOD= UPDATA|MDB_APPENDDUP))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; ret= urn MDB_KEYEXIST;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* overwrite it */<o:p><= /o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; goto current;<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; }<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; /* Back up original data item */<o:p></o:p></= p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; dkey.mv_size =3D olddata.mv_size;<o:p></o:p><= /p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; dkey.mv_data =3D memcpy(fp+1, olddata.mv_= data, olddata.mv_size);<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; /* Make sub-page header for the dup items, wi= th dummy body */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; fp->mp_flags =3D P_LEAF|P_DIRTY|P_SUBP;<o:= p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; fp->mp_lower =3D (PAGEHDRSZ-PAGEBASE);<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; xdata.mv_size =3D PAGEHDRSZ + dkey.mv_siz= e + data->mv_size;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; = &nb= sp; = if (mc->mc_db->md_flags & MDB_DUPFIXED) = {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp->mp_flags |=3D P_L= EAF2;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp->mp_pad =3D data-&= gt;mv_size;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; xdata.mv_size +=3D 2= * data->mv_size; /* leave space for 2 mor= e */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; } else {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; xdata.mv_size +=3D 2= * (sizeof(indx_t) + NODESIZE) +<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; (dk= ey.mv_size & 1) + (data->mv_size & 1);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; fp->mp_upper =3D xdata.mv_size - PAGEBASE;= <o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; olddata.mv_size =3D xdata.mv_size; /* pretend= olddata is fp */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; } else if (leaf->mn_flags & F_SUBDATA) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; /* Data is on sub-DB, just store it */<o:p></= o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; flags |=3D F_DUPDATA|F_SUBDATA;<o:p></o:p></p=
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; goto put_sub;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; } else {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; /* Data is on sub-page */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; fp =3D olddata.mv_data;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; switch (flags) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; default:<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (!(mc->mc_db->m= d_flags & MDB_DUPFIXED)) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; off= set =3D EVEN(NODESIZE + sizeof(indx_t) +<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; data->mv_size);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; bre= ak;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; offset =3D fp->mp_pad= ;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (SIZELEFT(fp) < of= fset) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; off= set *=3D 4; /* space for 4 more */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; bre= ak;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* FALLTHRU: Big enough = MDB_DUPFIXED sub-page */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; case MDB_CURRENT:<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp->mp_flags |=3D P_D= IRTY;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; COPY_PGNO(fp->mp_pgno= , mp->mp_pgno);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; mc->mc_xcursor->mx= _cursor.mc_pg[0] =3D fp;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; flags |=3D F_DUPDATA;<o:= p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; goto put_sub;<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; xdata.mv_size =3D olddata.mv_size + offse= t;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp_flags =3D fp->mp_flags;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (NODESIZE + NODEKSZ(leaf) + xdata.mv_size > env->= me_nodemax) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* Too big for a sub-pag= e, convert to sub-DB */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp_flags &=3D ~P_SUB= P;<o:p></o:p></p> <p class=3D"MsoPlainText">prep_subDB:<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (mc->mc_db->md_= flags & MDB_DUPFIXED) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; fp_= flags |=3D P_LEAF2;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; dum= my.md_pad =3D fp->mp_pad;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; dum= my.md_flags =3D MDB_DUPFIXED;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; if = (mc->mc_db->md_flags & MDB_INTEGERDUP)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; dummy.md_flags |=3D MDB_INTEGERKEY;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; } else {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; dum= my.md_pad =3D 0;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; dum= my.md_flags =3D 0;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; dummy.md_depth =3D 1;<o:= p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; dummy.md_branch_pages = =3D 0;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; = &nb= sp; = &nb= sp; dummy.md_leaf_pages =3D 1;<o:= p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; dummy.md_overflow_pages = =3D 0;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; dummy.md_entries =3D NUM= KEYS(fp);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; xdata.mv_size =3D sizeof= (MDB_db);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; xdata.mv_data =3D &d= ummy;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; if ((rc =3D mdb_page_all= oc(mc, 1, &mp)))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; ret= urn rc;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; offset =3D env->me_ps= ize - olddata.mv_size;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; flags |=3D F_DUPDATA|F_S= UBDATA;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; dummy.md_root =3D mp->= ;mp_pgno;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; sub_root =3D mp;<o:p></o= :p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (mp !=3D fp) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; mp->mp_flags =3D fp_flags | P_DIRTY;<o:p><= /o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; mp->mp_pad =3D fp->mp_pad;<= o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; mp->mp_lower =3D fp->mp_lower;<o:p></o:= p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; mp->mp_upper =3D fp->mp_upper + off= set;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; if (fp_flags & P_LEAF2) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; memcpy(METADATA(mp), MET= ADATA(fp), NUMKEYS(fp) * fp->mp_pad);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; } else {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; memcpy((char *)mp + = mp->mp_upper + PAGEBASE, (char *)fp + fp->mp_upper + PAGE= BASE,<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; old= data.mv_size - fp->mp_upper - PAGEBASE);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; for (i=3D0; i<NUMKEYS= (fp); i++)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; mp-= >mp_ptrs[i] =3D fp->mp_ptrs[i] + offset;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; rdata =3D &xdata;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; flags |=3D F_DUPDATA;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; do_sub =3D 1;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (!insert_key)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; mdb_node_del(mc, 0);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; goto new_sub;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; }<o:p></o:p>= </p> <p class=3D"MsoPlainText">current:<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; /* LMDB pass= es F_SUBDATA in 'flags' to write a DB record */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if ((leaf-&g= t;mn_flags ^ flags) & F_SUBDATA)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; return MDB_INCOMPATIBLE;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; /* overflow = page overwrites need special handling */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if (F_ISSET(= leaf->mn_flags, F_BIGDATA)) { <-------- is this taken?<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; MDB_page *omp;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; pgno_t pg;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; int level, ovpages, dpages =3D OVPAGES(data->mv_size, env->m= e_psize);<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; memcpy(&pg, olddata.mv_data, sizeof(pg));<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if ((rc2 =3D mdb_page_get(mc->mc_txn, pg, &omp, &level)= ) !=3D 0)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; return rc2;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; ovpages =3D omp->mp_pages;<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* Is the ov page large enough? */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (ovpages >=3D dpages) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (!(omp->mp_flags & P_DIRTY) &&<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; (level || (env->me_flags & MDB_= WRITEMAP)))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; rc =3D mdb_page_unspill(mc->mc_txn, omp, &= amp;omp); <-------- is this taken?<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; if (rc)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; return rc;<o:p></o:p></p=
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; level =3D 0; &nb= sp; = /* dirty= in this txn or clean */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* Is it dirty? */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (omp->mp_flags & P_DIRTY) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; /* yes, overwrite it. Note in this case we do= n't<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; * bother to try shrinking the page if the new= data<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; * is smaller than the overflow threshold.<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; if (level > 1) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* It is writable only i= n a parent txn */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; size_t sz =3D (size_t) e= nv->me_psize * ovpages, off;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; MDB_page *np =3D mdb_pag= e_malloc(mc->mc_txn, ovpages);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; MDB_ID2 id2;<o:p></o:p><= /p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (!np)<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; ret= urn ENOMEM;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; id2.mid =3D pg;<o:p></o:= p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; id2.mptr =3D np;<o:p></o= :p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* Note - this page is a= lready counted in parent's dirty_room */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; rc2 =3D mdb_mid2l_insert= (mc->mc_txn->mt_u.dirty_list, &id2);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; mdb_cassert(mc, rc2 =3D= =3D 0);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (!(flags & MDB_RE= SERVE)) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; /* = Copy end of page, adjusting alignment so<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; * c= ompiler may copy words instead of bytes.<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; */<= o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; off= =3D (PAGEHDRSZ + data->mv_size) & -sizeof(size_t);<o:p></o:p></= p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; mem= cpy((size_t *)((char *)np + off),<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; (size_t *)((char *)omp + off), sz - off);<o:p></o:p><= /p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; sz = =3D PAGEHDRSZ;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; memcpy(np, omp, sz); /* = Copy beginning of page */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; omp =3D np;<o:p></o:p></= p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; SETDSZ(leaf, data->mv_size);<o:p></o:p></p=
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; if (F_ISSET(flags, MDB_RESERVE))<o:p></o:p></= p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; data->mv_data =3D MET= ADATA(omp);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; else<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; &nbs= p; memcpy(METADATA(omp), da= ta->mv_data, data->mv_size);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; return MDB_SUCCESS;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if ((rc2 =3D mdb_ovpage_free(mc, omp)) !=3D MDB_SUCCESS)<o:p></o:p=
</p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; return rc2;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; } else if (d= ata->mv_size =3D=3D olddata.mv_size) {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* same size, just replace it. Note that we could<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; * also reuse this node if the new data is smaller,<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; * but instead we opt to shrink the node in that case.<o:p></o:p></= p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; if (F_ISSET(flags, MDB_RESERVE))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; data->mv_data =3D olddata.mv_data;<o:p></o= :p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; else if (!(mc->mc_flags & C_SUB))<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; memcpy(olddata.mv_data, data->mv_data, dat= a->mv_size);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; else {<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; memcpy(NODEKEY(leaf), key->mv_data, key-&g= t;mv_size);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; &= nbsp; goto fix_parent;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; }<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; return MDB_SUCCESS;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; }<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; mdb_node_del= (mc, 0);<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; } <-------- This entire else c= ontingency was likely skipped!!<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; rdata =3D data;<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">new_sub:<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; nflags =3D flags & NODE_ADD_F= LAGS;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; nsize =3D IS_LEAF2(mc->mc_pg[m= c->mc_top]) ? key->mv_size : mdb_leaf_size(env, key, rdata); <----= ---- SEGV<o:p></o:p></p> <p class=3D"MsoPlainText">... &nbs= p; <o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">This may be an identifiable bug in mdb_cursor_put= () as It does not safely handle the case when the noted call to mdb_cursor_= set() returns MDB_NOTFOUND (-30798)!<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">It explicitly fails to preemptively exit by retur= ning an error in this case.<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">The value of -30798 is in turn assigned to insert= _key, which is therefore non-null in the condition of the subsequent if sta= tement.<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; insert_key =3D insert_data =3D rc= ; <-------- insert_key =3D -30798 or MDB_NOTFOUND!<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; if (insert_key) { <-------- tr= ue<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; /* The key d= oes not exist */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; DPRINTF((&qu= ot;inserting key at index %i", mc->mc_ki[mc->mc_top]));<o:p></o:= p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; if ((mc->= mc_db->md_flags & MDB_DUPSORT) &&<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; LEAFSIZE(key, data) > env->me_nodemax) <-------- false si= nce mc->mc_db->md_flags =3D 0<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; {<o:p></o:p>= </p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; /* Too big for a node, insert in sub-DB. Set up an empty<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; * "old sub-page" for prep_subDB to expand to a full page= .<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; */<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp_flags =3D P_LEAF|P_DIRTY;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp =3D env->me_pbuf;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp->mp_pad =3D data->mv_size; /* used if MDB_DUPFIXED */<o:p=
</o:p></p>
<p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; fp->mp_lower =3D fp->mp_upper =3D (PAGEHDRSZ-PAGEBASE);<o:p>= </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; olddata.mv_size =3D PAGEHDRSZ;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; &= nbsp; &nbs= p; goto prep_subDB;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; &nbs= p; } <------= -- this was not executed, and the very long else contingency below is skipp= ed!<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; } else {<o:p></o:p></p> <p class=3D"MsoPlainText">Since mc->mc_db->md_flags =3D 0, the contin= gency in the embedded if statement fails.<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">The segmentation fault occurs due to the call of = IS_LEAF2 on the null pointer mc->mc_pg[0].<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText"> &= nbsp; rdata =3D data;<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoPlainText">new_sub:<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; nflags =3D flags & NODE_ADD_F= LAGS;<o:p></o:p></p> <p class=3D"MsoPlainText"> &= nbsp; nsize =3D IS_LEAF2(mc->mc_pg[m= c->mc_top]) ? key->mv_size : mdb_leaf_size(env, key, rdata); <----= ---- SEGV<o:p></o:p></p> <p class=3D"MsoPlainText"><o:p> </o:p></p> <p class=3D"MsoNormal">Regards,<o:p></o:p></p> <p class=3D"MsoNormal">Robins.<o:p></o:p></p> </div> </body> </html>
--_000_MN2PR06MB55017A7261FA27380778753BAFEA0MN2PR06MB5501namp_--