Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 5530c8e

Browse files
cferris1000Gerrit Code Review
authored andcommitted
Merge "Add a log_allocator_stats_on_exit option." into main
2 parents df5527f + c1341e1 commit 5530c8e

File tree

7 files changed

+57
-5
lines changed

7 files changed

+57
-5
lines changed

libc/malloc_debug/Config.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ const std::unordered_map<std::string, Config::OptionInfo> Config::kOptions = {
212212
"log_allocator_stats_on_signal",
213213
{LOG_ALLOCATOR_STATS_ON_SIGNAL, &Config::VerifyValueEmpty},
214214
},
215+
{
216+
"log_allocator_stats_on_exit",
217+
{LOG_ALLOCATOR_STATS_ON_EXIT, &Config::VerifyValueEmpty},
218+
},
215219
};
216220

217221
bool Config::ParseValue(const std::string& option, const std::string& value, size_t min_value,

libc/malloc_debug/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ constexpr uint64_t VERBOSE = 0x1000;
4949
constexpr uint64_t CHECK_UNREACHABLE_ON_SIGNAL = 0x2000;
5050
constexpr uint64_t BACKTRACE_SPECIFIC_SIZES = 0x4000;
5151
constexpr uint64_t LOG_ALLOCATOR_STATS_ON_SIGNAL = 0x8000;
52+
constexpr uint64_t LOG_ALLOCATOR_STATS_ON_EXIT = 0x10000;
5253

5354
// In order to guarantee posix compliance, set the minimum alignment
5455
// to 8 bytes for 32 bit systems and 16 bytes for 64 bit systems.

libc/malloc_debug/LogAllocatorStats.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,17 @@ static void CallMalloptLogStats(int, struct siginfo*, void*) {
4343
g_call_mallopt = true;
4444
}
4545

46+
void Log() {
47+
info_log("Logging allocator stats...");
48+
if (mallopt(M_LOG_STATS, 0) == 0) {
49+
error_log("mallopt(M_LOG_STATS, 0) call failed.");
50+
}
51+
}
52+
4653
void CheckIfShouldLog() {
4754
bool expected = true;
4855
if (g_call_mallopt.compare_exchange_strong(expected, false)) {
49-
info_log("Logging allocator stats...");
50-
if (mallopt(M_LOG_STATS, 0) == 0) {
51-
error_log("mallopt(M_LOG_STATS, 0) call failed.");
52-
}
56+
Log();
5357
}
5458
}
5559

libc/malloc_debug/LogAllocatorStats.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ namespace LogAllocatorStats {
3535

3636
bool Initialize(const Config& config);
3737

38+
void Log();
39+
3840
void CheckIfShouldLog();
3941

4042
} // namespace LogAllocatorStats

libc/malloc_debug/malloc_debug.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,10 @@ void debug_finalize() {
461461
getpid()).c_str());
462462
}
463463

464+
if (g_debug->config().options() & LOG_ALLOCATOR_STATS_ON_EXIT) {
465+
LogAllocatorStats::Log();
466+
}
467+
464468
backtrace_shutdown();
465469

466470
// In order to prevent any issues of threads freeing previous pointers

libc/malloc_debug/tests/malloc_debug_config_tests.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,24 @@ TEST_F(MallocDebugConfigTest, trigger_log_allocator_stats_on_signal_fail) {
861861
ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
862862
}
863863

864+
TEST_F(MallocDebugConfigTest, log_allocator_stats_on_exit) {
865+
ASSERT_TRUE(InitConfig("log_allocator_stats_on_exit")) << getFakeLogPrint();
866+
ASSERT_EQ(LOG_ALLOCATOR_STATS_ON_EXIT, config->options());
867+
868+
ASSERT_STREQ("", getFakeLogBuf().c_str());
869+
ASSERT_STREQ("", getFakeLogPrint().c_str());
870+
}
871+
872+
TEST_F(MallocDebugConfigTest, trigger_log_allocator_stats_on_exit_fail) {
873+
ASSERT_FALSE(InitConfig("log_allocator_stats_on_exit=200")) << getFakeLogPrint();
874+
875+
ASSERT_STREQ("", getFakeLogBuf().c_str());
876+
std::string log_msg(
877+
"6 malloc_debug malloc_testing: value set for option 'log_allocator_stats_on_exit' "
878+
"which does not take a value\n");
879+
ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
880+
}
881+
864882
TEST_F(MallocDebugConfigTest, size) {
865883
ASSERT_TRUE(InitConfig("backtrace_size=37")) << getFakeLogPrint();
866884
ASSERT_EQ(BACKTRACE_SPECIFIC_SIZES, config->options());

libc/malloc_debug/tests/malloc_debug_unit_tests.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ TEST_F(MallocDebugTest, all_options) {
426426
Init(
427427
"guard backtrace backtrace_enable_on_signal fill expand_alloc free_track leak_track "
428428
"record_allocs verify_pointers abort_on_error verbose check_unreachable_on_signal "
429-
"log_allocator_stats_on_signal");
429+
"log_allocator_stats_on_signal log_allocator_stats_on_exit");
430430
VerifyAllocCalls(true);
431431
}
432432

@@ -2844,6 +2844,25 @@ TEST_F(MallocDebugTest, log_allocator_stats_on_signal) {
28442844
}
28452845
}
28462846

2847+
TEST_F(MallocDebugTest, log_allocator_stats_on_exit) {
2848+
Init("log_allocator_stats_on_exit");
2849+
2850+
void* pointer = debug_malloc(110);
2851+
ASSERT_TRUE(pointer != nullptr);
2852+
debug_free(pointer);
2853+
2854+
debug_finalize();
2855+
2856+
ASSERT_STREQ("", getFakeLogBuf().c_str());
2857+
if (!running_with_hwasan()) {
2858+
// Do an exact match because the mallopt should not fail in normal operation.
2859+
ASSERT_STREQ("4 malloc_debug Logging allocator stats...\n", getFakeLogPrint().c_str());
2860+
} else {
2861+
// mallopt fails with hwasan, so just verify that the message is present.
2862+
ASSERT_MATCH(getFakeLogPrint(), "4 malloc_debug Logging allocator stats...\\n");
2863+
}
2864+
}
2865+
28472866
TEST_F(MallocDebugTest, backtrace_only_some_sizes_with_backtrace_size) {
28482867
Init("leak_track backtrace backtrace_size=120");
28492868

0 commit comments

Comments
 (0)