+
+static void
+trace_run(void)
+{
+#if HAVE_EXECINFO_H
+ if (backtrace_conn && n_traces >= MAX_TRACES) {
+ struct unixctl_conn *reply_conn = backtrace_conn;
+ struct ds ds = DS_EMPTY_INITIALIZER;
+ sigset_t oldsigs;
+ size_t i;
+
+ block_sigalrm(&oldsigs);
+
+ for (i = 0; i < n_traces; i++) {
+ struct trace *trace = &traces[i];
+ char **frame_strs;
+ size_t j;
+
+ frame_strs = backtrace_symbols(trace->backtrace, trace->n_frames);
+
+ ds_put_format(&ds, "Backtrace %zu\n", i + 1);
+ for (j = 0; j < trace->n_frames; j++) {
+ ds_put_format(&ds, "%s\n", frame_strs[j]);
+ }
+ ds_put_cstr(&ds, "\n");
+
+ free(frame_strs);
+ }
+
+ free(traces);
+ traces = NULL;
+ n_traces = 0;
+ backtrace_conn = NULL;
+
+ unblock_sigalrm(&oldsigs);
+
+ unixctl_command_reply(reply_conn, ds_cstr(&ds));
+ ds_destroy(&ds);
+ }
+#endif
+}