leak-detective: Optionally write report to a log file
This commit is contained in:
+36
-10
@@ -55,6 +55,13 @@ struct private_library_t {
|
|||||||
*/
|
*/
|
||||||
bool integrity_failed;
|
bool integrity_failed;
|
||||||
|
|
||||||
|
#ifdef LEAK_DETECTIVE
|
||||||
|
/**
|
||||||
|
* Where to write leak detective output to
|
||||||
|
*/
|
||||||
|
FILE *ld_out;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of times we have been initialized
|
* Number of times we have been initialized
|
||||||
*/
|
*/
|
||||||
@@ -95,32 +102,34 @@ library_t *lib = NULL;
|
|||||||
/**
|
/**
|
||||||
* Default leak report callback
|
* Default leak report callback
|
||||||
*/
|
*/
|
||||||
static void report_leaks(void *user, int count, size_t bytes,
|
CALLBACK(report_leaks, void,
|
||||||
backtrace_t *bt, bool detailed)
|
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);
|
bytes, count, bytes / count);
|
||||||
bt->log(bt, stderr, detailed);
|
bt->log(bt, this->ld_out, detailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default leak report summary callback
|
* 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)
|
switch (count)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
fprintf(stderr, "No leaks detected");
|
fprintf(this->ld_out, "No leaks detected");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
fprintf(stderr, "One leak detected");
|
fprintf(this->ld_out, "One leak detected");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%d leaks detected, %zu bytes", count, bytes);
|
fprintf(this->ld_out, "%d leaks detected, %zu bytes", count, bytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(stderr, ", %d suppressed by whitelist\n", whitelisted);
|
fprintf(this->ld_out, ", %d suppressed by whitelist\n", whitelisted);
|
||||||
}
|
}
|
||||||
#endif /* LEAK_DETECTIVE */
|
#endif /* LEAK_DETECTIVE */
|
||||||
|
|
||||||
@@ -166,12 +175,18 @@ void library_deinit()
|
|||||||
this->public.integrity->destroy(this->public.integrity);
|
this->public.integrity->destroy(this->public.integrity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LEAK_DETECTIVE
|
||||||
if (lib->leak_detective)
|
if (lib->leak_detective)
|
||||||
{
|
{
|
||||||
lib->leak_detective->report(lib->leak_detective, detailed);
|
lib->leak_detective->report(lib->leak_detective, detailed);
|
||||||
lib->leak_detective->destroy(lib->leak_detective);
|
lib->leak_detective->destroy(lib->leak_detective);
|
||||||
lib->leak_detective = NULL;
|
lib->leak_detective = NULL;
|
||||||
}
|
}
|
||||||
|
if (this->ld_out && this->ld_out != stderr)
|
||||||
|
{
|
||||||
|
fclose(this->ld_out);
|
||||||
|
}
|
||||||
|
#endif /* LEAK_DETECTIVE */
|
||||||
|
|
||||||
backtrace_deinit();
|
backtrace_deinit();
|
||||||
arrays_deinit();
|
arrays_deinit();
|
||||||
@@ -301,11 +316,22 @@ bool library_init(char *settings, const char *namespace)
|
|||||||
backtrace_init();
|
backtrace_init();
|
||||||
|
|
||||||
#ifdef LEAK_DETECTIVE
|
#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();
|
lib->leak_detective = leak_detective_create();
|
||||||
if (lib->leak_detective)
|
if (lib->leak_detective)
|
||||||
{
|
{
|
||||||
lib->leak_detective->set_report_cb(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 */
|
#endif /* LEAK_DETECTIVE */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user