diff options
author | Aliaksey Kandratsenka <alk@tut.by> | 2013-09-14 14:38:53 -0700 |
---|---|---|
committer | Aliaksey Kandratsenka <alk@tut.by> | 2013-09-14 17:42:41 -0700 |
commit | 326990b5c30d249c3cf4688a88fc415b05494aca (patch) | |
tree | 99428c07b03ecd6b3b90a40e85b9a85652413571 | |
parent | cb65e49b83c84bc205203c12793f2dd00c4a7721 (diff) | |
download | gperftools-326990b5c30d249c3cf4688a88fc415b05494aca.tar.gz |
issue-557: added support for dumping heap profile via signal
This applies patch from Jean Lee.
I've reformatted it to match surronding code style and changed
validation logic a bit. I.e. we're not checking signal for range
anymore given we're not sure what different platforms support, but
we're checking return value of signal() for SIG_ERR instead.
-rw-r--r-- | src/heap-profiler.cc | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/heap-profiler.cc b/src/heap-profiler.cc index aa95a51..3f06e94 100644 --- a/src/heap-profiler.cc +++ b/src/heap-profiler.cc @@ -51,6 +51,7 @@ #include <errno.h> #include <assert.h> #include <sys/types.h> +#include <signal.h> #include <algorithm> #include <string> @@ -535,6 +536,14 @@ extern "C" void HeapProfilerDump(const char *reason) { } } +// Signal handler that is registered when a user selectable signal +// number is defined in the environment variable HEAPPROFILESIGNAL. +static void HeapProfilerDumpSignal(int signal_number) { + (void)signal_number; + HeapProfilerDump("signal"); +} + + //---------------------------------------------------------------------- // Initialization/finalization code //---------------------------------------------------------------------- @@ -555,6 +564,19 @@ static void HeapProfilerInit() { } #endif + char *signal_number_str = getenv("HEAPPROFILESIGNAL"); + if (signal_number_str != NULL) { + long int signal_number = strtol(signal_number_str, NULL, 10); + intptr_t old_signal_handler = reinterpret_cast<intptr_t>(signal(signal_number, HeapProfilerDumpSignal)); + if (old_signal_handler == reinterpret_cast<intptr_t>(SIG_ERR)) { + RAW_LOG(FATAL, "Failed to set signal. Perhaps signal number %s is invalid\n", signal_number_str); + } else if (old_signal_handler == NULL) { + RAW_LOG(INFO,"Using signal %d as heap profiling switch", signal_number); + } else { + RAW_LOG(FATAL, "Signal %d already in use\n", signal_number); + } + } + HeapProfileTable::CleanupOldProfiles(fname); HeapProfilerStart(fname); |