diff --git a/src/dns_client.c b/src/dns_client.c index 4f3dfb659e..e439cd1599 100644 --- a/src/dns_client.c +++ b/src/dns_client.c @@ -1245,8 +1245,7 @@ static int _dns_client_server_remove(char *server_ip, int port, dns_server_type_ static void _dns_client_server_pending_get(struct dns_server_pending *pending) { if (atomic_inc_return(&pending->refcnt) <= 0) { - tlog(TLOG_ERROR, "BUG: pending ref is invalid"); - abort(); + BUG("pending ref is invalid"); } } @@ -1259,8 +1258,7 @@ static void _dns_client_server_pending_release(struct dns_server_pending *pendin if (refcnt) { if (refcnt < 0) { - tlog(TLOG_ERROR, "BUG: pending refcnt is %d", refcnt); - abort(); + BUG("BUG: pending refcnt is %d", refcnt); } return; } @@ -1373,8 +1371,7 @@ int dns_server_num(void) static void _dns_client_query_get(struct dns_query_struct *query) { if (atomic_inc_return(&query->refcnt) <= 0) { - tlog(TLOG_ERROR, "BUG: query ref is invalid, domain: %s", query->domain); - abort(); + BUG("query ref is invalid, domain: %s", query->domain); } } @@ -1387,8 +1384,7 @@ static void _dns_client_query_release(struct dns_query_struct *query) if (refcnt) { if (refcnt < 0) { - tlog(TLOG_ERROR, "BUG: refcnt is %d", refcnt); - abort(); + BUG("BUG: refcnt is %d", refcnt); } return; } @@ -2213,8 +2209,7 @@ static int _dns_client_process_tcp_buff(struct dns_server_info *server_info) server_info->recv_buff.len -= len; if (server_info->recv_buff.len < 0) { - tlog(TLOG_ERROR, "Internal error."); - abort(); + BUG("Internal error."); } /* move to next result */ @@ -2315,8 +2310,7 @@ static int _dns_client_process_tcp(struct dns_server_info *server_info, struct e if (server_info->send_buff.len > 0) { memmove(server_info->send_buff.data, server_info->send_buff.data + len, server_info->send_buff.len); } else if (server_info->send_buff.len < 0) { - tlog(TLOG_ERROR, "Internal Error"); - abort(); + BUG("Internal Error"); } pthread_mutex_unlock(&client.server_list_lock); } @@ -2971,8 +2965,7 @@ static int _dns_client_send_query(struct dns_query_struct *query, const char *do } if (encode_len > DNS_IN_PACKSIZE) { - tlog(TLOG_ERROR, "size is invalid."); - abort(); + BUG("size is invalid."); return -1; } diff --git a/src/dns_server.c b/src/dns_server.c index 8faff4a403..c7fcf96aea 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -797,8 +797,7 @@ static void _dns_server_conn_release(struct dns_server_conn_head *conn) if (refcnt) { if (refcnt < 0) { - tlog(TLOG_ERROR, "BUG: refcnt is %d, type = %d", refcnt, conn->type); - abort(); + BUG("BUG: refcnt is %d, type = %d", refcnt, conn->type); } return; } @@ -819,8 +818,7 @@ static void _dns_server_conn_get(struct dns_server_conn_head *conn) } if (atomic_inc_return(&conn->refcnt) <= 0) { - tlog(TLOG_ERROR, "BUG: client ref is invalid."); - abort(); + BUG("BUG: client ref is invalid."); } } @@ -1797,15 +1795,19 @@ static void _dns_server_request_release_complete(struct dns_request *request, in if (refcnt) { pthread_mutex_unlock(&server.request_list_lock); if (refcnt < 0) { - tlog(TLOG_ERROR, "BUG: refcnt is %d, domain %s, qtype %d", refcnt, request->domain, request->qtype); - abort(); + BUG("BUG: refcnt is %d, domain %s, qtype %d", refcnt, request->domain, request->qtype); } return; } list_del_init(&request->list); + list_del_init(&request->check_list); pthread_mutex_unlock(&server.request_list_lock); + pthread_mutex_lock(&server.request_pending_lock); + list_del_init(&request->pending_list); + pthread_mutex_unlock(&server.request_pending_lock); + if (do_complete) { /* Select max hit ip address, and return to client */ _dns_server_select_possible_ipaddress(request); @@ -1831,8 +1833,7 @@ static void _dns_server_request_release(struct dns_request *request) static void _dns_server_request_get(struct dns_request *request) { if (atomic_inc_return(&request->refcnt) <= 0) { - tlog(TLOG_ERROR, "BUG: request ref is invalid, %s", request->domain); - abort(); + BUG("BUG: request ref is invalid, %s", request->domain); } } @@ -1867,7 +1868,7 @@ static int _dns_server_set_to_pending_list(struct dns_request *request) pending_list = malloc(sizeof(*pending_list)); if (pending_list == NULL) { ret = -1; - goto errout; + goto out; } memset(pending_list, 0, sizeof(*pending_list)); @@ -1882,14 +1883,11 @@ static int _dns_server_set_to_pending_list(struct dns_request *request) ret = 0; } - pthread_mutex_lock(&pending_list->request_list_lock); if (ret == 0) { _dns_server_request_get(request); } list_add_tail(&request->pending_list, &pending_list->request_list); - - pthread_mutex_unlock(&pending_list->request_list_lock); -errout: +out: pthread_mutex_unlock(&server.request_pending_lock); return ret; } diff --git a/src/util.c b/src/util.c index 8ad6e94ac7..c3ef5fda4e 100644 --- a/src/util.c +++ b/src/util.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1121,7 +1122,7 @@ void print_stack(void) if (frame_num == 0) { return; } - + tlog(TLOG_FATAL, "Stack:"); for (idx = 0; idx < frame_num; ++idx) { const void *addr = buffer[idx]; @@ -1134,10 +1135,28 @@ void print_stack(void) } 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); + tlog(TLOG_FATAL, "#%.2d: %p %s() from %s+%p", idx + 1, addr, symbol, info.dli_fname, offset); } } +void bug_ext(const char *file, int line, const char *func, const char *errfmt, ...) +{ + va_list ap; + + va_start(ap, errfmt); + tlog_vext(TLOG_FATAL, file, line, func, NULL, errfmt, ap); + va_end(ap); + + print_stack(); + /* trigger BUG */ + sleep(1); + raise(SIGSEGV); + + while (true) { + sleep(1); + }; +} + int write_file(const char *filename, void *data, int data_len) { int fd = open(filename, O_WRONLY|O_CREAT, 0644); diff --git a/src/util.h b/src/util.h index b4411af860..81a5787454 100644 --- a/src/util.h +++ b/src/util.h @@ -45,6 +45,16 @@ extern "C" { #define PORT_NOT_DEFINED -1 #define MAX_IP_LEN 64 +#ifndef BASE_FILE_NAME +#define BASE_FILE_NAME \ + (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 \ + : __FILE__) +#endif +#define BUG(format, ...) bug_ext(BASE_FILE_NAME, __LINE__, __func__, format, ##__VA_ARGS__) + +void bug_ext(const char *file, int line, const char *func, const char *errfmt, ...) + __attribute__((format(printf, 4, 5))) __attribute__((nonnull(4))); + unsigned long get_tick_count(void); char *gethost_by_addr(char *host, int maxsize, struct sockaddr *addr);