]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master: master_service_init_finish() now verifies that t_pop() wasn't leaked
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 1 Sep 2016 05:34:22 +0000 (08:34 +0300)
committerGitLab <gitlab@git.dovecot.net>
Fri, 2 Sep 2016 07:50:29 +0000 (10:50 +0300)
src/lib-master/master-service-private.h
src/lib-master/master-service.c

index bb56568136c381ddc721da2edb0df7f0d7947a39..b8b6b1f466366b5d520e6f2749bd83461fd5c000 100644 (file)
@@ -34,6 +34,7 @@ struct master_service {
        ARRAY_TYPE(const_string) config_overrides;
        int config_fd;
        int syslog_facility;
+       data_stack_frame_t datastack_frame_id;
 
        struct master_service_listener *listeners;
        unsigned int socket_count;
index 0c5d355cd7ab0b50dc618a1dcf30fd153d122b9c..edbb2cb1cab4615e5a6368cfc7699cc0a3f01fb8 100644 (file)
@@ -152,6 +152,7 @@ master_service_init(const char *name, enum master_service_flags flags,
                    int *argc, char **argv[], const char *getopt_str)
 {
        struct master_service *service;
+       data_stack_frame_t datastack_frame_id = 0;
        unsigned int count;
        const char *value;
 
@@ -186,7 +187,7 @@ master_service_init(const char *name, enum master_service_flags flags,
           before we get to ioloop. the corresponding t_pop() is in
           master_service_init_finish(). */
        if ((flags & MASTER_SERVICE_FLAG_NO_INIT_DATASTACK_FRAME) == 0)
-               t_push(NULL);
+               datastack_frame_id = t_push(NULL);
 
        /* ignore these signals as early as possible */
        lib_signals_init();
@@ -210,6 +211,7 @@ master_service_init(const char *name, enum master_service_flags flags,
        service->ioloop = io_loop_create();
        service->service_count_left = UINT_MAX;
        service->config_fd = -1;
+       service->datastack_frame_id = datastack_frame_id;
 
        service->config_path = i_strdup(getenv(MASTER_CONFIG_FILE_ENV));
        if (service->config_path == NULL)
@@ -532,8 +534,10 @@ void master_service_init_finish(struct master_service *service)
        master_status_update(service);
 
        /* close data stack frame opened by master_service_init() */
-       if ((service->flags & MASTER_SERVICE_FLAG_NO_INIT_DATASTACK_FRAME) == 0)
-               t_pop();
+       if ((service->flags & MASTER_SERVICE_FLAG_NO_INIT_DATASTACK_FRAME) == 0) {
+               if (t_pop() != service->datastack_frame_id)
+                       i_panic("Leaked t_pop() call");
+       }
 }
 
 void master_service_env_clean(void)