|
@@ -21,7 +21,9 @@
|
|
|
#endif
|
|
#endif
|
|
|
#include "util.h"
|
|
#include "util.h"
|
|
|
#include "dns_conf.h"
|
|
#include "dns_conf.h"
|
|
|
|
|
+#include "tlog.h"
|
|
|
#include <arpa/inet.h>
|
|
#include <arpa/inet.h>
|
|
|
|
|
+#include <dlfcn.h>
|
|
|
#include <errno.h>
|
|
#include <errno.h>
|
|
|
#include <fcntl.h>
|
|
#include <fcntl.h>
|
|
|
#include <inttypes.h>
|
|
#include <inttypes.h>
|
|
@@ -39,6 +41,7 @@
|
|
|
#include <sys/types.h>
|
|
#include <sys/types.h>
|
|
|
#include <time.h>
|
|
#include <time.h>
|
|
|
#include <unistd.h>
|
|
#include <unistd.h>
|
|
|
|
|
+#include <unwind.h>
|
|
|
|
|
|
|
|
#define TMP_BUFF_LEN_32 32
|
|
#define TMP_BUFF_LEN_32 32
|
|
|
|
|
|
|
@@ -1009,3 +1012,50 @@ uint64_t get_free_space(const char *path)
|
|
|
|
|
|
|
|
return size;
|
|
return size;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+struct backtrace_state {
|
|
|
|
|
+ void **current;
|
|
|
|
|
+ void **end;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+static _Unwind_Reason_Code unwind_callback(struct _Unwind_Context *context, void *arg)
|
|
|
|
|
+{
|
|
|
|
|
+ struct backtrace_state *state = (struct backtrace_state *)(arg);
|
|
|
|
|
+ uintptr_t pc = _Unwind_GetIP(context);
|
|
|
|
|
+ if (pc) {
|
|
|
|
|
+ if (state->current == state->end) {
|
|
|
|
|
+ return _URC_END_OF_STACK;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ *state->current++ = (void *)(pc);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return _URC_NO_REASON;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void print_stack(void)
|
|
|
|
|
+{
|
|
|
|
|
+ const size_t max_buffer = 30;
|
|
|
|
|
+ void *buffer[max_buffer];
|
|
|
|
|
+
|
|
|
|
|
+ struct backtrace_state state = {buffer, buffer + max_buffer};
|
|
|
|
|
+ _Unwind_Backtrace(unwind_callback, &state);
|
|
|
|
|
+ int frame_num = state.current - buffer;
|
|
|
|
|
+ if (frame_num == 0) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tlog(TLOG_FATAL, "Stack:");
|
|
|
|
|
+ for (size_t idx = 0; idx < frame_num; ++idx) {
|
|
|
|
|
+ const void *addr = buffer[idx];
|
|
|
|
|
+ const char *symbol = "";
|
|
|
|
|
+
|
|
|
|
|
+ Dl_info info;
|
|
|
|
|
+ memset(&info, 0, sizeof(info));
|
|
|
|
|
+ if (dladdr(addr, &info) && info.dli_sname) {
|
|
|
|
|
+ symbol = info.dli_sname;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void *offset = (void *)((char *)(addr) - (char *)(info.dli_fbase));
|
|
|
|
|
+ tlog(TLOG_FATAL, "#%.2d: %p %s from %s+%p", idx + 1, addr, symbol, info.dli_fname, offset);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|