The struct mworker_proc is not uniformly freed everywhere, sometimes leading to leaks of the `id` string (and possibly the other strings).
Introduce a mworker_free_child function instead of duplicating the freeing logic everywhere to prevent this kind of issues. This leak was reported in issue #96. It looks like the leaks have been introduced in commit 9a1ee7ac31c56fd7d881adf2ef4659f336e50c9f, which is specific to 2.0-dev. Backporting `mworker_free_child` might be helpful to ease backporting other fixes, though. --- include/proto/mworker.h | 2 ++ src/haproxy.c | 3 ++- src/mworker-prog.c | 19 +------------------ src/mworker.c | 24 ++++++++++++++++++++++-- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/include/proto/mworker.h b/include/proto/mworker.h index 86f09049f..05fe82af6 100644 --- a/include/proto/mworker.h +++ b/include/proto/mworker.h @@ -37,4 +37,6 @@ int mworker_ext_launch_all(); void mworker_kill_max_reloads(int sig); +void mworker_free_child(struct mworker_proc *); + #endif /* PROTO_MWORKER_H_ */ diff --git a/src/haproxy.c b/src/haproxy.c index a47b7dd32..b688375e2 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -3002,7 +3002,8 @@ int main(int argc, char **argv) continue; } LIST_DEL(&child->list); - free(child); + mworker_free_child(child); + child = NULL; } } diff --git a/src/mworker-prog.c b/src/mworker-prog.c index fd8e66384..467ce9b24 100644 --- a/src/mworker-prog.c +++ b/src/mworker-prog.c @@ -69,24 +69,7 @@ int mworker_ext_launch_all() LIST_DEL(&child->list); - if (child->command) { - int i; - - for (i = 0; child->command[i]; i++) { - if (child->command[i]) { - free(child->command[i]); - child->command[i] = NULL; - } - } - free(child->command); - child->command = NULL; - } - if (child->id) { - free(child->id); - child->id = NULL; - } - - free(child); + mworker_free_child(child); child = NULL; continue; diff --git a/src/mworker.c b/src/mworker.c index 491d40837..8debbdc36 100644 --- a/src/mworker.c +++ b/src/mworker.c @@ -185,8 +185,7 @@ void mworker_env_to_proc_list() if (child->pid) { LIST_ADDQ(&proc_list, &child->list); } else { - free(child->id); - free(child); + mworker_free_child(child); } } @@ -553,6 +552,27 @@ out: return err_code; } +void mworker_free_child(struct mworker_proc *child) { + if (child == NULL) return; + + if (child->command) { + int i; + + for (i = 0; child->command[i]; i++) { + if (child->command[i]) { + free(child->command[i]); + child->command[i] = NULL; + } + } + free(child->command); + child->command = NULL; + } + if (child->id) { + free(child->id); + child->id = NULL; + } + free(child); +} static struct cfg_kw_list mworker_kws = {{ }, { { CFG_GLOBAL, "mworker-max-reloads", mworker_parse_global_max_reloads }, -- 2.21.0