[DTrace-devel] [PATCH 6/8] btf: fix memory leaks

Kris Van Hees kris.van.hees at oracle.com
Wed Apr 3 15:26:54 UTC 2024


Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/dt_btf.c    | 21 ++++++++++++++++-----
 libdtrace/dt_btf.h    |  1 +
 libdtrace/dt_module.c |  2 +-
 libdtrace/dt_open.c   |  3 +++
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/libdtrace/dt_btf.c b/libdtrace/dt_btf.c
index 3f713632..020c7877 100644
--- a/libdtrace/dt_btf.c
+++ b/libdtrace/dt_btf.c
@@ -240,7 +240,7 @@ dt_btf_load(dtrace_hdl_t *dtp, const char *fn)
 
 	fp = fopen(fn, "rb");
 	if (fp == NULL)
-		return dt_btf_set_load_errno(dtp,  errno);
+		goto err;
 
 	/* First see whether this might be a file with raw BTF data. */
 	if (fread(&hdr, 1, sizeof(hdr), fp) < sizeof(hdr))
@@ -317,12 +317,12 @@ elf_fail_no_end:
 	dt_btf_error(dtp, 0, "BTF: %s", elf_errmsg(err));
 	fclose(fp);
 
-	return NULL;
-
 fail:
 	dt_free(dtp, data);
+
+err:
+	dt_free(dtp, btf);
 	dt_btf_set_errno(dtp,  err ? err : errno);
-	fclose(fp);
 
 	return NULL;
 }
@@ -348,6 +348,17 @@ dt_btf_load_file(dtrace_hdl_t *dtp, const char *fn)
 	return btf;
 }
 
+void
+dt_btf_destroy(dtrace_hdl_t *dtp, dt_btf_t *btf)
+{
+	if (!btf)
+		return;
+
+	dt_free(dtp, btf->types);
+	dt_free(dtp, btf->data);
+	dt_free(dtp, btf);
+}
+
 static ctf_id_t
 dt_btf_add_to_ctf(dtrace_hdl_t *dtp, dt_btf_t *btf, ctf_dict_t *ctf,
 		  int32_t type_id)
@@ -752,7 +763,7 @@ dt_btf_load_module(dtrace_hdl_t *dtp, dt_module_t *dmp)
 	snprintf(fn, sizeof(fn), "/sys/kernel/btf/%s", dmp->dm_name);
 	btf = dt_btf_load_file(dtp, fn);
 
-	if (btf && strcmp(dmp->dm_name, "vmlinux") == 0)
+	if (btf && !dtp->dt_shared_btf && strcmp(dmp->dm_name, "vmlinux") == 0)
 		dtp->dt_shared_btf = btf;
 
 	return btf;
diff --git a/libdtrace/dt_btf.h b/libdtrace/dt_btf.h
index 85c8f1b4..f448ae59 100644
--- a/libdtrace/dt_btf.h
+++ b/libdtrace/dt_btf.h
@@ -18,6 +18,7 @@ extern "C" {
 typedef struct dt_btf	dt_btf_t;
 
 extern const char *dt_btf_errmsg(int);
+extern void dt_btf_destroy(dtrace_hdl_t *, dt_btf_t *);
 extern dt_btf_t *dt_btf_load_module(dtrace_hdl_t *, dt_module_t *);
 extern ctf_dict_t *dt_btf_module_ctf(dtrace_hdl_t *, dt_module_t *);
 extern const char *dt_btf_get_string(dtrace_hdl_t *, dt_btf_t *, uint32_t);
diff --git a/libdtrace/dt_module.c b/libdtrace/dt_module.c
index 3182f388..abd4c0ca 100644
--- a/libdtrace/dt_module.c
+++ b/libdtrace/dt_module.c
@@ -617,7 +617,7 @@ static void
 dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
 {
 	if (dmp->dm_btf != dtp->dt_shared_btf)
-		dt_free(dtp, dmp->dm_btf);
+		dt_btf_destroy(dtp, dmp->dm_btf);
 	dmp->dm_btf = NULL;
 
 	if (dmp->dm_ctfp != dtp->dt_shared_ctf)
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index 06a932be..66cee0a4 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -29,6 +29,7 @@
 
 #include <dt_impl.h>
 #include <dt_bpf.h>
+#include <dt_btf.h>
 #include <dt_pcap.h>
 #include <dt_program.h>
 #include <dt_module.h>
@@ -1279,6 +1280,8 @@ dtrace_close(dtrace_hdl_t *dtp)
 	dt_htab_destroy(dtp, dtp->dt_mods);
 	dt_htab_destroy(dtp, dtp->dt_kernpaths);
 
+	if (dtp->dt_shared_btf != NULL)
+		dt_btf_destroy(dtp, dtp->dt_shared_btf);
 	if (dtp->dt_shared_ctf != NULL)
 		ctf_close(dtp->dt_shared_ctf);
 	if (dtp->dt_ctfa != NULL)
-- 
2.42.0




More information about the DTrace-devel mailing list