Solve Vlagrind "definitely lost" memory leaks

pull/1013/head
Stefan Mititelu 6 years ago
parent 38bb6d8608
commit de28a65934

@ -141,8 +141,10 @@ void threads_join_all(int wait) {
pthread_join(*t, NULL);
threads_to_join = g_list_delete_link(threads_to_join, threads_to_join);
l = g_list_find_custom(threads_running, t, thread_equal);
if (l)
if (l) {
g_slice_free1(sizeof(*t), l->data);
threads_running = g_list_delete_link(threads_running, l);
}
else
abort();
g_slice_free1(sizeof(*t), t);
@ -264,3 +266,11 @@ void free_buf(char **p) {
if (*p)
free(*p);
}
void free_gbuf(char **p) {
g_free(*p);
}
void free_gvbuf(char ***p) {
g_strfreev(*p);
}

@ -68,14 +68,12 @@ struct rtpengine_config rtpe_config = {
.redis_allowed_errors = -1,
.redis_disable_time = 10,
.redis_connect_timeout = 1000,
.rec_method = "pcap",
.rec_format = "raw",
.media_num_threads = -1,
.dtls_rsa_key_size = 2048,
.dtls_ciphers = "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK",
.dtls_signature = 256,
};
char **if_a_global = NULL;
static void sighandler(gpointer x) {
sigset_t ss;
@ -288,32 +286,32 @@ static int redis_ep_parse(endpoint_t *ep, int *db, char **auth, const char *auth
static void options(int *argc, char ***argv) {
char **if_a = NULL;
char **ks_a = NULL;
AUTO_CLEANUP_GVBUF(ks_a);
unsigned long uint_keyspace_db;
str str_keyspace_db;
char **iter;
char *listenps = NULL;
char *listenudps = NULL;
char *listenngs = NULL;
char *listencli = NULL;
char *graphitep = NULL;
char *graphite_prefix_s = NULL;
char *redisps = NULL;
char *redisps_write = NULL;
char *log_facility_cdr_s = NULL;
char *log_facility_rtcp_s = NULL;
char *log_facility_dtmf_s = NULL;
char *log_format = NULL;
AUTO_CLEANUP_GBUF(listenps);
AUTO_CLEANUP_GBUF(listenudps);
AUTO_CLEANUP_GBUF(listenngs);
AUTO_CLEANUP_GBUF(listencli);
AUTO_CLEANUP_GBUF(graphitep);
AUTO_CLEANUP_GBUF(graphite_prefix_s);
AUTO_CLEANUP_GBUF(redisps);
AUTO_CLEANUP_GBUF(redisps_write);
AUTO_CLEANUP_GBUF(log_facility_cdr_s);
AUTO_CLEANUP_GBUF(log_facility_rtcp_s);
AUTO_CLEANUP_GBUF(log_facility_dtmf_s);
AUTO_CLEANUP_GBUF(log_format);
int sip_source = 0;
char *homerp = NULL;
char *homerproto = NULL;
AUTO_CLEANUP_GBUF(homerp);
AUTO_CLEANUP_GBUF(homerproto);
char *endptr;
int codecs = 0;
double max_load = 0;
double max_cpu = 0;
char *dtmf_udp_ep = NULL;
char *endpoint_learning = NULL;
char *dtls_sig = NULL;
AUTO_CLEANUP_GBUF(dtmf_udp_ep);
AUTO_CLEANUP_GBUF(endpoint_learning);
AUTO_CLEANUP_GBUF(dtls_sig);
GOptionEntry e[] = {
{ "table", 't', 0, G_OPTION_ARG_INT, &rtpe_config.kernel_table, "Kernel table to use", "INT" },
@ -394,6 +392,16 @@ static void options(int *argc, char ***argv) {
config_load(argc, argv, e, " - next-generation media proxy",
"/etc/rtpengine/rtpengine.conf", "rtpengine", &rtpe_config.common);
// default values, if not configured
if (rtpe_config.rec_method == NULL)
rtpe_config.rec_method = g_strdup("pcap");
if (rtpe_config.rec_format == NULL)
rtpe_config.rec_format = g_strdup("raw");
if (rtpe_config.dtls_ciphers == NULL)
rtpe_config.dtls_ciphers = g_strdup("DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK");
if (codecs) {
codeclib_init(1);
exit(0);
@ -595,6 +603,9 @@ static void options(int *argc, char ***argv) {
if (rtpe_config.jb_length < 0)
die("Invalid negative jitter buffer size");
// free local vars
if_a_global = if_a; // -> content is used; needs to be freed later
}
void fill_initial_rtpe_cfg(struct rtpengine_config* ini_rtpe_cfg) {
@ -670,6 +681,39 @@ void fill_initial_rtpe_cfg(struct rtpengine_config* ini_rtpe_cfg) {
ini_rtpe_cfg->jb_clock_drift = rtpe_config.jb_clock_drift;
}
static void unfill_initial_rtpe_cfg(struct rtpengine_config* ini_rtpe_cfg) {
// free g_strdup
g_free(ini_rtpe_cfg->b2b_url);
g_free(ini_rtpe_cfg->redis_auth);
g_free(ini_rtpe_cfg->redis_write_auth);
g_free(ini_rtpe_cfg->spooldir);
g_free(ini_rtpe_cfg->iptables_chain);
g_free(ini_rtpe_cfg->rec_method);
g_free(ini_rtpe_cfg->rec_format);
}
static void options_free(void) {
// free config options
g_free(rtpe_config.b2b_url);
g_free(rtpe_config.spooldir);
g_free(rtpe_config.rec_method);
g_free(rtpe_config.rec_format);
g_free(rtpe_config.iptables_chain);
g_free(rtpe_config.scheduling);
g_free(rtpe_config.idle_scheduling);
g_free(rtpe_config.mysql_host);
g_free(rtpe_config.mysql_user);
g_free(rtpe_config.mysql_pass);
g_free(rtpe_config.mysql_query);
g_free(rtpe_config.dtls_ciphers);
// free common config options
config_load_free(&rtpe_config.common);
// free if_a STRING LIST
g_strfreev(if_a_global);
}
static void early_init(void) {
socket_init(); // needed for socktype_udp
}
@ -905,5 +949,9 @@ int main(int argc, char **argv) {
ilog(LOG_INFO, "Version %s shutting down", RTPENGINE_VERSION);
unfill_initial_rtpe_cfg(&initial_rtpe_config);
options_free();
return 0;
}

@ -232,6 +232,8 @@ INLINE int rlim(int res, rlim_t val) {
}
void free_buf(char **);
void free_gbuf(char **);
void free_gvbuf(char ***);

@ -79,7 +79,7 @@ static unsigned int options_length(const GOptionEntry *arr) {
#define CONF_OPTION_GLUE(get_func, data_type, ...) \
{ \
data_type *varptr = e->arg_data; \
data_type var = g_key_file_get_ ## get_func(kf, rtpe_common_config_ptr->config_section, e->long_name, \
data_type var = g_key_file_get_ ## get_func(kf, use_section, e->long_name, \
##__VA_ARGS__, &er); \
if (er && g_error_matches(er, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) { \
g_error_free(er); \
@ -92,15 +92,25 @@ static unsigned int options_length(const GOptionEntry *arr) {
break; \
}
void config_load_free(struct rtpengine_common_config *cconfig) {
// free common config options
g_free(cconfig->config_file);
g_free(cconfig->config_section);
g_free(cconfig->log_facility);
g_free(cconfig->log_mark_prefix);
g_free(cconfig->log_mark_suffix);
g_free(cconfig->pidfile);
}
void config_load(int *argc, char ***argv, GOptionEntry *app_entries, const char *description,
char *default_config, char *default_section,
struct rtpengine_common_config *cconfig)
{
GOptionContext *c;
GError *er = NULL;
const char *use_section;
const char *use_config;
int fatal = 0;
int saved_argc = *argc;
char **saved_argv = g_strdupv(*argv);
rtpe_common_config_ptr = cconfig;
@ -111,8 +121,8 @@ void config_load(int *argc, char ***argv, GOptionEntry *app_entries, const char
#else
rtpe_common_config_ptr->log_level = LOG_DEBUG;
#endif
rtpe_common_config_ptr->log_mark_prefix = "";
rtpe_common_config_ptr->log_mark_suffix = "";
GKeyFile *kf = g_key_file_new();
GOptionEntry shared_options[] = {
{ "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Print build time and exit", NULL },
@ -137,8 +147,9 @@ void config_load(int *argc, char ***argv, GOptionEntry *app_entries, const char
memcpy(entries, shared_options, sizeof(*entries) * shared_len);
memcpy(&entries[shared_len], app_entries, sizeof(*entries) * (app_len + 1));
if (!rtpe_common_config_ptr->config_section)
rtpe_common_config_ptr->config_section = default_section;
use_section = default_section;
if (rtpe_common_config_ptr->config_section)
use_section = rtpe_common_config_ptr->config_section;
c = g_option_context_new(description);
g_option_context_add_main_entries(c, entries, NULL);
@ -154,7 +165,6 @@ void config_load(int *argc, char ***argv, GOptionEntry *app_entries, const char
fatal = 1;
}
GKeyFile *kf = g_key_file_new();
if (!g_key_file_load_from_file(kf, use_config, G_KEY_FILE_NONE, &er)) {
if (!fatal && (g_error_matches(er, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)
|| g_error_matches(er, G_FILE_ERROR, G_FILE_ERROR_NOENT)))
@ -185,14 +195,32 @@ void config_load(int *argc, char ***argv, GOptionEntry *app_entries, const char
CONF_OPTION_GLUE(string_list, char **, NULL);
default:
g_option_context_free(c);
g_strfreev(saved_argv);
g_key_file_free(kf);
free(entries);
config_load_free(rtpe_common_config_ptr);
abort();
}
}
// process CLI arguments again so they override options from the config file
g_option_context_parse(c, &saved_argc, &saved_argv, &er);
g_option_context_parse_strv(c, &saved_argv, &er);
// default common values, if not configured
if (rtpe_common_config_ptr->log_mark_prefix == NULL)
rtpe_common_config_ptr->log_mark_prefix = g_strdup("");
if (rtpe_common_config_ptr->log_mark_suffix == NULL)
rtpe_common_config_ptr->log_mark_suffix = g_strdup("");
out:
g_option_context_free(c);
g_strfreev(saved_argv);
g_key_file_free(kf);
free(entries);
if (version) {
fprintf(stderr, "Version: %s\n", RTPENGINE_VERSION);
exit(0);
@ -218,6 +246,12 @@ out:
return;
err:
g_option_context_free(c);
g_strfreev(saved_argv);
g_key_file_free(kf);
free(entries);
config_load_free(rtpe_common_config_ptr);
die("Bad command line: %s", er->message);
}

@ -42,6 +42,7 @@ extern volatile int rtpe_shutdown;
void daemonize(void);
void wpidfile(void);
void service_notify(const char *message);
void config_load_free(struct rtpengine_common_config *);
void config_load(int *argc, char ***argv, GOptionEntry *entries, const char *description,
char *default_config, char *default_section,
struct rtpengine_common_config *);
@ -64,6 +65,8 @@ int uint32_eq(const void *a, const void *b);
#define AUTO_CLEANUP_INIT(decl, func, val) AUTO_CLEANUP(decl, func) = val
#define AUTO_CLEANUP_NULL(decl, func) AUTO_CLEANUP_INIT(decl, func, 0)
#define AUTO_CLEANUP_BUF(var) AUTO_CLEANUP_NULL(char *var, free_buf)
#define AUTO_CLEANUP_GBUF(var) AUTO_CLEANUP_NULL(char *var, free_gbuf)
#define AUTO_CLEANUP_GVBUF(var) AUTO_CLEANUP_NULL(char **var, free_gvbuf)
/*** STRING HELPERS ***/

@ -32,20 +32,20 @@
int ktable = 0;
int num_threads = 8;
enum output_storage_enum output_storage = OUTPUT_STORAGE_FILE;
const char *spool_dir = "/var/spool/rtpengine";
const char *output_dir = "/var/lib/rtpengine-recording";
static const char *output_format = "wav";
char *spool_dir = NULL;
char *output_dir = NULL;
static char *output_format = NULL;
int output_mixed;
int output_single;
int output_enabled = 1;
int decoding_enabled;
const char *c_mysql_host,
char *c_mysql_host,
*c_mysql_user,
*c_mysql_pass,
*c_mysql_db;
int c_mysql_port;
const char *forward_to = NULL;
static const char *tls_send_to = NULL;
char *forward_to = NULL;
static char *tls_send_to = NULL;
endpoint_t tls_send_to_ep;
int tls_resample = 8000;
@ -144,7 +144,7 @@ static void cleanup(void) {
static void options(int *argc, char ***argv) {
const char *os_str = NULL;
char *os_str = NULL;
GOptionEntry e[] = {
{ "table", 't', 0, G_OPTION_ARG_INT, &ktable, "Kernel table rtpengine uses", "INT" },
@ -171,6 +171,16 @@ static void options(int *argc, char ***argv) {
config_load(argc, argv, e, " - rtpengine recording daemon",
"/etc/rtpengine/rtpengine-recording.conf", "rtpengine-recording", &rtpe_common_config);
// default config, if not configured
if (spool_dir == NULL)
spool_dir = g_strdup("/var/spool/rtpengine");
if (output_dir == NULL)
output_dir = g_strdup("/var/lib/rtpengine-recording");
if (output_format == NULL)
output_format = g_strdup("wav");
if (tls_send_to) {
if (endpoint_parse_any_getaddrinfo_full(&tls_send_to_ep, tls_send_to))
die("Failed to parse 'tls-send-to' option");
@ -202,8 +212,25 @@ static void options(int *argc, char ***argv) {
if ((output_storage & OUTPUT_STORAGE_FILE) && !strcmp(output_dir, spool_dir))
die("The spool-dir cannot be the same as the output-dir");
g_free(os_str);
}
static void options_free(void) {
// free config options
g_free(spool_dir);
g_free(output_dir);
g_free(output_format);
g_free(c_mysql_host);
g_free(c_mysql_user);
g_free(c_mysql_pass);
g_free(c_mysql_db);
g_free(forward_to);
g_free(tls_send_to);
// free common config options
config_load_free(&rtpe_common_config);
}
int main(int argc, char **argv) {
options(&argc, &argv);
@ -223,5 +250,7 @@ int main(int argc, char **argv) {
wait_threads_finish();
options_free();
cleanup();
}

@ -15,18 +15,18 @@ enum output_storage_enum {
extern int ktable;
extern int num_threads;
extern enum output_storage_enum output_storage;
extern const char *spool_dir;
extern const char *output_dir;
extern char *spool_dir;
extern char *output_dir;
extern int output_mixed;
extern int output_single;
extern int output_enabled;
extern int decoding_enabled;
extern const char *c_mysql_host,
extern char *c_mysql_host,
*c_mysql_user,
*c_mysql_pass,
*c_mysql_db;
extern int c_mysql_port;
extern const char *forward_to;
extern char *forward_to;
extern endpoint_t tls_send_to_ep;
extern int tls_resample;

Loading…
Cancel
Save