sig-monitor: Dump stack atomically
authorJosé Bollo <jose.bollo@iot.bzh>
Fri, 1 Sep 2017 09:36:54 +0000 (11:36 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Tue, 5 Sep 2017 16:37:25 +0000 (18:37 +0200)
Emitting the stack as a single string avoids
its accidental split and is better when receiving
monitoring events.

Change-Id: I74c16f36f026b4af4a42064f694ac1f4a342cc1f
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/sig-monitor.c
test/monitoring/monitor-base.css
test/monitoring/monitor.js

index fbc5b1f..a92fc81 100644 (file)
@@ -18,6 +18,7 @@
 #define _GNU_SOURCE
 
 #include <stdlib.h>
+#include <stdio.h>
 #include <signal.h>
 #include <string.h>
 #include <setjmp.h>
@@ -41,19 +42,35 @@ static _Thread_local timer_t thread_timerid;
 /*
  * Dumps the current stack
  */
-static void dumpstack(int crop)
+static void dumpstack(int crop, int signum)
 {
-       int idx, count;
-       void *addresses[1000];
+       int idx, count, rc;
+       void *addresses[100];
        char **locations;
+       char buffer[8000];
+       size_t pos, length;
 
        count = backtrace(addresses, sizeof addresses / sizeof *addresses);
-       locations = backtrace_symbols(addresses, count);
+       if (count <= crop)
+               crop = 0;
+       count -= crop;
+       locations = backtrace_symbols(&addresses[crop], count);
        if (locations == NULL)
                ERROR("can't get the backtrace (returned %d addresses)", count);
        else {
-               for (idx = crop; idx < count; idx++)
-                       ERROR("[BACKTRACE %d/%d] %s", idx - crop + 1, count - crop, locations[idx]);
+               length = sizeof buffer - 1;
+               pos = 0;
+               idx = 0;
+               while (pos < length && idx < count) {
+                       rc = snprintf(&buffer[pos], length - pos, " [%d/%d] %s\n", idx + 1, count, locations[idx]);
+                       pos += rc >= 0 ? rc : 0;
+                       idx++;
+               }
+               buffer[length] = 0;
+               if (signum)
+                       ERROR("BACKTRACE due to signal %s/%d:\n%s", strsignal(signum), signum, buffer);
+               else
+                       ERROR("BACKTRACE:\n%s", buffer);
                free(locations);
        }
 }
@@ -131,7 +148,7 @@ static void on_signal_terminate (int signum)
 {
        ERROR("Terminating signal %d received: %s", signum, strsignal(signum));
        if (signum == SIGABRT)
-               dumpstack(3);
+               dumpstack(3, signum);
        exit(1);
 }
 
@@ -144,7 +161,7 @@ static void on_signal_error(int signum)
        if (error_handler == NULL && signum == SIG_FOR_TIMER)
                return;
 
-       dumpstack(3);
+       dumpstack(3, signum);
 
        // unlock signal to allow a new signal to come
        if (error_handler != NULL) {
index 63838bc..2efeaf7 100644 (file)
@@ -168,6 +168,7 @@ body.on #params, body.on #connect, body.off #disconnect { display: none; }
 
 .traceevent .content {
        clear: both;
+       overflow-x: auto;
 }
 
 .traceevent, .x-button {
index 22d7182..6ca75cc 100644 (file)
@@ -499,6 +499,7 @@ function obj2html(json) {
                                        cls = 'key';
                                } else {
                                        cls = 'string';
+                                       match = match.replace(/\\n/g, "\\n<br>");
                                }
                        } else if (/true|false/.test(match)) {
                                cls = 'boolean';