-
-
Notifications
You must be signed in to change notification settings - Fork 111
Unexpected 'MDBX_PROBLEM' error when reusing cursors from read-only transactions #272
Comments
I will deal with your issue later, but it is reasonable to clarify the essence beforehand:
But in all these cases, the |
Basically, libmdbx's cursors is allocated (malloc/free) internally, and visible outside only as a pointers. As I wrote above, a binded cursor is linked to a transaction object and unlink from it on transaction termination or explicitly during cursor rebind or close. Please provide a test case or a pseudo code of your scenario. |
I have a simple test case now. Premise: I do not know if I am misusing mdbx API, in this case accept my apologies and please tell me when and how to use the mdbx_cursor_bind. Try this code:
If the second transaction, txn2, will be allocated at a different address than txn1, in the second cursor bind you will see that the cursor has a member mc_txn pointing to the old, destroyed, txn1 so it is a dangling pointer. So when the code that I quoted in my first post is ran, the dangling pointer is used and likely an error is raised. These are the variables the debug sees in the first and the second bind: |
Seems a bug, I'ill check/fix. |
Briefly, this commit fixes a missed flaw:
|
Thanks! My test case now works. |
Thank you for reporting. |
I am getting occasionally exceptions (MDBX_PROBLEM) on mdbx_cursor_bind.
For some reasons, I have a cursor with thread storage duration (thread_local) and I rebind it using mdbx_cursor_bind when I need to re-use it for another operation on a different transaction.
The code where the error MDBX_PROBLEM is generated is this:
libmdbx/src/core.c
Lines 16468 to 16474 in d01e44d
In a my failed run the checks of this code are as follows:
mc->mc_signature == MDBX_MC_LIVE
=> ok, the cursor has thread local duration, it will be closed at program termination (!), so no clean up code was called since the last usemc->mc_txn != 0
=> it is possible: the cursor was previously used so has an old txn addressmc->mc_txn->mt_signature != MDBX_MT_SIGNATURE
=> this condition is WRONG according to the code but it is NOT_IMPORTANT according to me: the previous transaction was destroyed, we are binding the cursor to another transaction so the memory area of the old transaction may have been reclaimed for other purposes so we are reading dirty dataOn some runs the memory area casually can be untouched so I get no error, sometimes on the contrary can be dirty and I got the error.
I think that the check on the
mc->mc_txn
is wrong here, it can be omitted.This is the state of variables:
I got the same on the releases: v0.11.4, v0.11.5
The text was updated successfully, but these errors were encountered: