int fr_set_dumpable_init(void);
int fr_set_dumpable(bool allow_core_dumps);
+int fr_log_talloc_report(TALLOC_CTX *ctx, int fd);
void fr_fault(int sig);
int fr_fault_setup(char const *cmd, char const *program);
void fr_fault_set_cb(fr_fault_cb cb);
char const *fmt, size_t indent, char const *error);
void log_talloc(char const *message);
-void log_talloc_report(TALLOC_CTX *ctx);
/*
* Multiple threads logging to one or more files.
return 0;
}
+/** Generate a talloc memory report for a context and print to stderr/stdout
+ *
+ * @param ctx to generate a report for, may be NULL in which case the root context is used.
+ */
+int fr_log_talloc_report(TALLOC_CTX *ctx, int fd)
+{
+ FILE *handle;
+ char const *null_ctx = NULL;
+ int i = 0;
+
+ handle = fdopen(fd, "w");
+ if (!handle) {
+ fr_strerror_printf("Couldn't write memory report, fdopen failed: %s", fr_syserror(errno));
+
+ return -1;
+ }
+
+ if (ctx) {
+ null_ctx = talloc_get_name(NULL);
+ }
+
+ if (!ctx) {
+ talloc_report_full(NULL, handle);
+ } else do {
+ fprintf(handle, "Context level %i", i++);
+
+ talloc_report_full(ctx, handle);
+ } while ((ctx = talloc_parent(ctx)) && (talloc_get_name(ctx) != null_ctx)); /* Stop before we hit NULL ctx */
+
+ fclose(handle);
+
+ return 0;
+}
+
+/** Signal handler to print out a talloc memory report
+ *
+ * @param sig caught
+ */
+static void fr_fault_memory_report(int sig)
+{
+ fprintf(stderr, "CAUGHT SIGNAL: %s\n", strsignal(sig));
+
+ fr_log_talloc_report(NULL, STDERR_FILENO);
+}
+
/** Check to see if panic_action file is world writeable
*
* @return 0 if file is OK, else -1.
if (sig == SIGUSR1) return;
#endif
-#ifdef SIGUSR2
- if (sig == SIGUSR2) return;
-#endif
fr_exit_now(1);
}
#endif
#ifdef SIGUSR2
- if (fr_set_signal(SIGUSR2, fr_fault) < 0) return -1;
+ if (fr_set_signal(SIGUSR2, fr_fault_memory_report) < 0) return -1;
#endif
}
setup = true;
INFO("%s", msg);
}
-void log_talloc_report(TALLOC_CTX *ctx)
-{
- FILE *fd;
- char const *null_ctx = NULL;
- int i = 0;
-
- if (ctx) {
- null_ctx = talloc_get_name(NULL);
- }
-
- fd = fdopen(default_log.fd, "w");
- if (!fd) {
- ERROR("Couldn't write memory report, fdopen failed: %s", fr_syserror(errno));
-
- return;
- }
-
- if (!ctx) {
- talloc_report_full(NULL, fd);
- } else {
- do {
- INFO("Context level %i", i++);
-
- talloc_report_full(ctx, fd);
- } while ((ctx = talloc_parent(ctx)) && (talloc_get_name(ctx) != null_ctx)); /* Stop before we hit NULL ctx */
- }
-
- fclose(fd);
-}
-
typedef struct fr_logfile_entry_t {
int fd;
int dup;
if (report) {
dict_free();
- log_talloc_report(NULL);
+ fr_log_talloc_report(NULL, default_log.fd);
}
return 0;
if (mainconfig.memory_report) {
INFO("Allocated memory at time of report:");
- log_talloc_report(NULL);
+ fr_log_talloc_report(NULL, default_log.fd);
}
return rcode;
if (!talloc_get_type(vp, VALUE_PAIR)) {
ERROR("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp));
- log_talloc_report(vp);
+ fr_log_talloc_report(vp, default_log.fd);
rad_assert(0);
}
if (!talloc_get_type(vp, VALUE_PAIR)) {
ERROR("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp));
- log_talloc_report(vp);
+ fr_log_talloc_report(vp, default_log.fd);
rad_assert(0);
}
if (memory_report) {
INFO("Allocated memory at time of report:");
- log_talloc_report(NULL);
+ fr_log_talloc_report(NULL, default_log.fd);
}
return rcode;
if (!talloc_get_type(vp, VALUE_PAIR)) {
REDEBUG("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp));
- log_talloc_report(vp);
+ fr_log_talloc_report(vp, default_log.fd);
rad_assert(0);
}