| 
					
				 | 
			
			
				@@ -21,7 +21,9 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "util.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "dns_conf.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "tlog.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <arpa/inet.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <dlfcn.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <errno.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <fcntl.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <inttypes.h> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -39,6 +41,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <sys/types.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <time.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <unistd.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <unwind.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define TMP_BUFF_LEN_32 32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1009,3 +1012,50 @@ uint64_t get_free_space(const char *path) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |