Howard Chu hyc@symas.com writes:
It would seem that attr_merge() (in attr.c) should have something like this:
if ( *a == NULL ) { *a = attr_alloc( desc ); if (desc->ad_type->sat_flags& SLAP_AT_SORTED_VAL) { (*a)->a_flags |= SLAP_ATTR_SORTED_VALS; } } else {
This is now fixed in HEAD in value.c.
Tested, bad behavior still persists. The call path I've observed is as follows:
T@5 : | | | | | >bdb_modify_internal T@5 : | | | | | | >modify_add_values T@5 : | | | | | | | >attr_merge T@5 : | | | | | | | | >attr_alloc
ordered_value_add() doesn't seem to be involved (I can provide the entire trace if necessary)
Further pursuing the issue, I started to focus on the index deletion code that was changed as a part of ITS#5183. Specifically, the portion of code within bdb_modify_internal() (in back-bdb/modify.c) that is commented:
/* Move deleted values to end of array */
This code modifies save_attrs, which is actually apparently a pointer to memory that resides within the cache. If a deadlock occurs, these changes are not reverted, thereby corrupting the entry in the cache. I replaced this code with the pre-ITS#5183 code and I am no longer able to 'break' the object and insert duplicate member/memberUids.
This is now fixed in HEAD.
Looks good, thanks.