123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- #include "test/jemalloc_test.h"
- const char *dump_filename = "/dev/null";
- prof_backtrace_hook_t default_hook;
- bool mock_bt_hook_called = false;
- bool mock_dump_hook_called = false;
- void
- mock_bt_hook(void **vec, unsigned *len, unsigned max_len) {
- *len = max_len;
- for (unsigned i = 0; i < max_len; ++i) {
- vec[i] = (void *)((uintptr_t)i);
- }
- mock_bt_hook_called = true;
- }
- void
- mock_bt_augmenting_hook(void **vec, unsigned *len, unsigned max_len) {
- default_hook(vec, len, max_len);
- expect_u_gt(*len, 0, "Default backtrace hook returned empty backtrace");
- expect_u_lt(*len, max_len,
- "Default backtrace hook returned too large backtrace");
- /* Add a separator between default frames and augmented */
- vec[*len] = (void *)0x030303030;
- (*len)++;
- /* Add more stack frames */
- for (unsigned i = 0; i < 3; ++i) {
- if (*len == max_len) {
- break;
- }
- vec[*len] = (void *)((uintptr_t)i);
- (*len)++;
- }
- mock_bt_hook_called = true;
- }
- void
- mock_dump_hook(const char *filename) {
- mock_dump_hook_called = true;
- expect_str_eq(filename, dump_filename,
- "Incorrect file name passed to the dump hook");
- }
- TEST_BEGIN(test_prof_backtrace_hook_replace) {
- test_skip_if(!config_prof);
- mock_bt_hook_called = false;
- void *p0 = mallocx(1, 0);
- assert_ptr_not_null(p0, "Failed to allocate");
- expect_false(mock_bt_hook_called, "Called mock hook before it's set");
- prof_backtrace_hook_t null_hook = NULL;
- expect_d_eq(mallctl("experimental.hooks.prof_backtrace",
- NULL, 0, (void *)&null_hook, sizeof(null_hook)),
- EINVAL, "Incorrectly allowed NULL backtrace hook");
- size_t default_hook_sz = sizeof(prof_backtrace_hook_t);
- prof_backtrace_hook_t hook = &mock_bt_hook;
- expect_d_eq(mallctl("experimental.hooks.prof_backtrace",
- (void *)&default_hook, &default_hook_sz, (void *)&hook,
- sizeof(hook)), 0, "Unexpected mallctl failure setting hook");
- void *p1 = mallocx(1, 0);
- assert_ptr_not_null(p1, "Failed to allocate");
- expect_true(mock_bt_hook_called, "Didn't call mock hook");
- prof_backtrace_hook_t current_hook;
- size_t current_hook_sz = sizeof(prof_backtrace_hook_t);
- expect_d_eq(mallctl("experimental.hooks.prof_backtrace",
- (void *)¤t_hook, ¤t_hook_sz, (void *)&default_hook,
- sizeof(default_hook)), 0,
- "Unexpected mallctl failure resetting hook to default");
- expect_ptr_eq(current_hook, hook,
- "Hook returned by mallctl is not equal to mock hook");
- dallocx(p1, 0);
- dallocx(p0, 0);
- }
- TEST_END
- TEST_BEGIN(test_prof_backtrace_hook_augment) {
- test_skip_if(!config_prof);
- mock_bt_hook_called = false;
- void *p0 = mallocx(1, 0);
- assert_ptr_not_null(p0, "Failed to allocate");
- expect_false(mock_bt_hook_called, "Called mock hook before it's set");
- size_t default_hook_sz = sizeof(prof_backtrace_hook_t);
- prof_backtrace_hook_t hook = &mock_bt_augmenting_hook;
- expect_d_eq(mallctl("experimental.hooks.prof_backtrace",
- (void *)&default_hook, &default_hook_sz, (void *)&hook,
- sizeof(hook)), 0, "Unexpected mallctl failure setting hook");
- void *p1 = mallocx(1, 0);
- assert_ptr_not_null(p1, "Failed to allocate");
- expect_true(mock_bt_hook_called, "Didn't call mock hook");
- prof_backtrace_hook_t current_hook;
- size_t current_hook_sz = sizeof(prof_backtrace_hook_t);
- expect_d_eq(mallctl("experimental.hooks.prof_backtrace",
- (void *)¤t_hook, ¤t_hook_sz, (void *)&default_hook,
- sizeof(default_hook)), 0,
- "Unexpected mallctl failure resetting hook to default");
- expect_ptr_eq(current_hook, hook,
- "Hook returned by mallctl is not equal to mock hook");
- dallocx(p1, 0);
- dallocx(p0, 0);
- }
- TEST_END
- TEST_BEGIN(test_prof_dump_hook) {
- test_skip_if(!config_prof);
- mock_dump_hook_called = false;
- expect_d_eq(mallctl("prof.dump", NULL, NULL, (void *)&dump_filename,
- sizeof(dump_filename)), 0, "Failed to dump heap profile");
- expect_false(mock_dump_hook_called, "Called dump hook before it's set");
- size_t default_hook_sz = sizeof(prof_dump_hook_t);
- prof_dump_hook_t hook = &mock_dump_hook;
- expect_d_eq(mallctl("experimental.hooks.prof_dump",
- (void *)&default_hook, &default_hook_sz, (void *)&hook,
- sizeof(hook)), 0, "Unexpected mallctl failure setting hook");
- expect_d_eq(mallctl("prof.dump", NULL, NULL, (void *)&dump_filename,
- sizeof(dump_filename)), 0, "Failed to dump heap profile");
- expect_true(mock_dump_hook_called, "Didn't call mock hook");
- prof_dump_hook_t current_hook;
- size_t current_hook_sz = sizeof(prof_dump_hook_t);
- expect_d_eq(mallctl("experimental.hooks.prof_dump",
- (void *)¤t_hook, ¤t_hook_sz, (void *)&default_hook,
- sizeof(default_hook)), 0,
- "Unexpected mallctl failure resetting hook to default");
- expect_ptr_eq(current_hook, hook,
- "Hook returned by mallctl is not equal to mock hook");
- }
- TEST_END
- int
- main(void) {
- return test(
- test_prof_backtrace_hook_replace,
- test_prof_backtrace_hook_augment,
- test_prof_dump_hook);
- }
|