mirror of
https://github.com/libgit2/libgit2.git
synced 2026-01-25 02:56:17 +00:00
Merge pull request #6811 from libgit2/ethomson/test_allocator
Introduce a stricter debugging allocator for testing
This commit is contained in:
@@ -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
|
||||
|
||||
73
src/util/allocators/debugalloc.c
Normal file
73
src/util/allocators/debugalloc.c
Normal 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;
|
||||
}
|
||||
17
src/util/allocators/debugalloc.h
Normal file
17
src/util/allocators/debugalloc.h
Normal 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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user