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

Reply via email to