From 3065cb9168e994b5388c37170c61b0956c91e0d2 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 28 Oct 2020 23:49:36 +0400 Subject: [PATCH] [mod_sofia] Fix memory leaks caused by improper profile destroy. Add a unit-test. --- src/mod/endpoints/mod_sofia/sofia.c | 25 +++-- tests/unit/Makefile.am | 2 +- tests/unit/conf_sofia/freeswitch.xml | 144 +++++++++++++++++++++++++++ tests/unit/test_sofia.c | 31 ++++++ 4 files changed, 191 insertions(+), 11 deletions(-) create mode 100644 tests/unit/conf_sofia/freeswitch.xml create mode 100644 tests/unit/test_sofia.c diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 4975ca8feb..87b09e5406 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -3180,7 +3180,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void if (!sofia_glue_init_sql(profile)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database [%s]!\n", profile->name); sofia_profile_start_failure(profile, profile->name); - sofia_glue_del_profile(profile); goto end; } @@ -3332,7 +3331,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void } sofia_profile_start_failure(profile, profile->name); - sofia_glue_del_profile(profile); goto end; } @@ -3500,6 +3498,20 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void } } + /* Do gateway cleanups */ + sofia_glue_del_every_gateway(profile); + sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL)); + sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL)); + sofia_glue_fire_events(profile); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Waiting for worker thread\n"); + + if (worker_thread) { + switch_thread_join(&st, worker_thread); + } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Sofia worker thead failed to start\n"); + } sofia_reg_unregister(profile); nua_shutdown(profile->nua); @@ -3514,13 +3526,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void sofia_clear_pflag_locked(profile, PFLAG_RUNNING); sofia_clear_pflag_locked(profile, PFLAG_SHUTDOWN); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Waiting for worker thread\n"); - - if ( worker_thread ) { - switch_thread_join(&st, worker_thread); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Sofia worker thead failed to start\n"); - } sanity = 4; while (profile->inuse) { @@ -3569,6 +3574,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void } } + end: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock %s\n", profile->name); switch_thread_rwlock_wrlock(profile->rwlock); @@ -3590,7 +3596,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void sofia_profile_destroy(profile); - end: switch_mutex_lock(mod_sofia_globals.mutex); mod_sofia_globals.threads--; switch_mutex_unlock(mod_sofia_globals.mutex); diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index 2511a143c2..231225c5aa 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/build/modmake.rulesam noinst_PROGRAMS = switch_event switch_hash switch_ivr_originate switch_utils switch_core switch_console switch_vpx switch_core_file \ switch_ivr_play_say switch_core_codec switch_rtp switch_xml -noinst_PROGRAMS += switch_core_video switch_core_db switch_vad switch_core_asr +noinst_PROGRAMS += switch_core_video switch_core_db switch_vad switch_core_asr test_sofia AM_LDFLAGS += -avoid-version -no-undefined $(SWITCH_AM_LDFLAGS) $(openssl_LIBS) AM_LDFLAGS += $(FREESWITCH_LIBS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) diff --git a/tests/unit/conf_sofia/freeswitch.xml b/tests/unit/conf_sofia/freeswitch.xml new file mode 100644 index 0000000000..793ac5a04a --- /dev/null +++ b/tests/unit/conf_sofia/freeswitch.xml @@ -0,0 +1,144 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
diff --git a/tests/unit/test_sofia.c b/tests/unit/test_sofia.c new file mode 100644 index 0000000000..e45bd5d3fd --- /dev/null +++ b/tests/unit/test_sofia.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2018-2019, Signalwire, Inc. ALL RIGHTS RESERVED + * test_sofia.c -- Tests mod_sofia for memory leaks + */ + +#include +#include + +FST_CORE_DB_BEGIN("conf_sofia") +{ + FST_SUITE_BEGIN(switch_sofia) + { + FST_SETUP_BEGIN() + { + fst_requires_module("mod_sofia"); + } + FST_SETUP_END() + + FST_TEARDOWN_BEGIN() + { + } + FST_TEARDOWN_END() + + FST_TEST_BEGIN(sofia_leaks) + { + } + FST_TEST_END() + } + FST_SUITE_END() +} +FST_CORE_END()