aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2017-09-01 11:36:54 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2017-09-05 18:37:25 +0200
commit32fb61f039933a946067cff434e8a3386694a1d4 (patch)
tree69c44be966e1f16ec3bb67ba9a0bd80c07ac1053
parent8f3368daeca3d5c184321e96cba60886bb7fc82f (diff)
sig-monitor: Dump stack atomically
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>
-rw-r--r--src/sig-monitor.c33
-rw-r--r--test/monitoring/monitor-base.css1
-rw-r--r--test/monitoring/monitor.js1
3 files changed, 27 insertions, 8 deletions
diff --git a/src/sig-monitor.c b/src/sig-monitor.c
index fbc5b1fb..a92fc814 100644
--- a/src/sig-monitor.c
+++ b/src/sig-monitor.c
@@ -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) {
diff --git a/test/monitoring/monitor-base.css b/test/monitoring/monitor-base.css
index 63838bcc..2efeaf7f 100644
--- a/test/monitoring/monitor-base.css
+++ b/test/monitoring/monitor-base.css
@@ -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 {
diff --git a/test/monitoring/monitor.js b/test/monitoring/monitor.js
index 22d71824..6ca75cc6 100644
--- a/test/monitoring/monitor.js
+++ b/test/monitoring/monitor.js
@@ -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';