зеркало из https://github.com/microsoft/git.git
wrapper.c: introduce gentle xmallocz that does not die()
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
41ca19b6a6
Коммит
f8bb1d9431
|
@ -593,6 +593,7 @@ extern try_to_free_t set_try_to_free_routine(try_to_free_t);
|
||||||
extern char *xstrdup(const char *str);
|
extern char *xstrdup(const char *str);
|
||||||
extern void *xmalloc(size_t size);
|
extern void *xmalloc(size_t size);
|
||||||
extern void *xmallocz(size_t size);
|
extern void *xmallocz(size_t size);
|
||||||
|
extern void *xmallocz_gently(size_t size);
|
||||||
extern void *xmemdupz(const void *data, size_t len);
|
extern void *xmemdupz(const void *data, size_t len);
|
||||||
extern char *xstrndup(const char *str, size_t len);
|
extern char *xstrndup(const char *str, size_t len);
|
||||||
extern void *xrealloc(void *ptr, size_t size);
|
extern void *xrealloc(void *ptr, size_t size);
|
||||||
|
|
68
wrapper.c
68
wrapper.c
|
@ -9,16 +9,23 @@ static void do_nothing(size_t size)
|
||||||
|
|
||||||
static void (*try_to_free_routine)(size_t size) = do_nothing;
|
static void (*try_to_free_routine)(size_t size) = do_nothing;
|
||||||
|
|
||||||
static void memory_limit_check(size_t size)
|
static int memory_limit_check(size_t size, int gentle)
|
||||||
{
|
{
|
||||||
static int limit = -1;
|
static int limit = -1;
|
||||||
if (limit == -1) {
|
if (limit == -1) {
|
||||||
const char *env = getenv("GIT_ALLOC_LIMIT");
|
const char *env = getenv("GIT_ALLOC_LIMIT");
|
||||||
limit = env ? atoi(env) * 1024 : 0;
|
limit = env ? atoi(env) * 1024 : 0;
|
||||||
}
|
}
|
||||||
if (limit && size > limit)
|
if (limit && size > limit) {
|
||||||
die("attempting to allocate %"PRIuMAX" over limit %d",
|
if (gentle) {
|
||||||
(intmax_t)size, limit);
|
error("attempting to allocate %"PRIuMAX" over limit %d",
|
||||||
|
(intmax_t)size, limit);
|
||||||
|
return -1;
|
||||||
|
} else
|
||||||
|
die("attempting to allocate %"PRIuMAX" over limit %d",
|
||||||
|
(intmax_t)size, limit);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
try_to_free_t set_try_to_free_routine(try_to_free_t routine)
|
try_to_free_t set_try_to_free_routine(try_to_free_t routine)
|
||||||
|
@ -42,11 +49,12 @@ char *xstrdup(const char *str)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *xmalloc(size_t size)
|
static void *do_xmalloc(size_t size, int gentle)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
memory_limit_check(size);
|
if (memory_limit_check(size, gentle))
|
||||||
|
return NULL;
|
||||||
ret = malloc(size);
|
ret = malloc(size);
|
||||||
if (!ret && !size)
|
if (!ret && !size)
|
||||||
ret = malloc(1);
|
ret = malloc(1);
|
||||||
|
@ -55,9 +63,16 @@ void *xmalloc(size_t size)
|
||||||
ret = malloc(size);
|
ret = malloc(size);
|
||||||
if (!ret && !size)
|
if (!ret && !size)
|
||||||
ret = malloc(1);
|
ret = malloc(1);
|
||||||
if (!ret)
|
if (!ret) {
|
||||||
die("Out of memory, malloc failed (tried to allocate %lu bytes)",
|
if (!gentle)
|
||||||
(unsigned long)size);
|
die("Out of memory, malloc failed (tried to allocate %lu bytes)",
|
||||||
|
(unsigned long)size);
|
||||||
|
else {
|
||||||
|
error("Out of memory, malloc failed (tried to allocate %lu bytes)",
|
||||||
|
(unsigned long)size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef XMALLOC_POISON
|
#ifdef XMALLOC_POISON
|
||||||
memset(ret, 0xA5, size);
|
memset(ret, 0xA5, size);
|
||||||
|
@ -65,16 +80,37 @@ void *xmalloc(size_t size)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *xmallocz(size_t size)
|
void *xmalloc(size_t size)
|
||||||
|
{
|
||||||
|
return do_xmalloc(size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *do_xmallocz(size_t size, int gentle)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
if (unsigned_add_overflows(size, 1))
|
if (unsigned_add_overflows(size, 1)) {
|
||||||
die("Data too large to fit into virtual memory space.");
|
if (gentle) {
|
||||||
ret = xmalloc(size + 1);
|
error("Data too large to fit into virtual memory space.");
|
||||||
((char*)ret)[size] = 0;
|
return NULL;
|
||||||
|
} else
|
||||||
|
die("Data too large to fit into virtual memory space.");
|
||||||
|
}
|
||||||
|
ret = do_xmalloc(size + 1, gentle);
|
||||||
|
if (ret)
|
||||||
|
((char*)ret)[size] = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *xmallocz(size_t size)
|
||||||
|
{
|
||||||
|
return do_xmallocz(size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *xmallocz_gently(size_t size)
|
||||||
|
{
|
||||||
|
return do_xmallocz(size, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xmemdupz() allocates (len + 1) bytes of memory, duplicates "len" bytes of
|
* xmemdupz() allocates (len + 1) bytes of memory, duplicates "len" bytes of
|
||||||
* "data" to the allocated memory, zero terminates the allocated memory,
|
* "data" to the allocated memory, zero terminates the allocated memory,
|
||||||
|
@ -96,7 +132,7 @@ void *xrealloc(void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
memory_limit_check(size);
|
memory_limit_check(size, 0);
|
||||||
ret = realloc(ptr, size);
|
ret = realloc(ptr, size);
|
||||||
if (!ret && !size)
|
if (!ret && !size)
|
||||||
ret = realloc(ptr, 1);
|
ret = realloc(ptr, 1);
|
||||||
|
@ -115,7 +151,7 @@ void *xcalloc(size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
memory_limit_check(size * nmemb);
|
memory_limit_check(size * nmemb, 0);
|
||||||
ret = calloc(nmemb, size);
|
ret = calloc(nmemb, size);
|
||||||
if (!ret && (!nmemb || !size))
|
if (!ret && (!nmemb || !size))
|
||||||
ret = calloc(1, 1);
|
ret = calloc(1, 1);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче