>>> Howard Chu <h...@symas.com> schrieb am 14.08.2020 um 02:14 in Nachricht <a9c55a18-7a70-1c84-42d7-bf7163455...@symas.com>: > Gábor Melis wrote: >> Hello >> >> I'm writing a Common Lisp wrapper for LMDB, starting where the >> previous efforts left off. I have a number of questions related to >> safety and the color of the smoke after a disaster. > > You should consider any misuses as you describe here as fatal, resulting > in irreparably corrupted DBs. >> >> 1. lmdb.h says that "A parent transaction and its cursors may not >> issue any other operations than mdb_txn_commit and mdb_txn_abort >> while it has active child transactions." >> >> What I observe is that when a cursor associated with the parent >> transaction is used in the child, there are no errors and the >> cursor behaves (my test only involved mdb_cursor_put and >> MDB_SET_KEY) as if it belonged to the child. >> >> Is this to be expected in general or my tests are insufficient and >> something really bad can happen? If this is a disaster waiting to >> happen, I need to add checks to the cursor code. > > Sounds like your test case was lucky. >> >> 2. mdb_txns are calloc()ed and free()d. In the case where a thread >> performs some operation (e.g. put, get, del) involving an already >> freed mdb_txn pointer, what kind of nastiness can happen? Can the >> database be corrupted? > > The C standard says any references to freed memory result in undefined > behavior. Nobody can give you a more specific answer than that. >> >> 3. Same question about mdb_cursors. >> >> 4. Async unwind safety. This is a bit like a thread being destroyed in >> the middle of an lmdb function call. >> >> Context: In some Common Lisp implementations (SBCL), Posix >> interrupts like SIGINT are used during development. If the >> developer presses C-c the lisp debugger will start where the signal >> handler was invoked, which may be in the middle of some mdb_* call. >> Depending on the actions taken, the stack (both the lisp and the C >> stack) may be unwound to some earlier frame. Another example is >> async timeouts (SBCL's WITH-TIMEOUT) can also unwind the stack. I >> understand that async unwinds are unsafe in general. >> >> There is a way to defer handling of interrupts, which I already use >> to protect allocations (mdb_txn_begin, mdb_txn_commit and similar), >> but it has a small performance cost and I hesitate to apply it to >> performance hotspots (e.g. put, get, del and most cursor ops). Are >> [some of] these functions safe in face of async unwinds? What kind >> of problem may arise? > > In a default build, read txns are always safe. No guarantees on > an interrupted write txn.
But still a valid issue is: Can some extra "debugging" protection code be added to locate such problems in LMDB? Examples I could think of: Assigning NULL to pointers that were freed, assigning -1 for file descriptors that were closed, etc. Then you'd get a core dump on modern architectures after such constellations at least. >> >> Cheers, >> Gábor Melis >> > > > -- > -- Howard Chu > CTO, Symas Corp. http://www.symas.com > Director, Highland Sun http://highlandsun.com/hyc/ > Chief Architect, OpenLDAP http://www.openldap.org/project/