buf::oom tests: use custom allocator for oom failures#4854
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`.)
pks-t
left a comment
There was a problem hiding this comment.
Thanks for working on my proposal! This is great, the proposed changes are something nice to have in the future only.
| * > 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. |
| { | ||
| /* 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.
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::oomtests 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/reallocwould returnNULL(instead of aborting the application, or appearing suspicious to various instrumentation or static code analysis tools like valgrind.)Introduce a fake
mallocandreallocthat will returnNULLon 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.)