-
Notifications
You must be signed in to change notification settings - Fork 2.5k
buf::oom tests: use custom allocator for oom failures #4854
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Provide a utility to reset custom allocators back to their default. This is particularly useful for testing.
Create a custom allocator for the `buf::oom` tests that will fail with out-of-memory errors in predictable ways. We were previously trying to guess the way that various allocators on various platforms would fail in a way such that `malloc`/`realloc` would return `NULL` (instead of aborting the application, or appearing suspicious to various instrumentation or static code analysis tools like valgrind.) Introduce a fake `malloc` and `realloc` that will return `NULL` on allocations requesting more than 100 bytes. Otherwise, we proxy to the default allocator. (It's important to use the _default_ allocator, not just call `malloc`, since the default allocator on Windows CI builds may be the debugging C runtime allocators which would not be compatible with a standard `malloc`.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on my proposal! This is great, the proposed changes are something nice to have in the future only.
@@ -364,7 +364,8 @@ typedef enum { | |||
* | |||
* > Set the memory allocator to a different memory allocator. This | |||
* > 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me
{ | ||
/* Reject any allocation of more than 100 bytes */ | ||
return (n > 100) ? NULL : std_alloc.grealloc(p, n, file, line); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really cool. We might think about extending this OOM allocator to a more general helper that fails on either allocating more than n
bytes in one allocation or if all allocations in total surpass m
bytes. So something like git_oomalloc_init_allocator(git_allocator *a, size_t max_allocation, size_t max_total)
. With such a utility we could easily test our code in various OOM scenarios.
One issue though with the current API is that custom allocators cannot store private data anywhere. Neither is there a field in the git_allocator
structure that allows one to store a payload nor can users declare a "parent" structure that contains the allocator as its first field, as we do not store the global allocator as a pointer.
From these options, I'd definitely prefer having a payload pointer in the allocator structure. Making git__allocator
a pointer creates another indirection to the function pointers that may decrease performance in allocation-heavy code
Create a custom allocator for the
buf::oom
tests that will fail with out-of-memory errors in predictable ways. We were previously trying to guess the way that various allocators on various platforms would fail in a way such thatmalloc
/realloc
would returnNULL
(instead of aborting the application, or appearing suspicious to various instrumentation or static code analysis tools like valgrind.)Introduce a fake
malloc
andrealloc
that will returnNULL
on allocations requesting more than 100 bytes. Otherwise, we proxy to the default allocator. (It's important to use the default allocator, not just callmalloc
, since the default allocator on Windows CI builds may be the debugging C runtime allocators which would not be compatible with a standardmalloc
.)