git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 2/4] SANITIZE tests: fix memory leaks in t13*config*, add to whitelist

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Sep 1, 2021, 11:45 UTC
Message-ID
<875yvkwllw.fsf@evledraar.gmail.com>
In-Reply-To
<YS8xj9XtKqEEy/Bb@coredump.intra.peff.net>
On Wed, Sep 01 2021, Jeff King wrote:
Show 33 quoted lines
> On Tue, Aug 31, 2021 at 02:47:01PM +0200, Ævar Arnfjörð Bjarmason wrote:
>
>> > That works, but now "util" is not available for all the _other_ uses for
>> > which it was intended. And if we're not using it for those other uses,
>> > then why does it need to exist at all? If we are only using it to hold
>> > the allocated string pointer, then shouldn't it be "char *to_free"?
>> 
>> Because having it be "char *" doesn't cover the common case of
>> e.g. getting an already allocated "struct something *" which contains
>> your string, setting the "string" in "struct string_list_item" to some
>> string in that struct, and the "util" to the struct itself, as we now
>> own it and want to free() it later in its entirety.
>
> OK. I buy that storing a void pointer makes it more flexible. I'm not
> altogether convinced this pattern is especially common, but it's not any
> harder to work with than a "need_to_free" flag, so there's no reason not
> to do that (and to be fair, I didn't look around for possible uses of
> the pattern; it's just not one I think of as common off the top of my
> head).
>
>> That and the even more common case I mentioned upthread of wanting to
>> ferry around the truncated version of some char *, but still wanting to
>> account for the original for an eventual free().
>> 
>> But yes, if you want to account for freeing that data *and* have util
>> set to something else you'll need to have e.g. your own wrapper struct
>> and your own string_list_clear_func() callback.
>
> But stuffing it into the util field of string_list really feels like a
> stretch, and something that would make existing string_list use painful.
> There are tons of cases where util points to some totally unrelated (in
> terms of memory ownership) item. I'd venture to say most cases where
> string_list_clear() is called without free_util would count here.

For what it's worth I've got some WIP code that's part of my daily build where I did end up going through all those callers, as part of general string_list_clear() improvements mentioned offhand in https://lore.kernel.org/git/87bl6kq631.fsf@evledraar.gmail.com/

This is just from fuzzy memory & I can't recall the specifics (and haven't combed through that WIP code now), but it's something like that in the ~100 uses of string_list in our codebase 60-70% are the simple case where the "strdup_strings" and string_list_clear() is enough, maybe another 10-20% have a "util" field they manage or not, 5%-ish have a simple string_list_clear_func().

It was just 2-3 cases that leaked memory due to skipping a prefix and sticking it in the list, and maybe another 1-2 where the void* to a struct containing the string stuck into the string slot was something we could use.

So it's not "common" in the sense of absolute numbers, but I did run into a handful of them, and having them handled by having the string_list take an arbitrary "util" was something I found neat.

I should probably have said "well known" (as in "well known technique"), "idiomatic" or something...

Show 25 quoted lines
>> > I don't think most interfaces take a string_list_item now, so wouldn't
>> > they similarly need to be changed? Though the point is that all of these
>> > degrade to a regular C-string, so when you are just passing the value
>> > (and not ownership), you would just dereference at that point.
>> 
>> Sure, just like things would need to be changed to handle your proposed
>> "struct def_string".
>> 
>> By piggy-backing on an already used struct in our codebase we can get a
>> lot of that memory management pretty much for free without much
>> churn.
>> 
>> If you squint and pretend that "struct string_list_item" isn't called
>> something to do with that particular collections API (but it would make
>> use of it) then we've already set up most of the scaffolding and
>> management for this.
>
> It's that squinting that bothers me. Sure, it's _kinda_ similar. And I
> don't have any problem with some kind of struct that says "this is a
> string, and when you are done with it, this is how you free it". And I
> don't have any problem with building the "dup" version of string_list
> with that struct as a primitive. But it seems to me to be orthogonal
> from the "util" pointer of a string_list, which is about creating a
> mapping from the string to some other thing (which may or may not
> contain the string, and may or may not be owned).

The "util" is whatever the user makes it. We could add a "pointer_to_free" to every container type to solve this more cleanly/generally at the API level, but just handing the problem to the user seems better to me. I.e. an API like string_list has convenience functions for freeing all the "util", if you only need it for memory tracking use it as-is, if you need a "real util" *and* such tracking just create a 2-member wrapper struct yourself & use that.

Show 6 quoted lines
> TBH, I have always found the "util" field of string_list a bit ugly (and
> really most of string_list). I think most cases would be better off with
> a different data structure (a set or a hash table), but we didn't have
> convenient versions of those for a long time. I don't mind seeing
> conversions of string_list to other data structures. But that seems to
> be working against using string_list's string struct in more places.

If we followed my idle musings we'd be using string_list_item in more places, not necessarily string_list, and would rename s/string_list_item/string_and_util/ or something.

One way to look at this problem is that we're pretty close to just re-inventing the sort of generalized refcounted container type that some programming languages carry around. E.g. Perl has a "struct SV*" that a $string maps to, but also hash and array values etc.

Those languages usually have a "refcount" or whatever, but since we're using this in native C and it's usually (or at least should be) clear who owns the memory just having something to point free() at will do.

I'm just saying that if we're going halfway there it would be unfortunate if we'd end up with a "struct def_string" which wouldn't handle this "borrowing a string from a struct" case.

Or maybe we should just use "struct strbuf" and do copying in even more places...

Previous: Jeff KingNext: Ævar Arnfjörð Bjarmason
Message 39 of 125 in “UNLEAK(), leak checking in the default tests etc.”
  1. Ævar Arnfjörð BjarmasonJun 9, 2021
  2. Andrzej HuntJun 9, 2021
  3. Felipe ContrerasJun 9, 2021
  4. Jeff KingJun 10, 2021
  5. Ævar Arnfjörð BjarmasonJun 10, 2021
  6. Jeff KingJun 10, 2021
  7. Andrzej HuntJun 10, 2021
  8. Jeff KingJun 10, 2021
  9. Andrzej HuntJun 11, 2021
  10. SZEDER GáborJun 10, 2021
  11. 0/4 add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Jul 14, 2021
  12. 1/4 tests: add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Jul 14, 2021
  13. Đoàn Trần Công DanhJul 14, 2021
  14. 2/4 SANITIZE tests: fix memory leaks in t13*config*, add to whitelistÆvar Arnfjörð Bjarmason, Jul 14, 2021
  15. 3/4 SANITIZE tests: fix memory leaks in t5701*, add to whitelistÆvar Arnfjörð Bjarmason, Jul 14, 2021
  16. 4/4 SANITIZE tests: fix leak in mailmap.cÆvar Arnfjörð Bjarmason, Jul 14, 2021
  17. Eric SunshineJul 14, 2021
  18. 0/4 add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Jul 14, 2021
  19. 1/4 tests: add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Jul 14, 2021
  20. Andrzej HuntJul 14, 2021
  21. Ævar Arnfjörð BjarmasonJul 14, 2021
  22. Jeff KingJul 15, 2021
  23. Jeff KingJul 15, 2021
  24. Ævar Arnfjörð BjarmasonJul 16, 2021
  25. Jeff KingJul 16, 2021
  26. Jeff KingJul 16, 2021
  27. Ævar Arnfjörð BjarmasonJul 16, 2021
  28. Jeff KingJul 16, 2021
  29. 2/4 SANITIZE tests: fix memory leaks in t13*config*, add to whitelistÆvar Arnfjörð Bjarmason, Jul 14, 2021
  30. Andrzej HuntJul 14, 2021
  31. Ævar Arnfjörð BjarmasonJul 14, 2021
  32. Jeff KingJul 15, 2021
  33. Andrzej HuntJul 16, 2021
  34. Jeff KingJul 16, 2021
  35. Ævar Arnfjörð BjarmasonJul 16, 2021
  36. Jeff KingJul 16, 2021
  37. Ævar Arnfjörð BjarmasonAug 31, 2021
  38. Jeff KingSep 1, 2021
  39. Ævar Arnfjörð BjarmasonSep 1, 2021
  40. 3/4 SANITIZE tests: fix memory leaks in t5701*, add to whitelistÆvar Arnfjörð Bjarmason, Jul 14, 2021
  41. Andrzej HuntJul 15, 2021
  42. Jeff KingJul 15, 2021
  43. protocol-caps.c: fix memory leak in send_info()Ævar Arnfjörð Bjarmason, Aug 31, 2021
  44. Bruno AlbuquerqueAug 31, 2021
  45. Junio C HamanoAug 31, 2021
  46. 4/4 SANITIZE tests: fix leak in mailmap.cÆvar Arnfjörð Bjarmason, Jul 14, 2021
  47. mailmap.c: fix a memory leak in free_mailap_{info,entry}()Ævar Arnfjörð Bjarmason, Aug 31, 2021
  48. Eric SunshineAug 31, 2021
  49. Jeff KingAug 31, 2021
  50. Junio C HamanoAug 31, 2021
  51. Andrzej HuntJul 15, 2021
  52. 0/8 add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Aug 31, 2021
  53. Jeff KingSep 1, 2021
  54. Jeff KingSep 1, 2021
  55. Ævar Arnfjörð BjarmasonSep 2, 2021
  56. Jeff KingSep 3, 2021
  57. 0/3 add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Sep 7, 2021
  58. 1/3 Makefile: add SANITIZE=leak flag to GIT-BUILD-OPTIONSÆvar Arnfjörð Bjarmason, Sep 7, 2021
  59. 2/3 CI: refactor "if" to "case" statementÆvar Arnfjörð Bjarmason, Sep 7, 2021
  60. 3/3 tests: add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Sep 7, 2021
  61. Eric SunshineSep 7, 2021
  62. Jeff KingSep 7, 2021
  63. Jeff KingSep 7, 2021
  64. Junio C HamanoSep 7, 2021
  65. 0/3 add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Sep 7, 2021
  66. 1/3 Makefile: add SANITIZE=leak flag to GIT-BUILD-OPTIONSÆvar Arnfjörð Bjarmason, Sep 7, 2021
  67. 2/3 CI: refactor "if" to "case" statementÆvar Arnfjörð Bjarmason, Sep 7, 2021
  68. 3/3 tests: add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Sep 7, 2021
  69. Eric SunshineSep 8, 2021
  70. fixup! tests: add a test mode for SANITIZE=leak, run it in CICarlo Marcelo Arenas Belón, Sep 16, 2021
  71. Ævar Arnfjörð BjarmasonSep 16, 2021
  72. Junio C HamanoSep 8, 2021
  73. Ævar Arnfjörð BjarmasonSep 8, 2021
  74. Emily ShafferSep 9, 2021
  75. 0/2 add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Sep 16, 2021
  76. 1/2 Makefile: add SANITIZE=leak flag to GIT-BUILD-OPTIONSÆvar Arnfjörð Bjarmason, Sep 16, 2021
  77. 2/2 tests: add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Sep 16, 2021
  78. 0/2 add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Sep 19, 2021
  79. 2/2 tests: add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Sep 19, 2021
  80. fixup! tests: add a test mode for SANITIZE=leak, run it in CICarlo Marcelo Arenas Belón, Sep 22, 2021
  81. Ævar Arnfjörð BjarmasonSep 23, 2021
  82. 1/2 Makefile: add SANITIZE=leak flag to GIT-BUILD-OPTIONSÆvar Arnfjörð Bjarmason, Sep 19, 2021
  83. 0/2 add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Sep 23, 2021
  84. 1/2 Makefile: add SANITIZE=leak flag to GIT-BUILD-OPTIONSÆvar Arnfjörð Bjarmason, Sep 23, 2021
  85. 2/2 tests: add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Sep 23, 2021
  86. Re* [PATCH v8 2/2] tests: add a test mode for SANITIZE=leak, run it in CIJunio C Hamano, Nov 3, 2021
  87. Junio C HamanoNov 3, 2021
  88. Ævar Arnfjörð BjarmasonNov 4, 2021
  89. t0006: date_mode can leak .strftime_fmt memberÆvar Arnfjörð Bjarmason, Nov 16, 2021
  90. Junio C HamanoNov 16, 2021
  91. Jeff KingNov 16, 2021
  92. 0/5 date.[ch] API: split from cache.h, add API docs, stop leaking memoryÆvar Arnfjörð Bjarmason, Feb 2, 2022
  93. 1/5 cache.h: remove always unused show_date_human() declarationÆvar Arnfjörð Bjarmason, Feb 2, 2022
  94. 2/5 date API: create a date.h, split from cache.hÆvar Arnfjörð Bjarmason, Feb 2, 2022
  95. Ævar Arnfjörð BjarmasonFeb 2, 2022
  96. Junio C HamanoFeb 15, 2022
  97. 3/5 date API: provide and use a DATE_MODE_INITÆvar Arnfjörð Bjarmason, Feb 2, 2022
  98. 4/5 date API: add basic API docsÆvar Arnfjörð Bjarmason, Feb 2, 2022
  99. Junio C HamanoFeb 15, 2022
  100. 5/5 date API: add and use a date_mode_release()Ævar Arnfjörð Bjarmason, Feb 2, 2022
  101. Junio C HamanoFeb 15, 2022
  102. 0/5 date.[ch] API: split from cache.h, add API docs, stop leaking memoryÆvar Arnfjörð Bjarmason, Feb 4, 2022
  103. 1/5 cache.h: remove always unused show_date_human() declarationÆvar Arnfjörð Bjarmason, Feb 4, 2022
  104. 2/5 date API: create a date.h, split from cache.hÆvar Arnfjörð Bjarmason, Feb 4, 2022
  105. 3/5 date API: provide and use a DATE_MODE_INITÆvar Arnfjörð Bjarmason, Feb 4, 2022
  106. 4/5 date API: add basic API docsÆvar Arnfjörð Bjarmason, Feb 4, 2022
  107. 5/5 date API: add and use a date_mode_release()Ævar Arnfjörð Bjarmason, Feb 4, 2022
  108. Ævar Arnfjörð BjarmasonFeb 14, 2022
  109. Junio C HamanoFeb 14, 2022
  110. 0/5 date.[ch] API: split from cache.h, add API docs, stop leaking memoryÆvar Arnfjörð Bjarmason, Feb 16, 2022
  111. 1/5 cache.h: remove always unused show_date_human() declarationÆvar Arnfjörð Bjarmason, Feb 16, 2022
  112. 2/5 date API: create a date.h, split from cache.hÆvar Arnfjörð Bjarmason, Feb 16, 2022
  113. 3/5 date API: provide and use a DATE_MODE_INITÆvar Arnfjörð Bjarmason, Feb 16, 2022
  114. 4/5 date API: add basic API docsÆvar Arnfjörð Bjarmason, Feb 16, 2022
  115. 5/5 date API: add and use a date_mode_release()Ævar Arnfjörð Bjarmason, Feb 16, 2022
  116. Junio C HamanoFeb 16, 2022
  117. 1/8 Makefile: add SANITIZE=leak flag to GIT-BUILD-OPTIONSÆvar Arnfjörð Bjarmason, Aug 31, 2021
  118. 2/8 CI: refactor "if" to "case" statementÆvar Arnfjörð Bjarmason, Aug 31, 2021
  119. 3/8 tests: add a test mode for SANITIZE=leak, run it in CIÆvar Arnfjörð Bjarmason, Aug 31, 2021
  120. 4/8 tests: annotate t000*.sh with TEST_PASSES_SANITIZE_LEAK=trueÆvar Arnfjörð Bjarmason, Aug 31, 2021
  121. 5/8 tests: annotate t001*.sh with TEST_PASSES_SANITIZE_LEAK=trueÆvar Arnfjörð Bjarmason, Aug 31, 2021
  122. 6/8 tests: annotate t002*.sh with TEST_PASSES_SANITIZE_LEAK=trueÆvar Arnfjörð Bjarmason, Aug 31, 2021
  123. 7/8 tests: annotate select t0*.sh with TEST_PASSES_SANITIZE_LEAK=trueÆvar Arnfjörð Bjarmason, Aug 31, 2021
  124. 8/8 tests: annotate select t*.sh with TEST_PASSES_SANITIZE_LEAK=trueÆvar Arnfjörð Bjarmason, Aug 31, 2021
  125. Ævar Arnfjörð BjarmasonAug 31, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.