mirror of
https://github.com/libgit2/libgit2.git
synced 2026-01-25 02:56:17 +00:00
alloc: introduce debug allocators
Instead of tweaking the `stdalloc` allocator when `GIT_DEBUG_STRICT_ALLOC` is defined, actually create a debugging allocator. This allows us to ensure that we are strict about things like not expecting `malloc(0)` to do something useful, but we can also introduce an excessively pedantic `realloc` implementation that _always_ creates a new buffer, throws away its original `ptr`, and overwrites the data that's there with garbage. This may be helpful to identify places that make assumptions about realloc.
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
|
||||
|
||||
71
src/util/allocators/debugalloc.c
Normal file
71
src/util/allocators/debugalloc.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
void *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)
|
||||
{
|
||||
void *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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user