diff --git a/README.md b/README.md index 3f8c0b1..fe5cce8 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,14 @@ function. For doing so, they must include the `huapi.h` public header file, link with the Heapusage shared library itself and call `hu_report()` when wanted. Still, this only works if the program is running through the `heapusage` tool. +Alternatively, on Linux, sending a `SIGUSR1` signal to the program being run +through Heapusage will also produce a Heapusage report on demand. + +For both `hu_report()` and `SIGUSR1`, it should be noted that the report will +reflect the state when they are used, which can e.g. report non-freed memory +that might be still released before the program exits and, therefore, not +necessarily constitute a memory leak. + Output Format ============= Example output: diff --git a/src/humain.cpp b/src/humain.cpp index 428a5eb..d0589c2 100644 --- a/src/humain.cpp +++ b/src/humain.cpp @@ -91,6 +91,34 @@ static inline bool hu_get_env_bool(const char* name) return (strcmp(value, "1") == 0); } +#if defined(__linux__) +static void hu_sigusr_handler(int sig) +{ + switch (sig) { + case SIGUSR1: + log_message("Caught User Signal: SIGUSR1 (%d): Request Log Summary\n", sig); + log_summary_safe(); + break; + default: + log_message("Caught User Signal: Unexpected Signal (%d): Ignore\n", sig); + break; + } +} +#endif + +static void hu_sigusr_init(void) +{ +#if defined(__linux__) + struct sigaction sa; + + sa.sa_handler = hu_sigusr_handler; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(SIGUSR1, &sa, NULL); + sigaction(SIGUSR2, &sa, NULL); +#endif +} + /* ----------- Global Functions ---------------------------------- */ extern "C" @@ -116,6 +144,8 @@ void __attribute__ ((constructor)) hu_init(void) hu_malloc_init(hu_overflow, hu_useafterfree, hu_minsize); } + hu_sigusr_init(); + /* Do not enable preload for child processes */ unsetenv("DYLD_INSERT_LIBRARIES"); unsetenv("LD_PRELOAD");