Merge pull request #6811 from libgit2/ethomson/test_allocator

Introduce a stricter debugging allocator for testing
This commit is contained in:
Edward Thomson
2024-05-16 11:34:07 +01:00
committed by GitHub
9 changed files with 122 additions and 23 deletions

View File

@@ -8,8 +8,9 @@
#include "alloc.h"
#include "runtime.h"
#include "allocators/failalloc.h"
#include "allocators/stdalloc.h"
#include "allocators/debugalloc.h"
#include "allocators/failalloc.h"
#include "allocators/win32_leakcheck.h"
/* Fail any allocation until git_libgit2_init is called. */
@@ -88,6 +89,8 @@ static int setup_default_allocator(void)
{
#if defined(GIT_WIN32_LEAKCHECK)
return git_win32_leakcheck_init_allocator(&git__allocator);
#elif defined(GIT_DEBUG_STRICT_ALLOC)
return git_debugalloc_init_allocator(&git__allocator);
#else
return git_stdalloc_init_allocator(&git__allocator);
#endif

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "debugalloc.h"
static void *debugalloc__malloc(size_t len, const char *file, int line)
{
unsigned char *ptr;
size_t total = len + sizeof(size_t);
GIT_UNUSED(file);
GIT_UNUSED(line);
if (!len || (ptr = malloc(total)) == NULL)
return NULL;
memcpy(ptr, &len, sizeof(size_t));
return ptr + sizeof(size_t);
}
static void *debugalloc__realloc(void *_ptr, size_t len, const char *file, int line)
{
unsigned char *ptr = _ptr, *newptr;
size_t original_len;
size_t total = len + sizeof(size_t);
GIT_UNUSED(file);
GIT_UNUSED(line);
if (!len && !ptr)
return NULL;
if (!len) {
free(ptr - sizeof(size_t));
return NULL;
}
if ((newptr = malloc(total)) == NULL)
return NULL;
if (ptr) {
memcpy(&original_len, ptr - sizeof(size_t), sizeof(size_t));
memcpy(newptr + sizeof(size_t), ptr, min(len, original_len));
memset(ptr - sizeof(size_t), 0xfd, original_len + sizeof(size_t));
free(ptr - sizeof(size_t));
}
memcpy(newptr, &len, sizeof(size_t));
return newptr + sizeof(size_t);
}
static void debugalloc__free(void *_ptr)
{
unsigned char *ptr = _ptr;
if (!ptr)
return;
free(ptr - sizeof(size_t));
}
int git_debugalloc_init_allocator(git_allocator *allocator)
{
allocator->gmalloc = debugalloc__malloc;
allocator->grealloc = debugalloc__realloc;
allocator->gfree = debugalloc__free;
return 0;
}

View File

@@ -0,0 +1,17 @@
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_allocators_debugalloc_h__
#define INCLUDE_allocators_debugalloc_h__
#include "git2_util.h"
#include "alloc.h"
int git_debugalloc_init_allocator(git_allocator *allocator);
#endif

View File

@@ -12,11 +12,6 @@ static void *stdalloc__malloc(size_t len, const char *file, int line)
GIT_UNUSED(file);
GIT_UNUSED(line);
#ifdef GIT_DEBUG_STRICT_ALLOC
if (!len)
return NULL;
#endif
return malloc(len);
}
@@ -25,11 +20,6 @@ static void *stdalloc__realloc(void *ptr, size_t size, const char *file, int lin
GIT_UNUSED(file);
GIT_UNUSED(line);
#ifdef GIT_DEBUG_STRICT_ALLOC
if (!size)
return NULL;
#endif
return realloc(ptr, size);
}

View File

@@ -16,17 +16,35 @@
char *p_realpath(const char *pathname, char *resolved)
{
char *ret;
if ((ret = realpath(pathname, resolved)) == NULL)
char *result;
if ((result = realpath(pathname, resolved)) == NULL)
return NULL;
#ifdef __OpenBSD__
/* The OpenBSD realpath function behaves differently,
* figure out if the file exists */
if (access(ret, F_OK) < 0)
ret = NULL;
if (access(ret, F_OK) < 0) {
if (!resolved)
free(result);
return NULL;
}
#endif
return ret;
/*
* If resolved == NULL, the system has allocated the result
* string. We need to strdup this into _our_ allocator pool
* so that callers can free it with git__free.
*/
if (!resolved) {
char *dup = git__strdup(result);
free(result);
result = dup;
}
return result;
}
#endif

View File

@@ -104,7 +104,5 @@ void cl_alloc_limit(size_t bytes)
void cl_alloc_reset(void)
{
git_allocator stdalloc;
git_stdalloc_init_allocator(&stdalloc);
git_allocator_setup(&stdalloc);
git_allocator_setup(NULL);
}

View File

@@ -1095,7 +1095,7 @@ static void collect_progress(
if (path == NULL)
return;
git_vector_insert(paths, strdup(path));
git_vector_insert(paths, git__strdup(path));
}
void test_checkout_conflict__report_progress(void)

View File

@@ -89,7 +89,7 @@ static void assert_name_is(const char *expected)
if (start)
cl_assert_equal_strn("/", actual + (start - 1), 1);
free(actual);
git__free(actual);
}
static int symlink_or_fake(git_repository *repo, const char *a, const char *b)

View File

@@ -40,10 +40,10 @@ void test_remote_fetch__cleanup(void) {
git_repository_free(repo2);
cl_git_pass(git_futils_rmdir_r(repo1_path, NULL, GIT_RMDIR_REMOVE_FILES));
free(repo1_path);
git__free(repo1_path);
cl_git_pass(git_futils_rmdir_r(repo2_path, NULL, GIT_RMDIR_REMOVE_FILES));
free(repo2_path);
git__free(repo2_path);
}