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

Re: [PATCH 2/3] dir: make clear_directory() free all relevant memory

From
Elijah Newren <newren@gmail.com>
Date
Aug 17, 2020, 16:58 UTC
Message-ID
<CABPp-BHUN=f-oGmjUpbRRs=h9OZ75jFZUZbQ7_sFO4cCKuVK_Q@mail.gmail.com>
In-Reply-To
<20200816085406.GB1221900@coredump.intra.peff.net>
On Sun, Aug 16, 2020 at 1:54 AM Jeff King <peff@peff.net> wrote:
Show 51 quoted lines
>
> On Sun, Aug 16, 2020 at 06:59:10AM +0000, Elijah Newren via GitGitGadget wrote:
>
> > From: Elijah Newren <newren@gmail.com>
> >
> > The calling convention for the dir API is supposed to end with a call to
> > clear_directory() to free up no longer needed memory.  However,
> > clear_directory() didn't free dir->entries or dir->ignored.  I believe
> > this was oversight, but a number of callers noticed memory leaks and
> > started free'ing these, but often somewhat haphazardly (sometimes
> > freeing the entries in the arrays, and sometimes only free'ing the
> > arrays themselves).  This suggests the callers weren't trying to make
> > sure any possible memory used might be free'd, but just the memory they
> > noticed their usecase definitely had allocated.  This also caused the
> > extra memory deallocations to be duplicated in many places.
> >
> > Fix this mess by moving all the duplicated free'ing logic into
> > clear_directory().
>
> Makes sense. I don't know the dir.c code very well, so my worry would be
> that some caller really wanted the other fields left untouched. But
> looking over the callers, it seems they're all clearing it before the
> struct goes out of scope. It's possible that they could have created
> other pointer references, but it seems unlikely (and I'd argue they
> should stop doing that and make their own copies of the data). E.g.,
> wt_status_collect_untracked() sticks names into a string_list, but it
> sets strdup_strings to make its own copy, so it's good.
>
> > @@ -3034,6 +3031,13 @@ void clear_directory(struct dir_struct *dir)
> >               free(group->pl);
> >       }
> >
> > +     for (i = 0; i < dir->ignored_nr; i++)
> > +             free(dir->ignored[i]);
> > +     for (i = 0; i < dir->nr; i++)
> > +             free(dir->entries[i]);
> > +     free(dir->ignored);
> > +     free(dir->entries);
> > +
> >       stk = dir->exclude_stack;
> >       while (stk) {
> >               struct exclude_stack *prev = stk->prev;
>
> In most of our "clear" functions, the struct is ready for use again
> (i.e., fields are set back to the initialized state). I don't think any
> caller cares at this point, but it may be worth doing while we are here
> as a least-surprise thing. That would mean setting these pointers to
> NULL, and probably a few others that you aren't touching here.
>
> Perhaps even easier would be to add a dir_init() call at the end after
> your next patch adds that function.
Make sense; I'll fix it up.
Previous: Jeff KingNext: Elijah Newren via GitGitGadget
Message 11 of 15 in “Clean up some memory leaks in and around dir.c”
  1. 0/3 Clean up some memory leaks in and around dir.cElijah Newren via GitGitGadget, Aug 16, 2020
  2. 1/3 dir: fix leak of parent_hashmap and recursive_hashmapElijah Newren via GitGitGadget, Aug 16, 2020
  3. Jeff KingAug 16, 2020
  4. Elijah NewrenAug 17, 2020
  5. 3/3 dir: fix problematic API to avoid memory leaksElijah Newren via GitGitGadget, Aug 16, 2020
  6. Jeff KingAug 16, 2020
  7. Elijah NewrenAug 17, 2020
  8. Jeff KingAug 17, 2020
  9. 2/3 dir: make clear_directory() free all relevant memoryElijah Newren via GitGitGadget, Aug 16, 2020
  10. Jeff KingAug 16, 2020
  11. Elijah NewrenAug 17, 2020
  12. 0/2 Clean up some memory leaks in and around dir.cElijah Newren via GitGitGadget, Aug 18, 2020
  13. 1/2 dir: make clear_directory() free all relevant memoryElijah Newren via GitGitGadget, Aug 18, 2020
  14. 2/2 dir: fix problematic API to avoid memory leaksElijah Newren via GitGitGadget, Aug 18, 2020
  15. Jeff KingAug 19, 2020

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.