Skip to content

Commit 48e6b02

Browse files
committed
alloc: add GIT_DEBUG_STRICT_ALLOC
Add `GIT_DEBUG_STRICT_ALLOC` to help identify problematic callers of allocation code that pass a `0` size to the allocators and then expect a non-`NULL` return. When given a 0-size allocation, `malloc` _may_ return either a `NULL` _or_ a pointer that is not writeable. Most systems return a non-`NULL` pointer; AIX is an outlier. We should be able to cope with this AIXy behavior, so this adds an option to emulate it.
1 parent 6a7f040 commit 48e6b02

File tree

4 files changed

+49
-10
lines changed

4 files changed

+49
-10
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ OPTION(USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF)
4949
OPTION(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)" OFF)
5050
OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF)
5151
OPTION(DEBUG_POOL "Enable debug pool allocator" OFF)
52+
OPTION(DEBUG_STRICT_ALLOC "Enable strict allocator behavior" OFF)
5253
OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF)
5354
OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib. Can be set to one of Bundled(ON)/Chromium. The Chromium option requires a x86_64 processor with SSE4.2 and CLMUL" OFF)
5455
SET(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.")

src/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ IF(DEBUG_POOL)
66
ENDIF()
77
ADD_FEATURE_INFO(debugpool GIT_DEBUG_POOL "debug pool allocator")
88

9+
IF(DEBUG_STRICT_ALLOC)
10+
SET(GIT_DEBUG_STRICT_ALLOC 1)
11+
ENDIF()
12+
ADD_FEATURE_INFO(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators")
13+
914
INCLUDE(PkgBuildConfig)
1015
INCLUDE(SanitizeBool)
1116

src/allocators/stdalloc.c

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,56 @@
99

1010
static void *stdalloc__malloc(size_t len, const char *file, int line)
1111
{
12-
void *ptr = malloc(len);
12+
void *ptr;
1313

1414
GIT_UNUSED(file);
1515
GIT_UNUSED(line);
1616

17-
if (!ptr) git_error_set_oom();
17+
#ifdef GIT_DEBUG_STRICT_ALLOC
18+
if (!len)
19+
return NULL;
20+
#endif
21+
22+
ptr = malloc(len);
23+
24+
if (!ptr)
25+
git_error_set_oom();
26+
1827
return ptr;
1928
}
2029

2130
static void *stdalloc__calloc(size_t nelem, size_t elsize, const char *file, int line)
2231
{
23-
void *ptr = calloc(nelem, elsize);
32+
void *ptr;
2433

2534
GIT_UNUSED(file);
2635
GIT_UNUSED(line);
2736

28-
if (!ptr) git_error_set_oom();
37+
#ifdef GIT_DEBUG_STRICT_ALLOC
38+
if (!elsize)
39+
return NULL;
40+
#endif
41+
42+
ptr = calloc(nelem, elsize);
43+
44+
if (!ptr)
45+
git_error_set_oom();
46+
2947
return ptr;
3048
}
3149

3250
static char *stdalloc__strdup(const char *str, const char *file, int line)
3351
{
34-
char *ptr = strdup(str);
52+
char *ptr;
3553

3654
GIT_UNUSED(file);
3755
GIT_UNUSED(line);
3856

39-
if (!ptr) git_error_set_oom();
57+
ptr = strdup(str);
58+
59+
if (!ptr)
60+
git_error_set_oom();
61+
4062
return ptr;
4163
}
4264

@@ -48,7 +70,7 @@ static char *stdalloc__strndup(const char *str, size_t n, const char *file, int
4870
length = p_strnlen(str, n);
4971

5072
if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
51-
!(ptr = stdalloc__malloc(alloclength, file, line)))
73+
!(ptr = stdalloc__malloc(alloclength, file, line)))
5274
return NULL;
5375

5476
if (length)
@@ -65,7 +87,7 @@ static char *stdalloc__substrdup(const char *start, size_t n, const char *file,
6587
size_t alloclen;
6688

6789
if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
68-
!(ptr = stdalloc__malloc(alloclen, file, line)))
90+
!(ptr = stdalloc__malloc(alloclen, file, line)))
6991
return NULL;
7092

7193
memcpy(ptr, start, n);
@@ -75,12 +97,21 @@ static char *stdalloc__substrdup(const char *start, size_t n, const char *file,
7597

7698
static void *stdalloc__realloc(void *ptr, size_t size, const char *file, int line)
7799
{
78-
void *new_ptr = realloc(ptr, size);
100+
void *new_ptr;
79101

80102
GIT_UNUSED(file);
81103
GIT_UNUSED(line);
82104

83-
if (!new_ptr) git_error_set_oom();
105+
#ifdef GIT_DEBUG_STRICT_ALLOC
106+
if (!size)
107+
return NULL;
108+
#endif
109+
110+
new_ptr = realloc(ptr, size);
111+
112+
if (!new_ptr)
113+
git_error_set_oom();
114+
84115
return new_ptr;
85116
}
86117

src/features.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#define INCLUDE_features_h__
33

44
#cmakedefine GIT_DEBUG_POOL 1
5+
#cmakedefine GIT_DEBUG_STRICT_ALLOC 1
6+
57
#cmakedefine GIT_TRACE 1
68
#cmakedefine GIT_THREADS 1
79
#cmakedefine GIT_WIN32_LEAKCHECK 1

0 commit comments

Comments
 (0)