Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a48c894

Browse files
tglsfdcCommitfest Bot
authored and
Commitfest Bot
committed
Suppress complaints about leaks in TS dictionary loading.
Like the situation with function cache loading, text search dictionary loading functions tend to leak some cruft into the dictionary's long-lived cache context. To judge by the examples in the core regression tests, not very many bytes are at stake. Moreover, I don't see a way to prevent such leaks without changing the API for TS template initialization functions: right now they do not have to worry about making sure that their results are long-lived. Hence, I think we should install a suppression rule rather than trying to fix this completely. However, I did grab some low-hanging fruit: several places were leaking the result of get_tsearch_config_filename. This seems worth doing mostly because they are inconsistent with other dictionaries that were freeing it already. Author: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/285483.1746756246@sss.pgh.pa.us
1 parent ea2f5fa commit a48c894

File tree

5 files changed

+32
-10
lines changed

5 files changed

+32
-10
lines changed

src/backend/tsearch/dict_ispell.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,24 +47,30 @@ dispell_init(PG_FUNCTION_ARGS)
4747

4848
if (strcmp(defel->defname, "dictfile") == 0)
4949
{
50+
char *filename;
51+
5052
if (dictloaded)
5153
ereport(ERROR,
5254
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5355
errmsg("multiple DictFile parameters")));
54-
NIImportDictionary(&(d->obj),
55-
get_tsearch_config_filename(defGetString(defel),
56-
"dict"));
56+
filename = get_tsearch_config_filename(defGetString(defel),
57+
"dict");
58+
NIImportDictionary(&(d->obj), filename);
59+
pfree(filename);
5760
dictloaded = true;
5861
}
5962
else if (strcmp(defel->defname, "afffile") == 0)
6063
{
64+
char *filename;
65+
6166
if (affloaded)
6267
ereport(ERROR,
6368
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6469
errmsg("multiple AffFile parameters")));
65-
NIImportAffixes(&(d->obj),
66-
get_tsearch_config_filename(defGetString(defel),
67-
"affix"));
70+
filename = get_tsearch_config_filename(defGetString(defel),
71+
"affix");
72+
NIImportAffixes(&(d->obj), filename);
73+
pfree(filename);
6874
affloaded = true;
6975
}
7076
else if (strcmp(defel->defname, "stopwords") == 0)

src/backend/tsearch/dict_synonym.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ dsynonym_init(PG_FUNCTION_ARGS)
199199
}
200200

201201
tsearch_readline_end(&trst);
202+
pfree(filename);
202203

203204
d->len = cur;
204205
qsort(d->syn, d->len, sizeof(Syn), compareSyn);

src/backend/tsearch/dict_thesaurus.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,17 +167,17 @@ addWrd(DictThesaurus *d, char *b, char *e, uint32 idsubst, uint16 nwrd, uint16 p
167167
static void
168168
thesaurusRead(const char *filename, DictThesaurus *d)
169169
{
170+
char *real_filename = get_tsearch_config_filename(filename, "ths");
170171
tsearch_readline_state trst;
171172
uint32 idsubst = 0;
172173
bool useasis = false;
173174
char *line;
174175

175-
filename = get_tsearch_config_filename(filename, "ths");
176-
if (!tsearch_readline_begin(&trst, filename))
176+
if (!tsearch_readline_begin(&trst, real_filename))
177177
ereport(ERROR,
178178
(errcode(ERRCODE_CONFIG_FILE_ERROR),
179179
errmsg("could not open thesaurus file \"%s\": %m",
180-
filename)));
180+
real_filename)));
181181

182182
while ((line = tsearch_readline(&trst)) != NULL)
183183
{
@@ -297,6 +297,7 @@ thesaurusRead(const char *filename, DictThesaurus *d)
297297
d->nsubst = idsubst;
298298

299299
tsearch_readline_end(&trst);
300+
pfree(real_filename);
300301
}
301302

302303
static TheLexeme *

src/backend/utils/cache/ts_cache.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,9 @@ lookup_ts_dictionary_cache(Oid dictId)
321321

322322
/*
323323
* Init method runs in dictionary's private memory context, and we
324-
* make sure the options are stored there too
324+
* make sure the options are stored there too. This typically
325+
* results in a small amount of memory leakage, but it's not worth
326+
* complicating the API for tmplinit functions to avoid it.
325327
*/
326328
oldcontext = MemoryContextSwitchTo(entry->dictCtx);
327329

src/tools/valgrind.supp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,15 @@
201201
...
202202
fun:cached_function_compile
203203
}
204+
205+
# Suppress complaints about stuff leaked during TS dictionary loading.
206+
# Not very much is typically lost there, and preventing it would
207+
# require a risky API change for TS tmplinit functions.
208+
{
209+
hide_ts_dictionary_leaks
210+
Memcheck:Leak
211+
match-leak-kinds: definite,possible,indirect
212+
213+
...
214+
fun:lookup_ts_dictionary_cache
215+
}

0 commit comments

Comments
 (0)