Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}
- From
- Eric Wong <normalperson@yhbt.net>
- Date
- Dec 24, 2005, 21:15 UTC
- Message-ID
- <20051224211546.GG3963@mail.yhbt.net>
- In-Reply-To
- <7v3bkis631.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
Show 21 quoted lines
> Eric Wong <normalperson@yhbt.net> writes: > > > dietlibc versions of these allocators returns NULL if a size of zero is > > specified. Obviously, this is a problem with the x* wrappers since > > we check for them returning NULL. > > > > Down the line, it'd be better to hunt down and eliminate all calls to > > these functions when they are called with a zero argument. I've already > > added some checks for these cases that were exposed by tests. > > I agree that it is a bug to rely on *alloc(0) not returning > NULL, but this patch is too risky. It would be a good thing to > have debugging variant of x* wrappers that barf on a 0-byte > allocation request to find the offending callers, instead of > returning NULL, maybe like the attached patch. > > Since eradicating *alloc(0) calls is the right way to go, but it > takes time. Touching x* wrappers for general public should not > be done before it is done. It breaks things for everybody, > while the current code is broken only for diet people and > developers that use the debugging variant of x* wrappers.
I'll be using the following patch to collect results for the next few days without interrupting my work on other projects. I'll post patches to remove *alloc(0) calls when I find them.
diff --git a/git-compat-util.h b/git-compat-util.h index 0c98c99..43be289 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -60,9 +60,41 @@ extern int gitsetenv(const char *, const extern char *gitstrcasestr(const char *haystack, const char *needle); #endif +static void fork_for_core (const char * caller) +{ + pid_t child = fork(); + if (child == 0) { + int i; + char out[4096]; + char * progname = "unknown"; + FILE * dbg = fopen("/var/tmp/git_alloc_dbg.log","a"); + + for(i = 0; environ[i]; i++) { + if (strstr(environ[i],"_=") == environ[i]) + progname = environ[i]; + } + + snprintf(out, 4096, "%s:%s: pid %d dumping core for pid %d\n", + progname, caller, getpid(), getppid()); + + fputs(out, stderr); + fputs(out, dbg); + fflush(NULL); + + abort(); + } +} + static inline void *xmalloc(size_t size) { - void *ret = malloc(size); + void *ret; + + if (!size) { + fork_for_core(__func__); + return NULL; + } + + ret = malloc(size); if (!ret) die("Out of memory, malloc failed"); return ret; @@ -70,7 +102,15 @@ static inline void *xmalloc(size_t size) static inline void *xrealloc(void *ptr, size_t size) { - void *ret = realloc(ptr, size); + void *ret; + + if (!size) { + fork_for_core(__func__); + free(ptr); + return NULL; + } + + ret = realloc(ptr, size); if (!ret) die("Out of memory, realloc failed"); return ret; @@ -78,7 +118,14 @@ static inline void *xrealloc(void *ptr, static inline void *xcalloc(size_t nmemb, size_t size) { - void *ret = calloc(nmemb, size); + void *ret; + + if (!nmemb || !size) { + fork_for_core(__func__); + return NULL; + } + + ret = calloc(nmemb, size); if (!ret) die("Out of memory, calloc failed"); return ret;
-- Eric Wong