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

Re: Re*: [PATCH] change contract between system_path and it's callers

From
Alexander Kuleshov <kuleshovmail@gmail.com>
Date
Nov 25, 2014, 18:03 UTC
Message-ID
<CANCZXo4=D=RPnGeAfcvD0O1hX0B43z1b11gyzjbJYGXzusfFYg@mail.gmail.com>
In-Reply-To
<xmqqbnnvtbac.fsf@gitster.dls.corp.google.com>

Ah, you little ahead me, so we do not care about config.c in this way, because it takes git_etc_gitconfig() in the same way as git_etc_gitattributes

2014-11-25 23:55 GMT+06:00 Junio C Hamano <gitster@pobox.com>:
Show 82 quoted lines
> Alexander Kuleshov <kuleshovmail@gmail.com> writes:
>
>> But if we still static const char* for git_etc_gitattributes and will
>> not free it in bootstrap_attr_stack there will no memory leak, just
>> tested it, so i'll remove free for it.
>
> Leak or no leak, freeing there is wrong.  It will free the piece of
> memory the next caller will obtain from the git_etc_gitattributes()
> function.  In other words, the return value from that function is
> owned by git_etc_gitattributes(), not by the caller.
>
> As to "leak", in the strictest sense of the word, i.e. "do we
> allocate on the heap and exit without freeing?", it _is_ leaking,
> and your above "just tested it" probably means "the tool I used did
> not find/report it".  But as I said, it is not something worth
> bothering about [*1*].
>
> Think of it this way.
>
> The git_etc_gitattributes() function goes like this with your patch
> (and there is no fundamental difference in the original version,
> which uses "const char *" where appropriate):
>
>          static char *git_etc_gitattributes(void)
>          {
>                 static char *system_wide;
>                 if (!system_wide)
>                         system_wide = system_path(ETC_GITATTRIBUTES);
>                 return system_wide;
>          }
>
> If you knew that the pathname for /etc/gitattributes substitute will
> never be longer than 256 bytes, you may have coded the above like so
> instead:
>
>         static char system_wide[256];
>         static char *git_etc_gitattributes(void)
>         {
>                 if (!system_wide[0]) {
>                         char *ret = system_path(ETC_GITATTRIBUTES);
>                         if (strncpy(system_wide, ret, 256) >= 256)
>                                 die("ETC_GITATTRIBUTES too long ");
>                 }
>                 return system_wide;
>         }
>
> Even though we used the memory occupied by system_wide[] and did not
> clean up before exit(), nobody would complain about leaking.
>
> The existing code is the moral equivalent of the "up to 256 bytes"
> illustration, but for a string whose size is not known at compile
> time.  It is using and keeping the memory until program exit.
> Nobody should complain about leaking.
>
> That is, unless (1) the held memory is expected to be very large and
> (2) you can prove that after the point you decide to insert free(),
> nobody will ever need that information again.
>
>
> [Footnote]
>
> *1* The leaks we care about are of this form:
>
>     void silly_leaker(void)
>     {
>         printf("%s\n", system_path(ETC_GITATTRIBUTES));
>     }
>
>     where each invocation allocates memory, uses it and then loses
>     the reference to it without doing anything to clean-up.  You can
>     call such a function unbounded number of times and waste
>     unbounded amount of memory.
>
>     The implementation of git_etc_gitattributes() is not of that
>     kind.  An invocation of it allocates, uses and keeps.  The
>     second and subsequent invocation does not allocate.  When you
>     call it unbounded number of times, it does not waste unbounded
>     amount of memory.  It just keeps what it needs to answer the
>     next caller with.
>
>     The pattern needs to be made thread-safe, but that is a separate
>     topic.
-- 
_________________________
0xAX
Previous: Junio C HamanoNext: Alexander Kuleshov
Message 23 of 33 in “GIT: [PATCH] exec_cmd: system_path memory leak fix”
  1. 0xAXNov 23, 2014
  2. exec_cmd: system_path memory leak fix0xAX, Nov 23, 2014
  3. 0xAXNov 23, 2014
  4. Junio C HamanoNov 23, 2014
  5. Alex KuleshovNov 23, 2014
  6. Alex KuleshovNov 23, 2014
  7. Jeff KingNov 23, 2014
  8. Eric SunshineNov 23, 2014
  9. Junio C HamanoNov 23, 2014
  10. Alex KuleshovNov 24, 2014
  11. Junio C HamanoNov 24, 2014
  12. Alex KuleshovNov 24, 2014
  13. Alexander KuleshovNov 24, 2014
  14. Alex KuleshovNov 24, 2014
  15. change contract between system_path and it's callers0xAX, Nov 24, 2014
  16. Re*: [PATCH] change contract between system_path and it's callersJunio C Hamano, Nov 24, 2014
  17. Alex KuleshovNov 24, 2014
  18. Junio C HamanoNov 24, 2014
  19. Junio C HamanoNov 24, 2014
  20. Alexander KuleshovNov 25, 2014
  21. Alexander KuleshovNov 25, 2014
  22. Junio C HamanoNov 25, 2014
  23. Alexander KuleshovNov 25, 2014
  24. 1/1 change contract between system_path and it's callersAlexander Kuleshov, Nov 25, 2014
  25. Junio C HamanoNov 25, 2014
  26. Alexander KuleshovNov 26, 2014
  27. Alexander KuleshovNov 26, 2014
  28. Alexander KuleshovNov 26, 2014
  29. Junio C HamanoNov 26, 2014
  30. Philip OakleyNov 28, 2014
  31. Junio C HamanoNov 25, 2014
  32. Alexander KuleshovNov 25, 2014
  33. Junio C HamanoNov 23, 2014

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.