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

[PATCH 5/7] Introduce malloc/strdup/pathdup variants for permanent allocations

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Oct 2, 2010, 08:38 UTC
Message-ID
<20101002083851.GF29638@burratino>
In-Reply-To
<20101002082752.GA29638@burratino>

In git (option parsing and some other places), we sometimes leak tiny bits of memory on purpose. Introduce a way to declare such allocations, to make the lives of people searching for real memory leaks easier.

Currently these are thin wrappers around xmalloc and xstrdup. The KEEP_WRAPPER attribute avoids a tail call to ensure their stack frame does not get replaced with the true xmalloc/xstrdup, so tools like valgrind can easily distinguish them and know that the memory they return is not meant to be freed.

In the long run it might be nice to tighten the semantics of these functions and use memory from a large pool that is never freed (to avoid fragmentation and save some allocation overhead).

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 cache.h                 |    2 ++
 git-compat-util.h       |    2 ++
 path.c                  |   10 ++++++++++
 t/valgrind/default.supp |   17 +++++++++++++++++
 wrapper.c               |   14 ++++++++++++++
 5 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/cache.h b/cache.h
index 9ee61a2..bbf32ff 100644
--- a/cache.h
+++ b/cache.h
@@ -638,6 +638,8 @@ extern char *git_snpath(char *buf, size_t n, const char *fmt, ...)
 	__attribute__((format (printf, 3, 4)));
 extern char *git_pathdup(const char *fmt, ...)
 	__attribute__((format (printf, 1, 2)));
+extern char *git_pathdup_permanent(const char *fmt, ...)
+	__attribute__((format (printf, 1, 2)));
 
 /* Return a statically allocated filename matching the sha1 signature */
 extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
diff --git a/git-compat-util.h b/git-compat-util.h
index 81883e7..f00ee33 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -380,7 +380,9 @@ typedef void (*try_to_free_t)(size_t);
 extern try_to_free_t set_try_to_free_routine(try_to_free_t);
 
 extern char *xstrdup(const char *str);
+extern char *strdup_permanent(const char *str);
 extern void *xmalloc(size_t size);
+extern void *alloc_permanent(size_t size);
 extern void *xmallocz(size_t size);
 extern void *xmemdupz(const void *data, size_t len);
 extern char *xstrndup(const char *str, size_t len);
diff --git a/path.c b/path.c
index a2c9d1e..332c903 100644
--- a/path.c
+++ b/path.c
@@ -87,6 +87,16 @@ char *git_pathdup(const char *fmt, ...)
 	return xstrdup(path);
 }
 
+char *git_pathdup_permanent(const char *fmt, ...)
+{
+	char path[PATH_MAX];
+	va_list args;
+	va_start(args, fmt);
+	(void)git_vsnpath(path, sizeof(path), fmt, args);
+	va_end(args);
+	return strdup_permanent(path);
+}
+
 char *mkpath(const char *fmt, ...)
 {
 	va_list args;
diff --git a/t/valgrind/default.supp b/t/valgrind/default.supp
index 7789edd..d237210 100644
--- a/t/valgrind/default.supp
+++ b/t/valgrind/default.supp
@@ -45,6 +45,23 @@
 }
 
 {
+	leaky malloc for option parsing and configuration
+	Memcheck:Leak
+	fun:malloc
+	fun:xmalloc
+	fun:alloc_permanent
+}
+
+{
+	leaky strdup for option parsing and configuration
+	Memcheck:Leak
+	fun:malloc
+	fun:strdup
+	fun:xstrdup
+	fun:strdup_permanent
+}
+
+{
 	see api-lockfile.txt
 	Memcheck:Leak
 	fun:calloc
diff --git a/wrapper.c b/wrapper.c
index fd8ead3..88ca3dd 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -3,6 +3,8 @@
  */
 #include "cache.h"
 
+#define KEEP_WRAPPER __attribute__((optimize("-fno-optimize-sibling-calls")))
+
 static void try_to_free_builtin(size_t size)
 {
 	release_pack_memory(size, -1);
@@ -17,6 +19,12 @@ try_to_free_t set_try_to_free_routine(try_to_free_t routine)
 	return old;
 }
 
+KEEP_WRAPPER
+char *strdup_permanent(const char *str)
+{
+	return xstrdup(str);
+}
+
 char *xstrdup(const char *str)
 {
 	char *ret = strdup(str);
@@ -29,6 +37,12 @@ char *xstrdup(const char *str)
 	return ret;
 }
 
+KEEP_WRAPPER
+void *alloc_permanent(size_t size)
+{
+	return xmalloc(size);
+}
+
 void *xmalloc(size_t size)
 {
 	void *ret = malloc(size);
-- 
1.7.2.3
Previous: Nguyen Thai Ngoc DuyNext: Jonathan Nieder
Message 23 of 33 in “memory leak reported by valgrind”
  1. memory leak reported by valgrindIvan Kanis, Aug 9, 2010
  2. Junio C HamanoAug 9, 2010
  3. Erik Faye-LundAug 9, 2010
  4. Alex RiesenAug 9, 2010
  5. Jonathan NiederAug 10, 2010
  6. 1/3 core: Stop leaking ondisk_cache_entrysJonathan Nieder, Aug 10, 2010
  7. 2/3 write-tree: Avoid leak when index refers to an invalid objectJonathan Nieder, Aug 10, 2010
  8. 3/3 read-tree: stop leaking tree objectsJonathan Nieder, Aug 10, 2010
  9. 0/7 Re: [PATCH] memory leak reported by valgrindJonathan Nieder, Oct 2, 2010
  10. 1/7 init: plug tiny one-time memory leakJonathan Nieder, Oct 2, 2010
  11. Junio C HamanoOct 3, 2010
  12. init: plug tiny one-time memory leakJonathan Nieder, Oct 4, 2010
  13. 2/7 lockfile: introduce alloc_lock_file() to avoid valgrind noiseJonathan Nieder, Oct 2, 2010
  14. Andreas EricssonOct 2, 2010
  15. Jonathan NiederOct 2, 2010
  16. Junio C HamanoOct 6, 2010
  17. Jonathan NiederOct 6, 2010
  18. Junio C HamanoOct 6, 2010
  19. Jonathan NiederOct 6, 2010
  20. 3/7 environment.c: remove unused variableJonathan Nieder, Oct 2, 2010
  21. 4/7 setup: make sure git dir path is in a permanent bufferJonathan Nieder, Oct 2, 2010
  22. Nguyen Thai Ngoc DuyOct 4, 2010
  23. 5/7 Introduce malloc/strdup/pathdup variants for permanent allocationsJonathan Nieder, Oct 2, 2010
  24. 6/7 environment: use alloc_permanent() for computed git_dir and coJonathan Nieder, Oct 2, 2010
  25. 7/7 commit-tree: free commit message before exitingJonathan Nieder, Oct 2, 2010
  26. Sverre RabbelierOct 2, 2010
  27. Jonathan NiederOct 2, 2010
  28. Sverre RabbelierOct 2, 2010
  29. Jonathan NiederOct 2, 2010
  30. Junio C HamanoOct 4, 2010
  31. Jonathan NiederOct 4, 2010
  32. Junio C HamanoOct 4, 2010
  33. Jonathan NiederOct 4, 2010

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.