Replace libc APIs with user-defined functions.
libc_replacer
enables developers to replace standard libc APIs with user-defined functions, providing greater control over non-deterministic behaviors in applications.
By substituting libc APIs with mock implementations, libc_replacer
allows for more predictable and isolated testing environments. Supported libc APIs include:
To use libc_replacer
, ensure your C/C++ toolchain meets the following requirements:
- C11 support
- Full static linking: All libraries must be statically linked to the application.
- Symbol wrapping support: Your linker must support symbol wrapping (e.g.,
--wrap
in GNU ld).
Although libc_replacer
can be used without Bazel, it is designed to integrate easily with it and includes dedicated Bazel rules to simplify usage. Bazel is therefore recommended for building and testing.
Headers for each target libc API are located under libc_replacer/cc/{target}.h
. The library provides two main functions for each API:
libc_replacer_overwrite_{target}
: Overwrites the original libc function call with a specified function pointer, returning void.libc_replacer_reset_{target}
: Restores the original libc function, returning void.
For usage examples, refer to the integration tests.
#include <libc_replacer/cc/malloc.h>
#include <stdlib.h>
static void *mock_malloc(size_t size) {
(void)size;
return NULL; // Always returns `NULL` to simulate allocation failure
}
int main(void) {
libc_replacer_overwrite_malloc(mock_malloc);
const size_t size_arg = 4;
// `malloc` is now replaced by `mock_malloc`,
// so `got` will always be `NULL` without heap allocation.
const void *const got = malloc(size_arg);
libc_replacer_reset_malloc();
// After reset, `malloc` behaves normally again.
void *const got_after_reset = malloc(size_arg);
free(got_after_reset);
}
Load libc_replacer
from the Bazel Central Registry to use it as a Bazel module.
The module provides cc_libc_replacer_binary
and cc_libc_replacer_test
, which are similar to cc_binary
and cc_test
, with one additional required parameter: libs_to_replace
. This parameter, a list of strings, specifies the names of libc APIs to replace.
load(
"@libc_replacer//:cc.bzl",
"cc_libc_replacer_binary",
"cc_libc_replacer_test",
)
# Define a binary target that replaces `malloc` with a user-defined function.
cc_libc_replacer_binary(
name = "your_binary",
srcs = ["your_binary_code.c"],
libs_to_replace = ["malloc"], # Required: List of libc APIs to replace
)
# Define a test target that replaces `time` with a user-defined function.
cc_libc_replacer_test(
name = "your_test",
timeout = "short",
srcs = ["your_test_code.c"],
libs_to_replace = ["time"], # Required: List of libc APIs to replace
)
Pull requests and issues are welcome! See DEVEL.md for development documentation.