summaryrefslogtreecommitdiff
path: root/src/libstrongswan/library.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/library.c')
-rw-r--r--src/libstrongswan/library.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c
index e130b93ee..4f79dcc5b 100644
--- a/src/libstrongswan/library.c
+++ b/src/libstrongswan/library.c
@@ -55,6 +55,13 @@ struct private_library_t {
*/
bool integrity_failed;
+#ifdef LEAK_DETECTIVE
+ /**
+ * Where to write leak detective output to
+ */
+ FILE *ld_out;
+#endif
+
/**
* Number of times we have been initialized
*/
@@ -95,32 +102,34 @@ library_t *lib = NULL;
/**
* Default leak report callback
*/
-static void report_leaks(void *user, int count, size_t bytes,
- backtrace_t *bt, bool detailed)
+CALLBACK(report_leaks, void,
+ private_library_t *this, int count, size_t bytes, backtrace_t *bt,
+ bool detailed)
{
- fprintf(stderr, "%zu bytes total, %d allocations, %zu bytes average:\n",
+ fprintf(this->ld_out, "%zu bytes total, %d allocations, %zu bytes average:\n",
bytes, count, bytes / count);
- bt->log(bt, stderr, detailed);
+ bt->log(bt, this->ld_out, detailed);
}
/**
* Default leak report summary callback
*/
-static void sum_leaks(void* user, int count, size_t bytes, int whitelisted)
+CALLBACK(sum_leaks, void,
+ private_library_t *this, int count, size_t bytes, int whitelisted)
{
switch (count)
{
case 0:
- fprintf(stderr, "No leaks detected");
+ fprintf(this->ld_out, "No leaks detected");
break;
case 1:
- fprintf(stderr, "One leak detected");
+ fprintf(this->ld_out, "One leak detected");
break;
default:
- fprintf(stderr, "%d leaks detected, %zu bytes", count, bytes);
+ fprintf(this->ld_out, "%d leaks detected, %zu bytes", count, bytes);
break;
}
- fprintf(stderr, ", %d suppressed by whitelist\n", whitelisted);
+ fprintf(this->ld_out, ", %d suppressed by whitelist\n", whitelisted);
}
#endif /* LEAK_DETECTIVE */
@@ -172,6 +181,12 @@ void library_deinit()
lib->leak_detective->destroy(lib->leak_detective);
lib->leak_detective = NULL;
}
+#ifdef LEAK_DETECTIVE
+ if (this->ld_out && this->ld_out != stderr)
+ {
+ fclose(this->ld_out);
+ }
+#endif /* LEAK_DETECTIVE */
backtrace_deinit();
arrays_deinit();
@@ -301,11 +316,22 @@ bool library_init(char *settings, const char *namespace)
backtrace_init();
#ifdef LEAK_DETECTIVE
+ {
+ FILE *out = NULL;
+ char *log;
+
+ log = getenv("LEAK_DETECTIVE_LOG");
+ if (log)
+ {
+ out = fopen(log, "a");
+ }
+ this->ld_out = out ?: stderr;
+ }
lib->leak_detective = leak_detective_create();
if (lib->leak_detective)
{
lib->leak_detective->set_report_cb(lib->leak_detective,
- report_leaks, sum_leaks, NULL);
+ report_leaks, sum_leaks, this);
}
#endif /* LEAK_DETECTIVE */