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

Commit c1341e1

Browse files
committed
Add a log_allocator_stats_on_exit option.
Running some types of executables, you want to get the stats at the end of the run. Therefore, add an option to dump the allocator stats when the program finishes. Add new unit tests to cover this new option. Test: All unit tests pass. Test: Enabled the option, ran getprop and verified that the Test: log contains the allocator stats. Change-Id: I1c9f7d5a1fe374e8cfb6ffc8d1caa59064c5d55e
1 parent d05459d commit c1341e1

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)