https://bugs.openldap.org/show_bug.cgi?id=10395
kero renault.cle@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #1086|0 |1 is obsolete| |
--- Comment #4 from kero renault.cle@gmail.com --- Created attachment 1088 --> https://bugs.openldap.org/attachment.cgi?id=1088&action=edit Support nested RDONLY transactions
Hey Howard,
I took more time to work on this patch to introduce the possibility of creating multiple nested RDONLY transactions from a parent one. This was already the case with my previous patch, but now: - The nested transactions are RDONLY and disallow writes. - The parent transaction prevents creating nested transactions, unless they are all RDONLY. - Nested RDONLY transactions now avoid leaking me_pgstate/me_pghead by not allocating or copying them.
However, I still encounter a SIGBUS error when using a cursor on a dbi created by the current parent transaction but not yet committed. It seems that the issue originates from mc->mc_pg and MDB_page.mp2_flags not being properly initialized.
I wrote a reproducer at the end of this very message. Would you have a moment to review and help me identify the source of the issue?
Have a nice end of the week, kero
#include <stdio.h> #include <stdlib.h> #include "lmdb.h"
#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) #define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0)) #define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \ "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))
int main(int argc,char * argv[]) { int rc; MDB_env *env; MDB_dbi dbi; MDB_val key, data; MDB_txn *txn, *nested; MDB_cursor *cursor;
E(mdb_env_create(&env)); E(mdb_env_set_maxdbs(env, 1)); E(mdb_env_set_maxreaders(env, 1)); E(mdb_env_set_mapsize(env, 10485760)); E(mdb_env_open(env, "./testdb", 0, 0664));
E(mdb_txn_begin(env, NULL, 0, &txn)); E(mdb_dbi_open(txn, "brand-new-db", MDB_CREATE, &dbi));
key.mv_data = "test-key\0"; key.mv_size = sizeof("test-key\0");
data.mv_data = "test-data\0"; data.mv_size = sizeof("test-data\0");
RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE));
E(mdb_txn_begin(env, txn, MDB_RDONLY, &nested)); E(mdb_cursor_open(nested, dbi, &cursor));
/* Crashes with a SIGBUS, a wrongly initialized mc->mc_pg */ RES(MDB_NOTFOUND, mdb_cursor_get(cursor, &key, &data, MDB_NEXT));
return 0; }