Re: [PATCH] diff-lib: plug minor memory leaks in do_diff_cache()
- From
Jeff King <peff@peff.net>
- Date
- Nov 17, 2020, 00:35 UTC
- Message-ID
- <20201117003511.GC13516@coredump.intra.peff.net>
- In-Reply-To
- <80fb4a2a-992f-7d3b-9413-5059da3a8f01@web.de>
On Sat, Nov 14, 2020 at 07:37:03PM +0100, René Scharfe wrote:
Show 6 quoted lines
> do_diff_cache() builds a struct rev_info to hand to diff_cache() from > scratch by initializing it using repo_init_revisions() and then > replacing its diffopt and prune_data members. > > The diffopt member is initialized to a heap-allocated list of options, > though. Release it using diff_setup_done() before overwriting it.
Makes sense. This whole "rewrite the options as a heap-allocated list" thing is pretty gross, but is probably the least-bad solution to the problem. I wondered if there might be other unpaired diff_setup() / diff_setup_done() calls. Curiously, there are more of the latter:
$ git grep 'diff_setup(' | wc -l
22 $ git grep 'diff_setup_done(' | wc -l
35I think because repo_init_revisions() makes an implicit call to diff_setup().
> The initial value of the prune_data member doesn't need to be released, > but the copy created using copy_pathspec() does. Clear it after use.
I suspect there are more elements of rev_info that could be allocated (e.g., in a traversal without "--objects", I think trees and blobs are left sitting in the pending array). It's a prime candidate for UNLEAK() in most cases where we do a single traversal and then exit the program. But for sub-functions like this, we perhaps should bite the bullet and just make a rev_info_clear() function that can be used everywhere.
(I'm not opposed to your patch here in the meantime, though).
-Peff