Unverified Commit 11945461 by Patrick Steinhardt Committed by GitHub

Merge pull request #4854 from libgit2/ethomson/buf_oom_test

 buf::oom tests: use custom allocator for oom failures
parents 671b2446 2e34efaa
...@@ -364,7 +364,8 @@ typedef enum { ...@@ -364,7 +364,8 @@ typedef enum {
* *
* > Set the memory allocator to a different memory allocator. This * > Set the memory allocator to a different memory allocator. This
* > allocator will then be used to make all memory allocations for * > allocator will then be used to make all memory allocations for
* > libgit2 operations. * > libgit2 operations. If the given `allocator` is NULL, then the
* > system default will be restored.
* *
* opts(GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY, int enabled) * opts(GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY, int enabled)
* *
......
...@@ -15,6 +15,15 @@ ...@@ -15,6 +15,15 @@
git_allocator git__allocator; git_allocator git__allocator;
static int setup_default_allocator(void)
{
#if defined(GIT_MSVC_CRTDBG)
return git_win32_crtdbg_init_allocator(&git__allocator);
#else
return git_stdalloc_init_allocator(&git__allocator);
#endif
}
int git_allocator_global_init(void) int git_allocator_global_init(void)
{ {
/* /*
...@@ -24,15 +33,14 @@ int git_allocator_global_init(void) ...@@ -24,15 +33,14 @@ int git_allocator_global_init(void)
if (git__allocator.gmalloc != NULL) if (git__allocator.gmalloc != NULL)
return 0; return 0;
#if defined(GIT_MSVC_CRTDBG) return setup_default_allocator();
return git_win32_crtdbg_init_allocator(&git__allocator);
#else
return git_stdalloc_init_allocator(&git__allocator);
#endif
} }
int git_allocator_setup(git_allocator *allocator) int git_allocator_setup(git_allocator *allocator)
{ {
if (!allocator)
return setup_default_allocator();
memcpy(&git__allocator, allocator, sizeof(*allocator)); memcpy(&git__allocator, allocator, sizeof(*allocator));
return 0; return 0;
} }
......
#include "clar_libgit2.h" #include "clar_libgit2.h"
#include "buffer.h" #include "buffer.h"
/* /* Override default allocators with ones that will fail predictably. */
* We want to use some ridiculous size that `malloc` will fail with
* but that does not otherwise interfere with testing. On Linux, choose static git_allocator std_alloc;
* a number that is large enough to fail immediately but small enough static git_allocator oom_alloc;
* that valgrind doesn't believe it to erroneously be a negative number.
* On macOS, choose a number that is large enough to fail immediately static void *oom_malloc(size_t n, const char *file, int line)
* without having libc print warnings to stderr. {
*/ /* Reject any allocation of more than 100 bytes */
#if defined(GIT_ARCH_64) && defined(__linux__) return (n > 100) ? NULL : std_alloc.gmalloc(n, file, line);
# define TOOBIG 0x0fffffffffffffff }
#elif defined(GIT_ARCH_64)
# define TOOBIG 0xffffffffffffff00 static void *oom_realloc(void *p, size_t n, const char *file, int line)
#endif {
/* Reject any allocation of more than 100 bytes */
/** return (n > 100) ? NULL : std_alloc.grealloc(p, n, file, line);
* If we make a ridiculously large request the first time we }
* actually allocate some space in the git_buf, the realloc()
* will fail. And because the git_buf_grow() wrapper always void test_buf_oom__initialize(void)
* sets mark_oom, the code in git_buf_try_grow() will free {
* the internal buffer and set it to git_buf__oom. git_stdalloc_init_allocator(&std_alloc);
* git_stdalloc_init_allocator(&oom_alloc);
* We initialized the internal buffer to (the static variable)
* git_buf__initbuf. The purpose of this test is to make sure oom_alloc.gmalloc = oom_malloc;
* that we don't try to free the static buffer. oom_alloc.grealloc = oom_realloc;
*
* Skip this test entirely on 32-bit platforms; a buffer large enough cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ALLOCATOR, &oom_alloc));
* to guarantee malloc failures is so large that valgrind considers }
* it likely to be an error.
*/ void test_buf_oom__cleanup(void)
{
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ALLOCATOR, NULL));
}
void test_buf_oom__grow(void) void test_buf_oom__grow(void)
{ {
#ifdef GIT_ARCH_64
git_buf buf = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT;
git_buf_clear(&buf); cl_git_pass(git_buf_grow(&buf, 42));
cl_assert(!git_buf_oom(&buf));
cl_assert(git_buf_grow(&buf, TOOBIG) == -1); cl_assert(git_buf_grow(&buf, 101) == -1);
cl_assert(git_buf_oom(&buf)); cl_assert(git_buf_oom(&buf));
git_buf_dispose(&buf); git_buf_dispose(&buf);
#else
cl_skip();
#endif
} }
void test_buf_oom__grow_by(void) void test_buf_oom__grow_by(void)
{ {
git_buf buf = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT;
buf.size = SIZE_MAX-10; cl_git_pass(git_buf_grow_by(&buf, 42));
cl_assert(!git_buf_oom(&buf));
cl_assert(git_buf_grow_by(&buf, 50) == -1); cl_assert(git_buf_grow_by(&buf, 101) == -1);
cl_assert(git_buf_oom(&buf)); cl_assert(git_buf_oom(&buf));
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment