Attached is a patch to configure libevent so that it uses pluto's
leak-detective. It does throw up some leaks but they are mostly
harmless - pluto just needs to execute:
+ dbg("releasing event base");
+ event_base_free(pluto_eb);
+ pluto_eb = NULL;
+ dbg("releasing global event data");
+ /* this releases data allocated by evthread_use_pthreads() */
+ libevent_global_shutdown();
as part of a clean shutdown. The attached patch also adds these missing calls.
I'm going to sit on this for now (I need to test more than just
ikev2-12-x509-ikev1-rw), but that can wait until later.
Andrew
PS: more surprisingly is that this patch and count-pointers.awk found
a bug in leak-detective :-)
commit f4c519e61129446dbe833115d5b6ecfc5b73b87a
Author: Andrew Cagney <[email protected]>
Date: Fri Mar 22 10:50:34 2019 -0400
events: point libevent at pluto's memory allocator; free libevent's resources during exit
diff --git a/include/lswalloc.h b/include/lswalloc.h
index 532bda451c..268a337ef2 100644
--- a/include/lswalloc.h
+++ b/include/lswalloc.h
@@ -29,6 +29,7 @@ extern void pfree(void *ptr);
extern void *alloc_bytes(size_t size, const char *name);
extern void *clone_bytes(const void *orig, size_t size,
const char *name);
+void resize_bytes(void **ptr, size_t new_size);
extern bool leak_detective;
extern void report_leaks(void);
diff --git a/lib/libswan/alloc.c b/lib/libswan/alloc.c
index e988e055a5..9c616e4cf7 100644
--- a/lib/libswan/alloc.c
+++ b/lib/libswan/alloc.c
@@ -219,3 +219,30 @@ void *clone_bytes(const void *orig, size_t size, const char *name)
memcpy(p, orig, size);
return p;
}
+
+/*
+ * Re-size something on the HEAP.
+ *
+ * Unlike the more traditional realloc() this code doesn't allow a
+ * NULL pointer. The caller, which is presumably implementing some
+ * sort of realloc() wrapper, gets to handle this. So as to avoid any
+ * confusion, give this a different name and function signature.
+ *
+ * Efficiency isn't this code's strong point.
+ */
+
+void resize_bytes(void **ptr, size_t new_size)
+{
+ void *old = *ptr;
+ passert(old != NULL);
+ if (leak_detective) {
+ const union mhdr *p = ((const union mhdr *)old) - 1;
+ passert(p->i.magic == LEAK_MAGIC);
+ void *new = alloc_bytes_raw(new_size, p->i.name);
+ memcpy(new, old, min(p->i.size, new_size));
+ pfree(old);
+ *ptr = new;
+ } else {
+ *ptr = realloc(old, new_size);
+ }
+}
diff --git a/programs/pluto/server.c b/programs/pluto/server.c
index 8183cc305b..4890262be0 100644
--- a/programs/pluto/server.c
+++ b/programs/pluto/server.c
@@ -442,7 +442,12 @@ void free_pluto_event_list(void)
struct pluto_event **head = &pluto_events_head;
while (*head != NULL)
*head = free_event_entry(head);
-
+ dbg("releasing event base");
+ event_base_free(pluto_eb);
+ pluto_eb = NULL;
+ dbg("releasing global event data");
+ /* this releases data allocated by evthread_use_pthreads() */
+ libevent_global_shutdown();
}
void link_pluto_event_list(struct pluto_event *e) {
@@ -962,7 +967,46 @@ static void childhandler_cb(int unused UNUSED, const short event UNUSED, void *a
}
}
-void init_event_base(void) {
+#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
+static void *libevent_malloc(size_t size)
+{
+ void *ptr = alloc_bytes(size, __func__);
+ dbg("%s: new ptr-libevent@%p size %zu", __func__, ptr, size);
+ return ptr;
+}
+static void *libevent_realloc(void *ptr, size_t size)
+{
+ if (ptr == NULL) {
+ ptr = alloc_bytes(size, __func__);
+ dbg("%s: new ptr-libevent@%p size %zu", __func__, ptr, size);
+ return ptr;
+ } else {
+ /* enough to keep count-pointers.awk happy */
+ dbg("%s: release ptr-libevent@%p", __func__, ptr);
+ resize_bytes(&ptr, size);
+ dbg("%s: new ptr-libevent@%p size %zu", __func__, ptr, size);
+ return ptr;
+ }
+}
+static void libevent_free(void *ptr)
+{
+ dbg("%s: release ptr-libevent@%p", __func__, ptr);
+ pfree(ptr);
+}
+#endif
+
+void init_event_base(void)
+{
+ /*
+ * "... if you are going to call this function, you should do
+ * so before any call to any Libevent function that does
+ * allocation."
+ */
+#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
+ dbg("pointing libevent at pluto's memory allocator");
+ event_set_mem_functions(libevent_malloc, libevent_realloc,
+ libevent_free);
+#endif
libreswan_log("Initializing libevent in pthreads mode: headers: %s (%" PRIx32 "); library: %s (%" PRIx32 ")",
LIBEVENT_VERSION, (ev_uint32_t)LIBEVENT_VERSION_NUMBER,
event_get_version(), event_get_version_number());
@@ -973,10 +1017,12 @@ void init_event_base(void) {
int r = evthread_use_pthreads();
passert(r >= 0);
/* now do anything */
+ dbg("creating event base");
pluto_eb = event_base_new();
passert(pluto_eb != NULL);
int s = evthread_make_base_notifiable(pluto_eb);
passert(s >= 0);
+ dbg("libevent initialized");
}
/* call_server listens for incoming ISAKMP packets and Whack messages,
_______________________________________________
Swan-dev mailing list
[email protected]
https://lists.libreswan.org/mailman/listinfo/swan-dev