]> granicus.if.org Git - pgbouncer/commitdiff
Clean allocated memory on exit.
authorMarko Kreen <markokr@gmail.com>
Mon, 25 Jan 2016 12:09:35 +0000 (14:09 +0200)
committerMarko Kreen <markokr@gmail.com>
Mon, 25 Jan 2016 12:09:35 +0000 (14:09 +0200)
Helps to track potential memory leaks.

include/admin.h
include/objects.h
include/pktbuf.h
include/sbuf.h
include/varcache.h
src/admin.c
src/main.c
src/objects.c
src/pktbuf.c
src/sbuf.c
src/varcache.c

index 188f255daa98207617efcf6dc7f90fba4439e685..87d7ee9c3ed6cf885253c3dde62f49d9f6a78cb0 100644 (file)
@@ -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);
 
index 23a5df8fd183bfc6c56b3215a6a60e8977a712c8..aec960cffd7dfe051e146c281030c2d7076ec856 100644 (file)
@@ -83,3 +83,5 @@ void init_objects(void);
 
 void init_caches(void);
 
+void objects_cleanup(void);
+
index 1e52649a7e3f4616f0732da25cd482c60f595886..e232e50e48ee784e7fa9834957e63cc56f12b44c 100644 (file)
@@ -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);
 
index 75032313cddbce51a53ed75d22d88c73cf5696f5..cd54b088c58b4b4d27c5c6b16f9d07ab65ab645e 100644 (file)
@@ -147,3 +147,5 @@ static inline int sbuf_op_close(SBuf *sbuf)
        return sbuf->ops->sbufio_close(sbuf);
 }
 
+void sbuf_cleanup(void);
+
index 4984b0179025c3c328cceee96e992f876926d316..51a330a7c35a511529242e6c4ff618527bd4384f 100644 (file)
@@ -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);
 
index d23d24b9e7637bcda111158e628ff9b7a6f34d48..735a21a595afbc337fbad56753f7914be8f9ba34 100644 (file)
@@ -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;",
index 78039bd283687001312e30ec6269856eb001564e..128d85470e44389d276ad61d7953c89e0b00a73e 100644 (file)
@@ -26,6 +26,7 @@
 #include <usual/err.h>
 #include <usual/cfparser.h>
 #include <usual/getopt.h>
+#include <usual/slab.h>
 
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
@@ -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;
 }
 
index 281c4207718986fd73a82807a0028bbbe80651cc..93eaa8890eecd51867768c0cca08c2f5c791fcbc 100644 (file)
@@ -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;
+}
+
index 4111c77d01fdd34f70a2b881a8be68a9af10ce5b..685d52ebbff7b776028eba436a1c1ea55cc65a2a 100644 (file)
@@ -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;
index 5c89ffec0343c5f2dfc2132e4783d1a1e590f8c6..199e72853c339624d05db53053de035a30ad1683 100644 (file)
@@ -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
index 6321dc537c3dc42a2874b9b422458e8a52f6ca2c..cbc19ed6daaea6263d4a993e21da03cebf7102a6 100644 (file)
@@ -177,3 +177,9 @@ void varcache_add_params(PktBuf *pkt, VarCache *vars)
        }
 }
 
+void varcache_deinit(void)
+{
+       strpool_free(vpool);
+       vpool = NULL;
+}
+