From: Marko Kreen Date: Mon, 25 Jan 2016 12:09:35 +0000 (+0200) Subject: Clean allocated memory on exit. X-Git-Tag: pgbouncer_1_7_1~19 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f98fc6d4806a01b5508f1a0faeecc867d74288e6;p=pgbouncer Clean allocated memory on exit. Helps to track potential memory leaks. --- diff --git a/include/admin.h b/include/admin.h index 188f255..87d7ee9 100644 --- a/include/admin.h +++ b/include/admin.h @@ -24,4 +24,5 @@ void admin_pause_done(void); bool admin_flush(PgSocket *admin, PktBuf *buf, const char *desc) /* _MUSTCHECK */; bool admin_ready(PgSocket *admin, const char *desc) _MUSTCHECK; void admin_handle_cancel(PgSocket *client); +void admin_cleanup(void); diff --git a/include/objects.h b/include/objects.h index 23a5df8..aec960c 100644 --- a/include/objects.h +++ b/include/objects.h @@ -83,3 +83,5 @@ void init_objects(void); void init_caches(void); +void objects_cleanup(void); + diff --git a/include/pktbuf.h b/include/pktbuf.h index 1e52649..e232e50 100644 --- a/include/pktbuf.h +++ b/include/pktbuf.h @@ -146,5 +146,5 @@ void pktbuf_write_ExtQuery(PktBuf *buf, const char *query, int nargs, ...); #define SEND_PasswordMessage(res, sk, psw) \ SEND_wrap(512, pktbuf_write_PasswordMessage, res, sk, psw) - +void pktbuf_cleanup(void); diff --git a/include/sbuf.h b/include/sbuf.h index 7503231..cd54b08 100644 --- a/include/sbuf.h +++ b/include/sbuf.h @@ -147,3 +147,5 @@ static inline int sbuf_op_close(SBuf *sbuf) return sbuf->ops->sbufio_close(sbuf); } +void sbuf_cleanup(void); + diff --git a/include/varcache.h b/include/varcache.h index 4984b01..51a330a 100644 --- a/include/varcache.h +++ b/include/varcache.h @@ -19,4 +19,5 @@ bool varcache_apply(PgSocket *server, PgSocket *client, bool *changes_p) _MUSTCH void varcache_fill_unset(VarCache *src, PgSocket *dst); void varcache_clean(VarCache *cache); void varcache_add_params(PktBuf *pkt, VarCache *vars); +void varcache_deinit(void); diff --git a/src/admin.c b/src/admin.c index d23d24b..735a21a 100644 --- a/src/admin.c +++ b/src/admin.c @@ -69,6 +69,14 @@ static PgPool *admin_pool; /* only valid during processing */ static const char *current_query; +void admin_cleanup(void) +{ + regfree(&rc_cmd); + regfree(&rc_set_str); + regfree(&rc_set_word); + admin_pool = NULL; +} + static bool syntax_error(PgSocket *admin) { return admin_error(admin, "invalid command '%s', use SHOW HELP;", diff --git a/src/main.c b/src/main.c index 78039bd..128d854 100644 --- a/src/main.c +++ b/src/main.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef HAVE_SYS_RESOURCE_H #include @@ -554,9 +555,12 @@ static void go_daemon(void) static void remove_pidfile(void) { - if (!cf_pidfile[0]) - return; - unlink(cf_pidfile); + if (cf_pidfile) { + if (cf_pidfile[0]) + unlink(cf_pidfile); + free(cf_pidfile); + cf_pidfile = NULL; + } } static void check_pidfile(void) @@ -733,6 +737,64 @@ static void dns_setup(void) fatal_perror("dns setup failed"); } +static void xfree(char **ptr_p) +{ + if (*ptr_p) { + free(*ptr_p); + *ptr_p = NULL; + } +} + +static void cleanup(void) +{ + adns_free_context(adns); + adns = NULL; + + admin_cleanup(); + objects_cleanup(); + sbuf_cleanup(); + + event_base_free(NULL); + + tls_deinit(); + varcache_deinit(); + pktbuf_cleanup(); + + reset_logging(); + + xfree(&cf_username); + xfree(&cf_config_file); + xfree(&cf_listen_addr); + xfree(&cf_unix_socket_dir); + xfree(&cf_unix_socket_group); + xfree(&cf_auth_file); + xfree(&cf_auth_hba_file); + xfree(&cf_auth_query); + xfree(&cf_server_reset_query); + xfree(&cf_server_check_query); + xfree(&cf_ignore_startup_params); + xfree(&cf_autodb_connstr); + xfree(&cf_jobname); + xfree(&cf_admin_users); + xfree(&cf_stats_users); + xfree(&cf_client_tls_protocols); + xfree(&cf_client_tls_ca_file); + xfree(&cf_client_tls_cert_file); + xfree(&cf_client_tls_key_file); + xfree(&cf_client_tls_ciphers); + xfree(&cf_client_tls_dheparams); + xfree(&cf_client_tls_ecdhecurve); + xfree(&cf_server_tls_protocols); + xfree(&cf_server_tls_ca_file); + xfree(&cf_server_tls_cert_file); + xfree(&cf_server_tls_key_file); + xfree(&cf_server_tls_ciphers); + + xfree((char **)&cf_logfile); + xfree((char **)&cf_syslog_ident); + xfree((char **)&cf_syslog_facility); +} + /* boot everything */ int main(int argc, char *argv[]) { @@ -857,6 +919,8 @@ int main(int argc, char *argv[]) while (cf_shutdown < 2) main_loop_once(); + cleanup(); + return 0; } diff --git a/src/objects.c b/src/objects.c index 281c420..93eaa88 100644 --- a/src/objects.c +++ b/src/objects.c @@ -1585,3 +1585,39 @@ void reuse_just_freed_objects(void) } } +void objects_cleanup(void) +{ + struct List *item; + PgDatabase *db; + + /* close can be postpones, just in case call twice */ + reuse_just_freed_objects(); + reuse_just_freed_objects(); + + statlist_for_each(item, &database_list) { + db = container_of(item, PgDatabase, head); + db->db_dead = 1; + } + config_postprocess(); + + memset(&login_client_list, 0, sizeof login_client_list); + memset(&user_list, 0, sizeof user_list); + memset(&database_list, 0, sizeof database_list); + memset(&pool_list, 0, sizeof pool_list); + memset(&user_tree, 0, sizeof user_tree); + memset(&autodatabase_idle_list, 0, sizeof autodatabase_idle_list); + + slab_destroy(server_cache); + server_cache = NULL; + slab_destroy(client_cache); + client_cache = NULL; + slab_destroy(db_cache); + db_cache = NULL; + slab_destroy(pool_cache); + pool_cache = NULL; + slab_destroy(user_cache); + user_cache = NULL; + slab_destroy(iobuf_cache); + iobuf_cache = NULL; +} + diff --git a/src/pktbuf.c b/src/pktbuf.c index 4111c77..685d52e 100644 --- a/src/pktbuf.c +++ b/src/pktbuf.c @@ -73,10 +73,10 @@ void pktbuf_static(PktBuf *buf, uint8_t *data, int len) buf->fixed_buf = 1; } +static PktBuf *temp_pktbuf; + struct PktBuf *pktbuf_temp(void) { - static PktBuf *temp_pktbuf; - if (!temp_pktbuf) temp_pktbuf = pktbuf_dynamic(512); if (!temp_pktbuf) @@ -85,6 +85,12 @@ struct PktBuf *pktbuf_temp(void) return temp_pktbuf; } +void pktbuf_cleanup(void) +{ + pktbuf_free(temp_pktbuf); + temp_pktbuf = NULL; +} + bool pktbuf_send_immediate(PktBuf *buf, PgSocket *sk) { uint8_t *pos = buf->buf + buf->send_pos; diff --git a/src/sbuf.c b/src/sbuf.c index 5c89ffe..199e728 100644 --- a/src/sbuf.c +++ b/src/sbuf.c @@ -1148,10 +1148,24 @@ static int tls_sbufio_close(struct SBuf *sbuf) return 0; } +void sbuf_cleanup(void) +{ + tls_free(client_accept_base); + tls_config_free(client_accept_conf); + tls_config_free(server_connect_conf); + client_accept_conf = NULL; + server_connect_conf = NULL; + client_accept_base = NULL; +} + #else void sbuf_tls_setup(void) { } bool sbuf_tls_accept(SBuf *sbuf) { return false; } bool sbuf_tls_connect(SBuf *sbuf, const char *hostname) { return false; } +void sbuf_cleanup(void) +{ +} + #endif diff --git a/src/varcache.c b/src/varcache.c index 6321dc5..cbc19ed 100644 --- a/src/varcache.c +++ b/src/varcache.c @@ -177,3 +177,9 @@ void varcache_add_params(PktBuf *pkt, VarCache *vars) } } +void varcache_deinit(void) +{ + strpool_free(vpool); + vpool = NULL; +} +