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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).