From d7e1e4046b97df4b73591a8e9e2dc06c5daad863 Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Mon, 2 May 2016 10:48:36 +0930 Subject: [PATCH] Add debug messages to diagnose possible ref counting bug --- conf_schema.h | 1 + overlay_interface.h | 17 ++++++++++++----- route_link.c | 20 ++++++++++++-------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/conf_schema.h b/conf_schema.h index 8cc2fac0..c5ac1399 100644 --- a/conf_schema.h +++ b/conf_schema.h @@ -268,6 +268,7 @@ ATOM(bool_t, vomp, 0, boolean,, "") ATOM(bool_t, profiling, 0, boolean,, "") ATOM(bool_t, linkstate, 0, boolean,, "") ATOM(bool_t, watchdog, 0, boolean,, "") +ATOM(bool_t, ref_counts, 0, boolean,, "") END_STRUCT #define LOG_FORMAT_OPTIONS \ diff --git a/overlay_interface.h b/overlay_interface.h index d78a7567..31d02349 100644 --- a/overlay_interface.h +++ b/overlay_interface.h @@ -101,11 +101,18 @@ typedef struct overlay_interface { */ extern overlay_interface overlay_interfaces[OVERLAY_MAX_INTERFACES]; -struct network_destination * new_destination(struct overlay_interface *interface); -struct network_destination * create_unicast_destination(struct socket_address *addr, struct overlay_interface *interface); -struct network_destination * add_destination_ref(struct network_destination *ref); -void release_destination_ref(struct network_destination *ref); -int set_destination_ref(struct network_destination **ptr, struct network_destination *ref); +struct network_destination * _new_destination(struct __sourceloc __whence, struct overlay_interface *interface); +struct network_destination * _create_unicast_destination(struct __sourceloc __whence, struct socket_address *addr, struct overlay_interface *interface); +struct network_destination * _add_destination_ref(struct __sourceloc __whence, struct network_destination *ref); +void _release_destination_ref(struct __sourceloc __whence, struct network_destination *ref); +int _set_destination_ref(struct __sourceloc __whence, struct network_destination **ptr, struct network_destination *ref); + +#define new_destination(I) _new_destination(__WHENCE__, I) +#define create_unicast_destination(A, I) _create_unicast_destination(__WHENCE__, A, I) +#define add_destination_ref(R) _add_destination_ref(__WHENCE__, R) +#define release_destination_ref(R) _release_destination_ref(__WHENCE__, R) +#define set_destination_ref(P, R) _set_destination_ref(__WHENCE__, P, R) + void overlay_interface_config_change(); struct config_mdp_iftype; diff --git a/route_link.c b/route_link.c index 4bfdadc7..e7d1c22b 100644 --- a/route_link.c +++ b/route_link.c @@ -174,7 +174,7 @@ struct neighbour *neighbours=NULL; unsigned neighbour_count=0; int route_version=0; -struct network_destination * new_destination(struct overlay_interface *interface){ +struct network_destination * _new_destination(struct __sourceloc __whence, struct overlay_interface *interface){ assert(interface); struct network_destination *ret = emalloc_zero(sizeof(struct network_destination)); if (ret){ @@ -184,11 +184,12 @@ struct network_destination * new_destination(struct overlay_interface *interface ret->last_tx = TIME_MS_NEVER_HAS; ret->sequence_number = -1; ret->last_ack_seq = -1; + DEBUGF(ref_counts, "Created destination %p refs %u", ret, ret->_ref_count); } return ret; } -struct network_destination * create_unicast_destination(struct socket_address *addr, struct overlay_interface *interface){ +struct network_destination * _create_unicast_destination(struct __sourceloc whence, struct socket_address *addr, struct overlay_interface *interface){ if (!interface && addr->addr.sa_family == AF_INET) interface = overlay_interface_find(addr->inet.sin_addr, 1); if (!interface){ @@ -203,7 +204,7 @@ struct network_destination * create_unicast_destination(struct socket_address *a return NULL; if (!interface->ifconfig.unicast.send) return NULL; - struct network_destination *ret = new_destination(interface); + struct network_destination *ret = _new_destination(whence, interface); if (ret){ ret->address = *addr; ret->unicast = 1; @@ -212,26 +213,29 @@ struct network_destination * create_unicast_destination(struct socket_address *a return ret; } -struct network_destination * add_destination_ref(struct network_destination *ref){ +struct network_destination * _add_destination_ref(struct __sourceloc __whence, struct network_destination *ref){ ref->_ref_count++; + DEBUGF(ref_counts, "Added destination %p refs %u", ref, ref->_ref_count); return ref; } -void release_destination_ref(struct network_destination *ref){ +void _release_destination_ref(struct __sourceloc __whence, struct network_destination *ref){ if (ref->_ref_count<=1){ + DEBUGF(ref_counts, "Released destination %p refs %u", ref, ref->_ref_count); free(ref); }else{ ref->_ref_count--; + DEBUGF(ref_counts, "Decremented destination %p refs %u", ref, ref->_ref_count); } } -int set_destination_ref(struct network_destination **ptr, struct network_destination *ref){ +int _set_destination_ref(struct __sourceloc __whence, struct network_destination **ptr, struct network_destination *ref){ if (ref==*ptr) return 0; if (ref) - add_destination_ref(ref); + _add_destination_ref(__whence, ref); if (*ptr) - release_destination_ref(*ptr); + _release_destination_ref(__whence, *ptr); *ptr = ref; return 1; }