Add debug messages to diagnose possible ref counting bug

This commit is contained in:
Jeremy Lakeman 2016-05-02 10:48:36 +09:30
parent 0c0726a2b6
commit d7e1e4046b
3 changed files with 25 additions and 13 deletions

View File

@ -268,6 +268,7 @@ ATOM(bool_t, vomp, 0, boolean,, "")
ATOM(bool_t, profiling, 0, boolean,, "") ATOM(bool_t, profiling, 0, boolean,, "")
ATOM(bool_t, linkstate, 0, boolean,, "") ATOM(bool_t, linkstate, 0, boolean,, "")
ATOM(bool_t, watchdog, 0, boolean,, "") ATOM(bool_t, watchdog, 0, boolean,, "")
ATOM(bool_t, ref_counts, 0, boolean,, "")
END_STRUCT END_STRUCT
#define LOG_FORMAT_OPTIONS \ #define LOG_FORMAT_OPTIONS \

View File

@ -101,11 +101,18 @@ typedef struct overlay_interface {
*/ */
extern overlay_interface overlay_interfaces[OVERLAY_MAX_INTERFACES]; extern overlay_interface overlay_interfaces[OVERLAY_MAX_INTERFACES];
struct network_destination * new_destination(struct overlay_interface *interface); struct network_destination * _new_destination(struct __sourceloc __whence, struct overlay_interface *interface);
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);
struct network_destination * add_destination_ref(struct network_destination *ref); struct network_destination * _add_destination_ref(struct __sourceloc __whence, struct network_destination *ref);
void release_destination_ref(struct network_destination *ref); void _release_destination_ref(struct __sourceloc __whence, struct network_destination *ref);
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);
#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(); void overlay_interface_config_change();
struct config_mdp_iftype; struct config_mdp_iftype;

View File

@ -174,7 +174,7 @@ struct neighbour *neighbours=NULL;
unsigned neighbour_count=0; unsigned neighbour_count=0;
int route_version=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); assert(interface);
struct network_destination *ret = emalloc_zero(sizeof(struct network_destination)); struct network_destination *ret = emalloc_zero(sizeof(struct network_destination));
if (ret){ if (ret){
@ -184,11 +184,12 @@ struct network_destination * new_destination(struct overlay_interface *interface
ret->last_tx = TIME_MS_NEVER_HAS; ret->last_tx = TIME_MS_NEVER_HAS;
ret->sequence_number = -1; ret->sequence_number = -1;
ret->last_ack_seq = -1; ret->last_ack_seq = -1;
DEBUGF(ref_counts, "Created destination %p refs %u", ret, ret->_ref_count);
} }
return ret; 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) if (!interface && addr->addr.sa_family == AF_INET)
interface = overlay_interface_find(addr->inet.sin_addr, 1); interface = overlay_interface_find(addr->inet.sin_addr, 1);
if (!interface){ if (!interface){
@ -203,7 +204,7 @@ struct network_destination * create_unicast_destination(struct socket_address *a
return NULL; return NULL;
if (!interface->ifconfig.unicast.send) if (!interface->ifconfig.unicast.send)
return NULL; return NULL;
struct network_destination *ret = new_destination(interface); struct network_destination *ret = _new_destination(whence, interface);
if (ret){ if (ret){
ret->address = *addr; ret->address = *addr;
ret->unicast = 1; ret->unicast = 1;
@ -212,26 +213,29 @@ struct network_destination * create_unicast_destination(struct socket_address *a
return ret; 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++; ref->_ref_count++;
DEBUGF(ref_counts, "Added destination %p refs %u", ref, ref->_ref_count);
return ref; 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){ if (ref->_ref_count<=1){
DEBUGF(ref_counts, "Released destination %p refs %u", ref, ref->_ref_count);
free(ref); free(ref);
}else{ }else{
ref->_ref_count--; 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) if (ref==*ptr)
return 0; return 0;
if (ref) if (ref)
add_destination_ref(ref); _add_destination_ref(__whence, ref);
if (*ptr) if (*ptr)
release_destination_ref(*ptr); _release_destination_ref(__whence, *ptr);
*ptr = ref; *ptr = ref;
return 1; return 1;
} }