Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

ethomson
Copy link
Member

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.)

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`.)
Copy link
Member

@pks-t pks-t left a 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.
Copy link
Member

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);
}
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants