Dear List,
I have run CodeSonar on a project using lmdb. I have downloaded lmdb-0.9.70.tar.gz. These
warnings are a "Copy-Paste" error and "Use of memory after free". I
would like to share the details to help find out whether these are real or false
positives.
The copy-paste warning is generated by code around lines 8870f in mdb.c. In the first
block, csrc-> is used throughout, in the second block cdst-> is used, except in one
line:
/* Update the parent separators.
*/
if (csrc->mc_ki[csrc->mc_top] == 0) {
if (csrc->mc_ki[csrc->mc_top-1] != 0) {
if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) {
key.mv_data = LEAF2KEY(csrc->mc_pg[csrc->mc_top], 0, key.mv_size);
} else {
srcnode = NODEPTR(csrc->mc_pg[csrc->mc_top], 0);
key.mv_size = NODEKSZ(srcnode);
key.mv_data = NODEKEY(srcnode);
}
DPRINTF(("update separator for source page %"Yu" to [%s]",
csrc->mc_pg[csrc->mc_top]->mp_pgno, DKEY(&key)));
mdb_cursor_copy(csrc, &mn);
mn.mc_snum--;
mn.mc_top--;
/* We want mdb_rebalance to find mn when doing fixups */
WITH_CURSOR_TRACKING(mn,
rc = mdb_update_key(&mn, &key));
if (rc)
return rc;
}
if (IS_BRANCH(csrc->mc_pg[csrc->mc_top])) {
MDB_val nullkey;
indx_t ix = csrc->mc_ki[csrc->mc_top];
nullkey.mv_size = 0;
csrc->mc_ki[csrc->mc_top] = 0;
rc = mdb_update_key(csrc, &nullkey);
csrc->mc_ki[csrc->mc_top] = ix;
mdb_cassert(csrc, rc == MDB_SUCCESS);
}
}
if (cdst->mc_ki[cdst->mc_top] == 0) {
if (cdst->mc_ki[cdst->mc_top-1] != 0) {
if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) {
/*
Copy-Paste Error [help]
<
http://codesonar.rd.skov.com:7340/install/codesonar/doc/html/CodeSonar.ht...
This block of text appears to be a modified copy of the highlighted text. Did you intend
to consistently change csrc to cdst, including here?
*/
key.mv_data = LEAF2KEY(cdst->mc_pg[cdst->mc_top], 0, key.mv_size);
} else {
srcnode = NODEPTR(cdst->mc_pg[cdst->mc_top], 0);
key.mv_size = NODEKSZ(srcnode);
key.mv_data = NODEKEY(srcnode);
}
DPRINTF(("update separator for destination page %"Yu" to
[%s]",
cdst->mc_pg[cdst->mc_top]->mp_pgno, DKEY(&key)));
mdb_cursor_copy(cdst, &mn);
mn.mc_snum--;
mn.mc_top--;
/* We want mdb_rebalance to find mn when doing fixups */
WITH_CURSOR_TRACKING(mn,
rc = mdb_update_key(&mn, &key));
if (rc)
return rc;
}
if (IS_BRANCH(cdst->mc_pg[cdst->mc_top])) {
MDB_val nullkey;
indx_t ix = cdst->mc_ki[cdst->mc_top];
nullkey.mv_size = 0;
cdst->mc_ki[cdst->mc_top] = 0;
rc = mdb_update_key(cdst, &nullkey);
cdst->mc_ki[cdst->mc_top] = ix;
mdb_cassert(cdst, rc == MDB_SUCCESS);
}
}
The second error is triggered by the loop freeing loose pages at line 3451 in mdb.c:
NEXT_LOOSE_PAGE(mp) would access memory that is freed before, if mp points to an overflow
page with more than one page allocated. If this is never the case, then maybe
mdb_page_free() should be called on mp directly?
for (; mp; mp = NEXT_LOOSE_PAGE(mp)) {
/*
Use After Free [help]
<
http://codesonar.rd.skov.com:7340/install/codesonar/doc/html/CodeSonar.ht...
The memory pointed to by mp was freed at mdb.c:2047 and is read from here.
*/
mdb_midl_xappend(txn->mt_free_pgs, mp->mp_pgno);
/* must also remove from dirty list */
if (txn->mt_flags & MDB_TXN_WRITEMAP) {
for (x=1; x<=dl[0].mid; x++)
if (dl[x].mid == mp->mp_pgno)
break;
mdb_tassert(txn, x <= dl[0].mid);
} else {
x = mdb_mid2l_search(dl, mp->mp_pgno);
mdb_tassert(txn, dl[x].mid == mp->mp_pgno);
}
dl[x].mptr = NULL;
mdb_dpage_free(env, mp);
mdb_dpage_free(MDB_env *env, MDB_page *dp)
{
if (!IS_OVERFLOW(dp) || dp->mp_pages == 1) {
mdb_page_free(env, dp);
} else {
/* large pages just get freed directly */
VGMEMP_FREE(env, dp);
free(dp);
}
}
I hope you can follow these descriptions, I can provide more detail if needed. I would
like to get some help figuring out how to resolve these warnings.
Best regards,
Christian Wendt
Software developer
Ext: +45 7217 5943
______________________________________
SKOV A/S
Hedelund 4, Glyngoere, 7870 Roslev, Denmark
Tel.: +45 7217 5555 - Fax: +45 7217 5959
www.skov.com<http://www.skov.com/>