fixes #730 nn_assert could print a backtrace
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0cf09e9..e1c55f4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -190,6 +190,7 @@
nn_check_sym (CLOCK_MONOTONIC time.h NN_HAVE_CLOCK_MONOTONIC)
nn_check_sym (atomic_cas_32 atomic.h NN_HAVE_ATOMIC_SOLARIS)
nn_check_sym (AF_UNIX sys/socket.h NN_HAVE_UNIX_SOCKETS)
+ nn_check_sym (backtrace_symbols_fd execinfo.h NN_HAVE_BACKTRACE)
nn_check_struct_member(msghdr msg_control sys/socket.h NN_HAVE_MSG_CONTROL)
if (NN_HAVE_SEMAPHORE_RT OR NN_HAVE_SEMAPHORE_PTHREAD)
add_definitions (-DNN_HAVE_SEMAPHORE)
diff --git a/perf/local_lat.c b/perf/local_lat.c
index 3d7e973..a1452a0 100644
--- a/perf/local_lat.c
+++ b/perf/local_lat.c
@@ -1,5 +1,6 @@
/*
Copyright (c) 2012 Martin Sustrik All rights reserved.
+ Copyright 2016 Garrett D'Amore <garrett@damore.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
@@ -27,7 +28,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
+
+#include "../src/utils/err.c"
int main (int argc, char *argv [])
{
@@ -50,28 +52,28 @@
rts = atoi (argv [3]);
s = nn_socket (AF_SP, NN_PAIR);
- assert (s != -1);
+ nn_assert (s != -1);
opt = 1;
rc = nn_setsockopt (s, NN_TCP, NN_TCP_NODELAY, &opt, sizeof (opt));
- assert (rc == 0);
+ nn_assert (rc == 0);
rc = nn_bind (s, bind_to);
- assert (rc >= 0);
+ nn_assert (rc >= 0);
buf = malloc (sz);
- assert (buf);
+ nn_assert (buf);
memset (buf, 111, sz);
for (i = 0; i != rts; i++) {
nbytes = nn_recv (s, buf, sz, 0);
- assert (nbytes == (int)sz);
+ nn_assert (nbytes == (int)sz);
nbytes = nn_send (s, buf, sz, 0);
- assert (nbytes == (int)sz);
+ nn_assert (nbytes == (int)sz);
}
free (buf);
rc = nn_close (s);
- assert (rc == 0);
+ nn_assert (rc == 0);
return 0;
}
diff --git a/perf/local_thr.c b/perf/local_thr.c
index b8ba1f6..a3f9fb3 100644
--- a/perf/local_thr.c
+++ b/perf/local_thr.c
@@ -1,5 +1,6 @@
/*
Copyright (c) 2012 Martin Sustrik All rights reserved.
+ Copyright 2016 Garrett D'Amore <garrett@damore.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
@@ -25,9 +26,9 @@
#include <stdio.h>
#include <stdlib.h>
-#include <assert.h>
#include "../src/utils/stopwatch.c"
+#include "../src/utils/err.c"
int main (int argc, char *argv [])
{
@@ -53,20 +54,20 @@
count = atoi (argv [3]);
s = nn_socket (AF_SP, NN_PAIR);
- assert (s != -1);
+ nn_assert (s != -1);
rc = nn_bind (s, bind_to);
- assert (rc >= 0);
+ nn_assert (rc >= 0);
buf = malloc (sz);
- assert (buf);
+ nn_assert (buf);
nbytes = nn_recv (s, buf, sz, 0);
- assert (nbytes == 0);
+ nn_assert (nbytes == 0);
nn_stopwatch_init (&sw);
for (i = 0; i != count; i++) {
nbytes = nn_recv (s, buf, sz, 0);
- assert (nbytes == (int)sz);
+ nn_assert (nbytes == (int)sz);
}
total = nn_stopwatch_term (&sw);
if (total == 0)
@@ -83,7 +84,7 @@
free (buf);
rc = nn_close (s);
- assert (rc == 0);
+ nn_assert (rc == 0);
return 0;
}
diff --git a/perf/remote_lat.c b/perf/remote_lat.c
index 400468a..cde1869 100644
--- a/perf/remote_lat.c
+++ b/perf/remote_lat.c
@@ -1,5 +1,6 @@
/*
Copyright (c) 2012 Martin Sustrik All rights reserved.
+ Copyright 2016 Garrett D'Amore <garrett@damore.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
@@ -27,9 +28,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
#include "../src/utils/stopwatch.c"
+#include "../src/utils/err.c"
int main (int argc, char *argv [])
{
@@ -56,23 +57,23 @@
rts = atoi (argv [3]);
s = nn_socket (AF_SP, NN_PAIR);
- assert (s != -1);
+ nn_assert (s != -1);
opt = 1;
rc = nn_setsockopt (s, NN_TCP, NN_TCP_NODELAY, &opt, sizeof (opt));
- assert (rc == 0);
+ nn_assert (rc == 0);
rc = nn_connect (s, connect_to);
- assert (rc >= 0);
+ nn_assert (rc >= 0);
buf = malloc (sz);
- assert (buf);
+ nn_assert (buf);
memset (buf, 111, sz);
nn_stopwatch_init (&sw);
for (i = 0; i != rts; i++) {
nbytes = nn_send (s, buf, sz, 0);
- assert (nbytes == (int)sz);
+ nn_assert (nbytes == (int)sz);
nbytes = nn_recv (s, buf, sz, 0);
- assert (nbytes == (int)sz);
+ nn_assert (nbytes == (int)sz);
}
total = nn_stopwatch_term (&sw);
@@ -84,7 +85,7 @@
free (buf);
rc = nn_close (s);
- assert (rc == 0);
+ nn_assert (rc == 0);
return 0;
}
diff --git a/perf/remote_thr.c b/perf/remote_thr.c
index 3b8f60c..82ca2f6 100644
--- a/perf/remote_thr.c
+++ b/perf/remote_thr.c
@@ -1,5 +1,6 @@
/*
Copyright (c) 2012 Martin Sustrik All rights reserved.
+ Copyright 2016 Garrett D'Amore <garrett@damore.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
@@ -26,7 +27,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
+
+#include "../src/utils/err.c"
int main (int argc, char *argv [])
{
@@ -48,26 +50,26 @@
count = atoi (argv [3]);
s = nn_socket (AF_SP, NN_PAIR);
- assert (s != -1);
+ nn_assert (s != -1);
rc = nn_connect (s, connect_to);
- assert (rc >= 0);
+ nn_assert (rc >= 0);
buf = malloc (sz);
- assert (buf);
+ nn_assert (buf);
memset (buf, 111, sz);
nbytes = nn_send (s, buf, 0, 0);
- assert (nbytes == 0);
+ nn_assert (nbytes == 0);
for (i = 0; i != count; i++) {
nbytes = nn_send (s, buf, sz, 0);
- assert (nbytes == (int)sz);
+ nn_assert (nbytes == (int)sz);
}
free (buf);
rc = nn_close (s);
- assert (rc == 0);
+ nn_assert (rc == 0);
return 0;
}
diff --git a/src/utils/err.c b/src/utils/err.c
index cdbfb47..e15148d 100644
--- a/src/utils/err.c
+++ b/src/utils/err.c
@@ -1,5 +1,6 @@
/*
Copyright (c) 2012 Martin Sustrik All rights reserved.
+ Copyright 2016 Garrett D'Amore <garrett@damore.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
@@ -26,6 +27,28 @@
#include "win.h"
#endif
+#ifdef NN_HAVE_BACKTRACE
+#include <execinfo.h>
+
+void nn_backtrace_print (void)
+{
+ void *frames[50];
+ int size;
+ size = backtrace (frames, sizeof (frames) / sizeof (frames[0]));
+ if (size > 1) {
+ /* Don't include the frame nn_backtrace_print itself. */
+ backtrace_symbols_fd (&frames[1], size-1, fileno (stderr));
+ }
+}
+
+/* XXX: Add Windows backtraces */
+
+#else
+void nn_backtrace_print (void)
+{
+}
+#endif
+
#include <stdlib.h>
void nn_err_abort (void)
@@ -187,4 +210,3 @@
}
#endif
-
diff --git a/src/utils/err.h b/src/utils/err.h
index 8864e68..fbaf65d 100644
--- a/src/utils/err.h
+++ b/src/utils/err.h
@@ -1,5 +1,6 @@
/*
Copyright (c) 2012 Martin Sustrik All rights reserved.
+ Copyright 2016 Garrett D'Amore <garrett@damore.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
@@ -45,6 +46,7 @@
#define nn_assert(x) \
do {\
if (nn_slow (!(x))) {\
+ nn_backtrace_print (); \
fprintf (stderr, "Assertion failed: %s (%s:%d)\n", #x, \
__FILE__, __LINE__);\
fflush (stderr);\
@@ -55,6 +57,7 @@
#define nn_assert_state(obj, state_name) \
do {\
if (nn_slow ((obj)->state != state_name)) {\
+ nn_backtrace_print (); \
fprintf (stderr, \
"Assertion failed: %d == %s (%s:%d)\n", \
(obj)->state, #state_name, \
@@ -68,6 +71,7 @@
#define alloc_assert(x) \
do {\
if (nn_slow (!x)) {\
+ nn_backtrace_print (); \
fprintf (stderr, "Out of memory (%s:%d)\n",\
__FILE__, __LINE__);\
fflush (stderr);\
@@ -79,6 +83,7 @@
#define errno_assert(x) \
do {\
if (nn_slow (!(x))) {\
+ nn_backtrace_print (); \
fprintf (stderr, "%s [%d] (%s:%d)\n", nn_err_strerror (errno),\
(int) errno, __FILE__, __LINE__);\
fflush (stderr);\
@@ -90,6 +95,7 @@
#define errnum_assert(cond, err) \
do {\
if (nn_slow (!(cond))) {\
+ nn_backtrace_print (); \
fprintf (stderr, "%s [%d] (%s:%d)\n", nn_err_strerror (err),\
(int) (err), __FILE__, __LINE__);\
fflush (stderr);\
@@ -102,9 +108,11 @@
do {\
if (nn_slow (!(x))) {\
char errstr [256];\
- nn_win_error ((int) GetLastError (), errstr, 256);\
+ DWORD errnum = WSAGetLastError ();\
+ nn_backtrace_print (); \
+ nn_win_error ((int) errnum, errstr, 256);\
fprintf (stderr, "%s [%d] (%s:%d)\n",\
- errstr, (int) GetLastError (), __FILE__, __LINE__);\
+ errstr, (int) errnum, __FILE__, __LINE__);\
fflush (stderr);\
nn_err_abort ();\
}\
@@ -115,9 +123,11 @@
do {\
if (nn_slow (!(x))) {\
char errstr [256];\
- nn_win_error (WSAGetLastError (), errstr, 256);\
+ DWORD errnum = WSAGetLastError ();\
+ nn_backtrace_print (); \
+ nn_win_error (errnum, errstr, 256);\
fprintf (stderr, "%s [%d] (%s:%d)\n",\
- errstr, (int) WSAGetLastError (), __FILE__, __LINE__);\
+ errstr, (int) errnum, __FILE__, __LINE__);\
fflush (stderr);\
nn_err_abort ();\
}\
@@ -126,6 +136,7 @@
/* Assertion-like macros for easier fsm debugging. */
#define nn_fsm_error(message, state, src, type) \
do {\
+ nn_backtrace_print(); \
fprintf (stderr, "%s: state=%d source=%d action=%d (%s:%d)\n", \
message, state, src, type, __FILE__, __LINE__);\
fflush (stderr);\
@@ -153,6 +164,7 @@
NN_NORETURN void nn_err_abort (void);
int nn_err_errno (void);
const char *nn_err_strerror (int errnum);
+void nn_backtrace_print (void);
#ifdef NN_HAVE_WINDOWS
int nn_err_wsa_to_posix (int wsaerr);
@@ -160,4 +172,3 @@
#endif
#endif
-