From 01f3775b377fb126f16783c3f1628236766ef31d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 21 Nov 2009 01:11:49 -0500 Subject: [PATCH] Fix memory-leak of signal handler array with kqueue. [backport] It turns out that kqueue_dealloc wasn't calling evsig_dealloc() (because it doesn't use the main signal handler logic) so the sh_old array was leaking. This patch also introduces a fix in evsig_dealloc() where we set the sh_old array to NULL when we free it, so that main/fork can pass. --- kqueue.c | 4 ++++ signal.c | 19 +++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/kqueue.c b/kqueue.c index 33476611..ee740eec 100644 --- a/kqueue.c +++ b/kqueue.c @@ -63,6 +63,7 @@ #include "event.h" #include "event-internal.h" #include "log.h" +#include "evsignal.h" #define EVLIST_X_KQINKERNEL 0x1000 @@ -440,12 +441,15 @@ kq_dealloc(struct event_base *base, void *arg) { struct kqop *kqop = arg; + evsignal_dealloc(base); + if (kqop->changes) free(kqop->changes); if (kqop->events) free(kqop->events); if (kqop->kq >= 0 && kqop->pid == getpid()) close(kqop->kq); + memset(kqop, 0, sizeof(struct kqop)); free(kqop); } diff --git a/signal.c b/signal.c index 74fa23f6..4371b703 100644 --- a/signal.c +++ b/signal.c @@ -346,12 +346,19 @@ evsignal_dealloc(struct event_base *base) _evsignal_restore_handler(base, i); } - EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]); - base->sig.ev_signal_pair[0] = -1; - EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]); - base->sig.ev_signal_pair[1] = -1; + if (base->sig.ev_signal_pair[0] != -1) { + EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]); + base->sig.ev_signal_pair[0] = -1; + } + if (base->sig.ev_signal_pair[1] != -1) { + EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]); + base->sig.ev_signal_pair[1] = -1; + } base->sig.sh_old_max = 0; - /* per index frees are handled in evsignal_del() */ - free(base->sig.sh_old); + /* per index frees are handled in evsig_del() */ + if (base->sig.sh_old) { + free(base->sig.sh_old); + base->sig.sh_old = NULL; + } }