git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 05/10] commit-graph: free all elements of graph chain

From
Jeff King <peff@peff.net>
Date
Oct 3, 2023, 20:29 UTC
Message-ID
<20231003202930.GE7812@coredump.intra.peff.net>
In-Reply-To
<20231003202504.GA7697@coredump.intra.peff.net>

When running "commit-graph verify", we call free_commit_graph(). That's sufficient for the case of a single graph file, but if we loaded a chain of split graph files, they form a linked list via the base_graph pointers. We need to free all of them, or we leak all but the first struct.

We can make this work by teaching free_commit_graph() to walk the base_graph pointers and free each element. This in turn lets us simplify close_commit_graph(), which does the same thing by recursion (we cannot just use close_commit_graph() in "commit-graph verify", as the function takes a pointer to an object store, and the verify command creates a single one-off graph struct).

While indenting the code in free_commit_graph() for the loop, I noticed that setting g->data to NULL is rather pointless, as we free the struct a few lines later. So I cleaned that up while we're here.

Signed-off-by: Jeff King <peff@peff.net>
---
 commit-graph.c | 29 +++++++++++------------------
 1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/commit-graph.c b/commit-graph.c
index dc54ef4776..2f75ecd9ae 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -723,19 +723,10 @@ struct bloom_filter_settings *get_bloom_filter_settings(struct repository *r)
 	return NULL;
 }
 
-static void close_commit_graph_one(struct commit_graph *g)
-{
-	if (!g)
-		return;
-
-	close_commit_graph_one(g->base_graph);
-	free_commit_graph(g);
-}
-
 void close_commit_graph(struct raw_object_store *o)
 {
 	clear_commit_graph_data_slab(&commit_graph_data_slab);
-	close_commit_graph_one(o->commit_graph);
+	free_commit_graph(o->commit_graph);
 	o->commit_graph = NULL;
 }
 
@@ -2753,15 +2744,17 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
 
 void free_commit_graph(struct commit_graph *g)
 {
-	if (!g)
-		return;
-	if (g->data) {
-		munmap((void *)g->data, g->data_len);
-		g->data = NULL;
+	while (g) {
+		struct commit_graph *next = g->base_graph;
+
+		if (g->data)
+			munmap((void *)g->data, g->data_len);
+		free(g->filename);
+		free(g->bloom_filter_settings);
+		free(g);
+
+		g = next;
 	}
-	free(g->filename);
-	free(g->bloom_filter_settings);
-	free(g);
 }
 
 void disable_commit_graph(struct repository *r)
-- 
2.42.0.810.gbc538a0ee6
Previous: Taylor BlauNext: Jeff King
Message 9 of 24 in “some commit-graph leak fixes”
  1. 0/10 some commit-graph leak fixesJeff King, Oct 3, 2023
  2. 01/10 t6700: mark test as leak-freeJeff King, Oct 3, 2023
  3. Taylor BlauOct 5, 2023
  4. 02/10 commit-reach: free temporary list in get_octopus_merge_bases()Jeff King, Oct 3, 2023
  5. 03/10 merge: free result of repo_get_merge_bases()Jeff King, Oct 3, 2023
  6. Taylor BlauOct 5, 2023
  7. 04/10 commit-graph: move slab-clearing to close_commit_graph()Jeff King, Oct 3, 2023
  8. Taylor BlauOct 5, 2023
  9. 05/10 commit-graph: free all elements of graph chainJeff King, Oct 3, 2023
  10. 06/10 commit-graph: delay base_graph assignment in add_graph_to_chain()Jeff King, Oct 3, 2023
  11. Taylor BlauOct 5, 2023
  12. 07/10 commit-graph: free graph struct that was not added to chainJeff King, Oct 3, 2023
  13. 08/10 commit-graph: free write-context entries before overwritingJeff King, Oct 3, 2023
  14. Taylor BlauOct 5, 2023
  15. Jeff KingOct 5, 2023
  16. 09/10 commit-graph: free write-context base_graph_name during cleanupJeff King, Oct 3, 2023
  17. 10/10 commit-graph: clear oidset after finishing writeJeff King, Oct 3, 2023
  18. Is SANITIZE=leak make test unreliable for anyone else?Eric W. Biederman, Oct 4, 2023
  19. Jeff KingOct 4, 2023
  20. Eric W. BiedermanOct 4, 2023
  21. Jeff KingOct 4, 2023
  22. Eric W. BiedermanOct 4, 2023
  23. Taylor BlauOct 5, 2023
  24. Junio C HamanoOct 6, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.