[-- Attachment #1.1: Type: text/plain, Size: 2423 bytes --] Hi, libnotmuch 5.5.0 (notmuch 0.34.2) leaks memory when opening a database with 'notmuch_database_open_with_config()' and cleaning it up with 'notmuch_database_destroy()'. I've included a reproducer program (based on an existing notmuch test) and ASAN output below. Replacing 'notmuch_database_destroy()' with 'notmuch_database_close()' or omitting the database clean-up entirely resolves all but the first ASAN entry. There's no leak if 'notmuch_database_open_with_config()' returns an error. Thanks! Austin Reproducer program: #include <notmuch.h> #include <stdio.h> int main(int argc, char **argv) { notmuch_database_t *db = NULL; notmuch_status_t st = notmuch_database_open_with_config( argv[1], NOTMUCH_DATABASE_MODE_READ_ONLY, argv[2], NULL, &db, NULL); if (db != NULL) { notmuch_database_destroy(db); } printf("db != NULL: %d\n", db != NULL); } ASAN output: ================================================================= ==1059281==ERROR: LeakSanitizer: detected memory leaks Direct leak of 32 byte(s) in 1 object(s) allocated from: #0 0x7fb9d1230777 in __interceptor_malloc (/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/libasan.so.6+0xb6777) #1 0x7fb9d0a2b098 in g_malloc (/usr/lib64/libglib-2.0.so.0+0x5b098) Direct leak of 8 byte(s) in 1 object(s) allocated from: #0 0x7fb9d1232137 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/libasan.so.6+0xb8137) #1 0x7fb9d1164ef4 (/usr/lib64/libnotmuch.so.5+0x2aef4) #2 0x7fb9d1165abc in notmuch_database_open_with_config (/usr/lib64/libnotmuch.so.5+0x2babc) Indirect leak of 56 byte(s) in 1 object(s) allocated from: #0 0x7fb9d1232137 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/libasan.so.6+0xb8137) #1 0x7fb9d08ef849 (/usr/lib64/libxapian.so.30+0x15d849) #2 0x7fb9d1165abc in notmuch_database_open_with_config (/usr/lib64/libnotmuch.so.5+0x2babc) Indirect leak of 25 byte(s) in 1 object(s) allocated from: #0 0x7fb9d1230777 in __interceptor_malloc (/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/libasan.so.6+0xb6777) #1 0x7fb9d08efded (/usr/lib64/libxapian.so.30+0x15dded) SUMMARY: AddressSanitizer: 121 byte(s) leaked in 4 allocation(s). -- https://austinray.io Open Source Maintainer, Software Engineer, Keyboard Enthusiast GPG: 0127 ED83 B939 CCC9 8082 476E 1AA0 B115 C8AC 2C9E [-- Attachment #1.2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] [-- Attachment #2: Type: text/plain, Size: 0 bytes --]
In [1] Austin Ray reported some memory leaks in notmuch_database_open. One of those leaks is caused by jumping to the next key without freeing val. This change avoids that leak. [1]: id:20220105224538.m36lnjn7rf3ieonc@athena --- lib/config.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/config.cc b/lib/config.cc index 7a2882de..b9e11a54 100644 --- a/lib/config.cc +++ b/lib/config.cc @@ -435,11 +435,6 @@ _notmuch_config_load_from_file (notmuch_database_t *notmuch, for (gchar **keys_p = keys; *keys_p; keys_p++) { char *absolute_key = talloc_asprintf (notmuch, "%s.%s", *grp, *keys_p); char *normalized_val; - val = g_key_file_get_string (file, *grp, *keys_p, NULL); - if (! val) { - status = NOTMUCH_STATUS_FILE_ERROR; - goto DONE; - } /* If we opened from a given path, do not overwrite it */ if (strcmp (absolute_key, "database.path") == 0 && @@ -447,6 +442,12 @@ _notmuch_config_load_from_file (notmuch_database_t *notmuch, notmuch->xapian_db) continue; + val = g_key_file_get_string (file, *grp, *keys_p, NULL); + if (! val) { + status = NOTMUCH_STATUS_FILE_ERROR; + goto DONE; + } + normalized_val = _expand_path (notmuch, absolute_key, val); _notmuch_string_map_set (notmuch->config, absolute_key, normalized_val); g_free (val); -- 2.34.1
Commit 3202e0d1feba1ab955ba1c07098c00208f8f0ada left the stemmer object accessible, but did not add de-allocation code to notmuch_database_destroy. This commit corrects that oversight. --- lib/database.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/database.cc b/lib/database.cc index 6ef56d56..a012ebcf 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -753,6 +753,8 @@ notmuch_database_destroy (notmuch_database_t *notmuch) notmuch->date_range_processor = NULL; delete notmuch->last_mod_range_processor; notmuch->last_mod_range_processor = NULL; + delete notmuch->stemmer; + notmuch->stemmer = NULL; talloc_free (notmuch); -- 2.34.1
Austin Ray <austin@austinray.io> writes:
> Hi,
>
> libnotmuch 5.5.0 (notmuch 0.34.2) leaks memory when opening a database
> with 'notmuch_database_open_with_config()' and cleaning it up with
> 'notmuch_database_destroy()'. I've included a reproducer program (based
> on an existing notmuch test) and ASAN output below.
>
> Replacing 'notmuch_database_destroy()' with 'notmuch_database_close()'
> or omitting the database clean-up entirely resolves all but the first
> ASAN entry. There's no leak if 'notmuch_database_open_with_config()'
> returns an error.
>
> Thanks!
>
> Austin
In id:20220122205416.nbxqdcapjab62iln@athena Austin confirmed these leaks
were fixed as of 2786aa4d548d28579c761e9358d44c84dfb29068