I have observed random failures with PIC, when looking up breakpoints.
It looks like find_slot() doesn't search far enough in to the dictionary
before giving up, after an item has been erased.
Patch enclosed with a simple test-case.
Regards,
Faraz Shahbazker
diff --git a/dict.c b/dict.c
index 236e90e..3f9be8c 100644
--- a/dict.c
+++ b/dict.c
@@ -227,8 +227,10 @@ find_slot(struct dict *dict, const void *key,
* later, we return that position. */
for (; bitp(dict, pos)->taken || bitp(dict, pos)->erased;
pos = (pos + d) % n(dict)) {
- if (pos0 == (size_t)-1 && bitp(dict, pos)->erased)
+ if (pos0 == (size_t)-1 && bitp(dict, pos)->erased) {
pos0 = pos;
+ continue;
+ }
/* If there is a loop, but we've seen an erased
* element, take that one. Otherwise give up. */
@@ -635,10 +637,39 @@ test_erase(void)
DICT_DESTROY(&d2, int, int, NULL, NULL, NULL);
}
+static void
+test_erase_find(void)
+{
+ /* Degenerate case for erase followed by find, considering 2 colliding keys.
+ Erase 1st inserted key, then try finding 2nd.
+ */
+ struct dict d2;
+ DICT_INIT(&d2, int, int, dict_hash_int_silly, dict_eq_int, NULL);
+ int key;
+ int value;
+
+ key = 0, value = 0;
+ DICT_INSERT(&d2, &key, &value);
+ key = 10, value = 10;
+ DICT_INSERT(&d2, &key, &value);
+
+ key = 10;
+ assert (DICT_FIND_REF(&d2, &key, int) != NULL);
+
+ key = 0;
+ DICT_ERASE(&d2, &key, int, NULL, NULL, NULL);
+
+ key = 10;
+ assert (DICT_FIND_REF(&d2, &key, int) != NULL);
+
+ DICT_DESTROY(&d2, int, int, NULL, NULL, NULL);
+}
+
int main(int argc, char *argv[])
{
test1();
test_erase();
+ test_erase_find();
return 0;
}
_______________________________________________
Ltrace-devel mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/ltrace-devel