Hi!
Could you check if there is some alternative way that doesn't use
system(), syslog() and fgets() from within the signal handler?
regards,
Anders Widell
------------------------------------------------------------------------
*Från:* Ravi Sekhar Reddy Konda <[email protected]>
*Skickat:* den 30 maj 2018 08:10:56
*Till:* Hans Nordebäck; Anders Widell; Gary Lee
*Kopia:* [email protected]
*Ämne:* RE: [PATCH 1/1] base: Improve backtrace print in daemon.c [#2853]
Hi Hans,
Ack, code review only
Regards,
Ravi
-----Original Message-----
From: Hans Nordeback [mailto:[email protected]]
Sent: Wednesday, May 16, 2018 12:54 PM
To: [email protected]; Ravi Sekhar Reddy Konda
<[email protected]>; [email protected]
Cc: [email protected]; Hans Nordeback
<[email protected]>
Subject: [PATCH 1/1] base: Improve backtrace print in daemon.c [#2853]
---
src/base/daemon.c | 52 ++++++++++++++++++++++++++++++---
tools/cluster_sim_uml/build_uml | 1 +
2 files changed, 49 insertions(+), 4 deletions(-)
diff --git a/src/base/daemon.c b/src/base/daemon.c index
361dd8dd6..2ad0dcd2d 100644
--- a/src/base/daemon.c
+++ b/src/base/daemon.c
@@ -608,14 +608,18 @@ static void fatal_signal_handler(int sig,
siginfo_t *siginfo, void *ctx)
const int BT_ARRAY_SIZE = 20;
void *bt_array[BT_ARRAY_SIZE];
size_t bt_size;
- int fd;
char bt_header[40];
+ char cmd_buf[200];
+ char addr2line_buf[120];
+ Dl_info dl_info;
+ FILE *fp;
- if ((fd = open(bt_filename, O_RDWR | O_CREAT, 0644)) < 0) {
+ int fd = open(bt_filename, O_RDWR | O_CREAT, 0644);
+
+ if (fd < 0)
goto done;
- }
- snprintf(bt_header, sizeof(bt_header), "signal: %d pid: %u
uid: %u\n",
+ snprintf(bt_header, sizeof(bt_header), "signal: %d pid: %u uid:
+%u\n\n",
sig, siginfo->si_pid, siginfo->si_uid);
if (write(fd, bt_header, strlen(bt_header)) < 0) { @@ -624,6
+628,45 @@ static void fatal_signal_handler(int sig, siginfo_t
*siginfo, void *ctx)
}
bt_size = plibc_backtrace(bt_array, BT_ARRAY_SIZE);
+
+ if (system("which addr2line") == 0) {
+ for (int i = 0; i < bt_size; ++i) {
+ memset(&dl_info, 0, sizeof(dl_info));
+ dladdr(bt_array[i], &dl_info);
+ ptrdiff_t offset = bt_array[i] -
dl_info.dli_fbase;
+
+ snprintf(cmd_buf, sizeof(cmd_buf),
+ "addr2line %tx -p -f -e %s",
+ offset, dl_info.dli_fname);
+
+ fp = popen(cmd_buf, "r");
+ if (fp == NULL) {
+ syslog(LOG_ERR,
+ "popen failed: %s",
strerror(errno));
+ } else {
+ if (fgets(addr2line_buf,
+ sizeof(addr2line_buf),
+ fp) != NULL) {
+ snprintf(cmd_buf, sizeof(cmd_buf),
+ "# %d %s",
+ i, addr2line_buf);
+ if (write(fd, cmd_buf,
+ strlen(cmd_buf)) < 0) {
+ syslog(LOG_ERR,
+ "write failed: %s",
+ strerror(errno));
+ }
+ }
+ pclose(fp);
+ }
+ }
+ }
+
+ if (write(fd, "\n", 1) < 0) {
+ syslog(LOG_ERR,
+ "write failed: %s", strerror(errno));
+ }
+
plibc_backtrace_symbols_fd(bt_array, bt_size, fd);
close(fd);
@@ -677,6 +720,7 @@ static void install_fatal_signal_handlers(void)
time_string, getpid());
struct sigaction action;
+
memset(&action, 0, sizeof(action));
action.sa_sigaction = fatal_signal_handler;
sigfillset(&action.sa_mask);
diff --git a/tools/cluster_sim_uml/build_uml
b/tools/cluster_sim_uml/build_uml index b9f224360..16d49d03e 100755
--- a/tools/cluster_sim_uml/build_uml
+++ b/tools/cluster_sim_uml/build_uml
@@ -176,6 +176,7 @@ cmd_create_rootfs()
test -e /usr/bin/lsof && install /usr/bin/lsof usr/bin
test -e /bin/pidof && install /bin/pidof usr/bin
test -e /usr/sbin/tcpdump && install /usr/sbin/tcpdump usr/sbin
+ test -e /usr/bin/addr2line && install /usr/bin/addr2line usr/bin
if test -e /usr/bin/gdb; then
install /usr/bin/gdb usr/bin
if test -d /usr/share/gdb; then
--
2.17.0