From: Jonathan Nieder <jrnieder@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org, Pierre Habouzit <madcoder@debian.org>,
David Barr <david.barr@cordelta.com>
Subject: [PATCH 2/7] lockfile: introduce alloc_lock_file() to avoid valgrind noise
Date: Sat, 2 Oct 2010 03:32:16 -0500 [thread overview]
Message-ID: <20101002083216.GC29638@burratino> (raw)
In-Reply-To: <20101002082752.GA29638@burratino>
The current lockfile API often requires leaking memory:
- the list of lockfiles to remove at exit is maintained in a
singly linked list, so one cannot easily remove a lockfile
record when it is no longer needed
- some lockfile records are statically allocated and others are on
the heap, so the remove_lock_file() atexit handler cannot easily
free them at exit (not to mention that it would be a waste of time
since _exit() takes care of freeing them anyway)
As the git libification effort proceeds, maybe this will become worth
fixing. For now, since there are so few lock files used by a given
process, it is simpler to tolerate the leak.
Add a alloc_lock_file() helper to make such tolerance easier.
Allocations made through this helper function will not be reported as
leaks by valgrind even if there is no corresponding free(). The
((optimize("-fno-optimize-sibling-calls"))) attribute is needed on
platforms with GCC to ensure that the stack frame for
alloc_lock_file() is not replaced by the stack frame for xcalloc().
For illustration, this patch updates a few example xcalloc(1,
sizeof(struct lockfile)) call sites to use the new wrapper.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Documentation/technical/api-lockfile.txt | 9 +++++++++
builtin/update-index.c | 4 +---
cache-tree.c | 7 +------
cache.h | 1 +
config.c | 2 +-
lockfile.c | 6 ++++++
t/valgrind/default.supp | 8 ++++++++
7 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/Documentation/technical/api-lockfile.txt b/Documentation/technical/api-lockfile.txt
index dd89404..8eac22a 100644
--- a/Documentation/technical/api-lockfile.txt
+++ b/Documentation/technical/api-lockfile.txt
@@ -22,6 +22,15 @@ The lockfile API serves two purposes:
The functions
-------------
+alloc_lock_file::
+
+ Allocate and clear a `struct lock_file`. Because the
+ structure is used in an `atexit(3)` handler, its
+ storage has to stay throughout the life of the
+ program. Using this allocation function instead of
+ `malloc` allows profiling tools like valgrind to keep
+ track of such storage and avoid reporting it as a leak.
+
hold_lock_file_for_update::
Take a pointer to `struct lock_file`, the filename of
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 3ab214d..7697631 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -591,9 +591,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
git_config(git_default_config, NULL);
- /* We can't free this memory, it becomes part of a linked list parsed atexit() */
- lock_file = xcalloc(1, sizeof(struct lock_file));
-
+ lock_file = alloc_lock_file();
newfd = hold_locked_index(lock_file, 0);
if (newfd < 0)
lock_error = errno;
diff --git a/cache-tree.c b/cache-tree.c
index f755590..81cf785 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -550,12 +550,7 @@ int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix)
int entries, was_valid, newfd;
struct lock_file *lock_file;
- /*
- * We can't free this memory, it becomes part of a linked list
- * parsed atexit()
- */
- lock_file = xcalloc(1, sizeof(struct lock_file));
-
+ lock_file = alloc_lock_file();
newfd = hold_locked_index(lock_file, 1);
entries = read_cache();
diff --git a/cache.h b/cache.h
index 2ef2fa3..9ee61a2 100644
--- a/cache.h
+++ b/cache.h
@@ -517,6 +517,7 @@ struct lock_file {
#define LOCK_NODEREF 2
extern int unable_to_lock_error(const char *path, int err);
extern NORETURN void unable_to_lock_index_die(const char *path, int err);
+extern struct lock_file *alloc_lock_file(void);
extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);
extern int hold_lock_file_for_append(struct lock_file *, const char *path, int);
extern int commit_lock_file(struct lock_file *);
diff --git a/config.c b/config.c
index 4b0a820..3f30e2b 100644
--- a/config.c
+++ b/config.c
@@ -1158,7 +1158,7 @@ int git_config_set_multivar(const char *key, const char *value,
* The lock serves a purpose in addition to locking: the new
* contents of .git/config will be written into it.
*/
- lock = xcalloc(sizeof(struct lock_file), 1);
+ lock = alloc_lock_file();
fd = hold_lock_file_for_update(lock, config_filename, 0);
if (fd < 0) {
error("could not lock config file %s: %s", config_filename, strerror(errno));
diff --git a/lockfile.c b/lockfile.c
index b0d74cd..161dea8 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -184,6 +184,12 @@ NORETURN void unable_to_lock_index_die(const char *path, int err)
die("%s", unable_to_lock_message(path, err));
}
+__attribute__((optimize("-fno-optimize-sibling-calls")))
+struct lock_file *alloc_lock_file(void)
+{
+ return xcalloc(1, sizeof(struct lock_file));
+}
+
int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
{
int fd = lock_file(lk, path, flags);
diff --git a/t/valgrind/default.supp b/t/valgrind/default.supp
index 9e013fa..7789edd 100644
--- a/t/valgrind/default.supp
+++ b/t/valgrind/default.supp
@@ -43,3 +43,11 @@
fun:write_buffer
fun:write_loose_object
}
+
+{
+ see api-lockfile.txt
+ Memcheck:Leak
+ fun:calloc
+ fun:xcalloc
+ fun:alloc_lock_file
+}
--
1.7.2.3
next prev parent reply other threads:[~2010-10-02 8:35 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-09 9:48 [PATCH] memory leak reported by valgrind Ivan Kanis
2010-08-09 19:37 ` Junio C Hamano
2010-08-09 20:19 ` Erik Faye-Lund
2010-08-09 20:29 ` Alex Riesen
2010-08-10 3:26 ` Jonathan Nieder
2010-08-10 3:28 ` [PATCH/RFC 1/3] core: Stop leaking ondisk_cache_entrys Jonathan Nieder
2010-08-10 3:32 ` [PATCH/RFC 2/3] write-tree: Avoid leak when index refers to an invalid object Jonathan Nieder
2010-08-10 3:33 ` [PATCH/RFC 3/3] read-tree: stop leaking tree objects Jonathan Nieder
2010-10-02 8:27 ` [PATCH/RFC 0/7] Re: [PATCH] memory leak reported by valgrind Jonathan Nieder
2010-10-02 8:31 ` [PATCH 1/7] init: plug tiny one-time memory leak Jonathan Nieder
2010-10-03 23:46 ` Junio C Hamano
2010-10-04 4:34 ` [PATCH v2] " Jonathan Nieder
2010-10-02 8:32 ` Jonathan Nieder [this message]
2010-10-02 16:30 ` [PATCH 2/7] lockfile: introduce alloc_lock_file() to avoid valgrind noise Andreas Ericsson
2010-10-02 16:43 ` Jonathan Nieder
2010-10-06 20:10 ` Junio C Hamano
2010-10-06 20:21 ` Jonathan Nieder
2010-10-06 21:45 ` Junio C Hamano
2010-10-06 22:17 ` Jonathan Nieder
2010-10-02 8:35 ` [PATCH 3/7] environment.c: remove unused variable Jonathan Nieder
2010-10-02 8:36 ` [PATCH 4/7] setup: make sure git dir path is in a permanent buffer Jonathan Nieder
2010-10-04 9:25 ` Nguyen Thai Ngoc Duy
2010-10-02 8:38 ` [PATCH 5/7] Introduce malloc/strdup/pathdup variants for permanent allocations Jonathan Nieder
2010-10-02 8:39 ` [PATCH 6/7] environment: use alloc_permanent() for computed git_dir and co Jonathan Nieder
2010-10-02 8:41 ` [PATCH 7/7] commit-tree: free commit message before exiting Jonathan Nieder
2010-10-02 18:14 ` Sverre Rabbelier
2010-10-02 18:26 ` Jonathan Nieder
2010-10-02 20:12 ` Sverre Rabbelier
2010-10-02 20:50 ` Jonathan Nieder
2010-10-04 0:31 ` Junio C Hamano
2010-10-04 4:18 ` Jonathan Nieder
2010-10-04 7:55 ` Junio C Hamano
2010-10-04 7:56 ` Jonathan Nieder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101002083216.GC29638@burratino \
--to=jrnieder@gmail.com \
--cc=david.barr@cordelta.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=madcoder@debian.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.