Description of problem: the compare function in db_185 mode is called with key2 containing garbage in the high bits of the size field. Version-Release number of selected component (if applicable): db4-4.3.29-2.x86_64 How reproducible: Always. Steps to Reproduce: 1. gcc -o test_db test_db.c -ldb 2. ./test_db Actual results: key1->size = 3 key2->size = 2ada00000003 Expected results: key1->size = 3 key2->size = 3 Additional info:
Created attachment 125913 [details] test_db.c
Yes, reproduced on x86_64. <nitpick> key->size should be cast as size_t instead of unsigned long. </nitpick>
size_t isn't known to printf.. unsigned long is the closest approximation which is.. (key->size is a size_t). Either way the problem is not related to the cast. The cast is just there to be able to print this size_t.
Of course it's not a cast problem, but a db bug. The problem is that __bam_cmp() from bt_compare.c that calls compare() function in your code actually calls the comparison function prototyped as: int (*func)__P((DB *, const DBT *, const DBT *)); but the prototype declared in BTREEINFO claims the comparison function is: int (*compare) /* comparison function */ __P((const DBT *, const DBT *)); what doesn't look too consistent to me.
I seriously doubt this is the case. If this was the case then the compare function would not work at all, and the first argument surely would not be the needle to match against. Now the first argument works fine, and is the needle to match agains. The problem is in the second argument where dbt->data is correct but dbt->size contains garbage in the high bits and the correct size in the lower 32 bits. From what I can tell func mentioned here should be db185_compare, which in turn talls the supplied compare function with the correct arguments.
Looked a bit further. The problem is in db185/ where DBT is used for the 185 compare function where DBT185 should be used.. db185_compare should in fact translate DBT to DBT185, not pass it along unmodified. Works on 32-bit machines only because there DBT and DBT185 has the exact same common fields with DBT only beeing bigger (size_t == uint32_t on 32-bits), but fails on 64-bit machines as there size_t is 64 bits while DBT only has 32-bits in the size field.. The "garbage" is the ulen field from the DB4 DBT incorrectly passed to the compare function..
Created attachment 126044 [details] Change compare and prefix functions to use DBT185 wrapper Attached is an initial patch adding this translation of DBT to DBT185. Not yet verified, but should work... Note: DBT185 is the internal representation of the 1.85 DBT, same as DBT in /usr/include/db_185.h.
Looked into upstream release notes and it's a known bug in 4.3.29 and is fixed in 4.4.20. Documented in the "Utility Changes" section of the release notes. 3. Fix a bug in the 1.85 compatibility code supporting per-application Btree comparison and prefix compression functions. The functions would not work on big-endian 64-bit hardware. [#13316] just that the bug is broader than they thought and it these functions won't work on 64-bit hardware, little or big endian.
Created attachment 126050 [details] Change compare and prefix functions to use DBT185 wrapper Sorry, got the patch order reversed in the original patch. This is the same patch but in correct direction.. the building of a patched db4 package has now finished and the patch has now been verified to do what it should..
One more note: The DB man page documents db 1.85, not the DB 2.X or later interfaces.. should file a bug against the man-pages package about the header name in the man page, still claims one should include db.h when the db 1.85 API is in db_185.h..
Yes, feel free to report a new bug for man pages then. I do believe that documentation might be outdated. Your fix is now applied. Thanks.
From User-Agent: XML-RPC db4-4.3.27-5.fc4 has been pushed for FC4, which should resolve this issue. If these problems are still present in this version, then please make note of it in this bug report.
Haven't seen an FC5 update of this package yet. Seems a bit odd to have it pushed to FC4, but not FC5 which the bug was reported against. If it is in the FC5 repository but just not yet rebuilt / propagated out to the mirrors then ignore me. If not please don't forget to push it into FC5 as well at some point in time..
The delay is caused by FC5/FC6 branch split done yestreday, which of course doesn't affect FC4, therefore it's pushed sooner. FC5 db4 is now built for four days already so the package will appear in FC5 updates soon.