[DTrace-devel] [PATCH v2 04/11] htab: have dt_htab_destroy del all the elements

Nick Alcock nick.alcock at oracle.com
Wed Oct 20 11:53:57 PDT 2021


This means that a dt_htab_destroy of a non-empy htab doesn't leak memory
and leave all its former elements full of wild pointers.

Also add some comments to dt_htab_delete given how many mistakes I made
reading it.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
---
 libdtrace/dt_htab.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/libdtrace/dt_htab.c b/libdtrace/dt_htab.c
index e8004e2b2bca..b8910442cd07 100644
--- a/libdtrace/dt_htab.c
+++ b/libdtrace/dt_htab.c
@@ -73,13 +73,24 @@ dt_htab_t *dt_htab_create(dtrace_hdl_t *dtp, dt_htab_ops_t *ops)
 }
 
 /*
- * Destroy a hashtable.
+ * Destroy a hashtable, deleting all its entries first.
  */
 void dt_htab_destroy(dtrace_hdl_t *dtp, dt_htab_t *htab)
 {
+	size_t		i;
+
 	if (!htab)
 		return;
 
+	for (i = 0; i < htab->size; i++) {
+		dt_hbucket_t	*bucket = htab->tab[i];
+
+		while (bucket && bucket->head)
+			bucket->head = htab->ops->del(bucket->head,
+			    bucket->head);
+		free(bucket);
+	}
+
 	dt_free(dtp, htab->tab);
 	dt_free(dtp, htab);
 }
@@ -193,6 +204,10 @@ int dt_htab_delete(dt_htab_t *htab, void *entry)
 	dt_hbucket_t	*bucket;
 	void		*head;
 
+	/*
+	 * Find the right bucket in cases of hash collision.
+	 */
+
 	for (bucket = htab->tab[idx]; bucket; bucket = bucket->next) {
 		if (htab->ops->cmp(bucket->head, entry) == 0)
 			break;
@@ -201,9 +216,16 @@ int dt_htab_delete(dt_htab_t *htab, void *entry)
 	if (bucket == NULL)
 		return -ENOENT;
 
+	/*
+	 * Destroy the specified entry, now known to be in this bucket.
+	 */
 	head = htab->ops->del(bucket->head, entry);
 	bucket->nentries--;
 	htab->nentries--;
+
+	/*
+	 * Deal with a now-empty bucket.
+	 */
 	if (!head) {
 		dt_hbucket_t	*b = htab->tab[idx];
 
-- 
2.33.1.257.g9e0974a4e8




More information about the DTrace-devel mailing list