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

Re: [PATCH 0/7] Fix all leaks in t0001

From
Andrzej Hunt <andrzej@ahunt.org>
Date
Mar 14, 2021, 16:54 UTC
Message-ID
<d22dc5e6-415e-e265-e894-67b28fe9fe54@ahunt.org>
In-Reply-To
<YEZzGjNMSj+MkDUH@coredump.intra.peff.net>
On 08/03/2021 19:55, Jeff King wrote:
Show 12 quoted lines
> I think it's worth doing. The reason t0000 passes is because it was my
> reference script when adding UNLEAK() back in:
> 
>    https://lore.kernel.org/git/20170905130149.agc3zp3s6i6e5aki@sigill.intra.peff.net/
> 
> (which might be of historical interest if you haven't read it). I knew
> that the next step would be tediously going through the test suite
> looking at the tool results, and I somehow stalled on that part. ;)
> 
> But I think it's nice to move the goal forward incrementally. I agree
> that a lot of these leaks aren't that important, but it's generally as
> easy to fix or annotate them as it is to argue that they shouldn't be > dealt with.

Thanks for the confirmation! I'd seen your post, but wasn't sure if there'd been a change of plan or just lack of time :).

Show 12 quoted lines
>> Note: this series does not guarantee that there are no leaks within
>> t0000-t0001, it only fixes those leaks which cause test failures. There is
>> at least one test case in t0000 where git is invoked in a subshell, and the
>> return value is ignored - meaning that a memory leak that is occuring during
>> that invocation does not cause tests to fail (I'm still trying to figure out
>> if that's something that's worth fixing - but that's probably a topic for a
>> separate thread):
>> https://git.kernel.org/pub/scm/git/git.git/tree/t/t0000-basic.sh#n1285
> 
> It's not the subshell there, but rather that git is on the left-hand
> side of a pipe (and so its exit code is discarded). We've been slowly
> fixing such cases (the usual technique is to use a tempfile).

Thanks for the tip! I've started on another series to fix t0000-basic along with the leaks that that uncovers. In future I suspect it's best to start by removing pipes _before_ running leak-checking against a given test. (Fortunately t0001 doesn't contain any such cases, so this series is valid as is.)

Show 14 quoted lines
>> In case anyone is interested: I have been using the following workflow to
>> find leaks and verify fixes - I'm running into crashes when using LSAN
>> standalone, therefore I'm using full ASAN instead (I'm not particularly
>> concerned about this: LSAN standalone mode is known to be less-well tested
>> than leak-checking within ASAN [1], and the crashes are occurring within the
>> leak-checker itself):
> 
> Yeah, I think using ASAN is just fine. I found that LSAN is faster, but
> if you are running a single script the difference probably doesn't
> matter. I also found that clang's support was much more mature than
> gcc's (I don't know how different the state is these days, though).
> 
> Regardless, if you can get it to run cleanly with _any_ leak checker,
> I'll be quite happy. :)

I was wrong when it comes to LSAN being broken. What was actually happening is: we default to running ASAN and LSAN with abort_on_error=1, and I had overridden that setting when running with ASAN. When I switched to LSAN, abort_on_error was enabled again - and I was just misinterpreting the intentional abortion as opposed to seeing an unexplained crashes. [As far as I can tell, abort_on_error is needed to detect leaks during a test_must_fail and similar scenarios.]

I've briefly tested all the various combinations of gcc or clang, with LSAN or ASAN or both - and they all seem to work as expected, with one exception: gcc with LSAN-only finds what seems to be a false positive, in a method which mallocs, followed by a die().

To make it trickier, that new "leak" happens inside a test_must_fail - the LSAN output is swallowed, making it hard to diagnose. I'll try to prepare a separate patch to not discard stderr in that scenario.

Regardless of the LSAN/ASAN differences - I'm wondering whether piggybacking on the existing ASAN validation might be the best way to get leak checking run more often (limited to a subset of leak-free tests of course). I'll expand on these thoughts in my reply to Junio.

Show 12 quoted lines
>> make GIT_TEST_OPTS="-i -v" DEFAULT_TEST_TARGET="t0000-basic.sh"
>> ASAN_OPTIONS="detect_leaks=1:abort_on_error=1" SANITIZE=address DEVELOPER=1
>> CFLAGS="-DSUPPRESS_ANNOTATED_LEAKS -g -fno-optimize-sibling-calls -O1
>> -fno-omit-frame-pointer" test
> 
> There's some magic in the Makefile for detecting SANITIZE=leak and
> setting -DSUPPRESS_ANNOTATED_LEAKS. It might be worth that extending
> that to SANITIZE=address, but I guess we wouldn't want to do so for most
> builds (which also are setting detect_leaks=0 in the test suite). Maybe
> we should have some other name to trigger asan-as-a-leak-detector. Or
> maybe that just gets complicated, because we pass the results of
> SANITIZE on to the compiler directly.

I've realised it's enough to set SANITIZE=leak,address. That gives us the benefits of ASAN, but still adds -DSUPPRESS_ANNOTATED_LEAKS. Given that LSAN seems stable enough with clang, I suppose this is only really useful for gcc users.

> I haven't looked at the individual patches yet. I'll respond to them
> individually.
> 
> -Peff

Thank you for the reviews! I'm still a bit new to the git codebase, thank you for being patient with my (deficits of) style :).

Previous: Junio C HamanoNext: Andrzej Hunt
Message 22 of 52 in “Fix all leaks in t0001”
  1. 0/7 Fix all leaks in t0001Andrzej Hunt via GitGitGadget, Mar 8, 2021
  2. 1/7 symbolic-ref: don't leak shortened refname in check_symref()Andrzej Hunt via GitGitGadget, Mar 8, 2021
  3. Jeff KingMar 8, 2021
  4. Andrzej HuntMar 14, 2021
  5. 2/7 reset: free instead of leaking unneeded refAndrzej Hunt via GitGitGadget, Mar 8, 2021
  6. Jeff KingMar 8, 2021
  7. 3/7 clone: free or UNLEAK further pointers when finishedAndrzej Hunt via GitGitGadget, Mar 8, 2021
  8. Jeff KingMar 8, 2021
  9. Andrzej HuntMar 14, 2021
  10. 6/7 init-db: silence template_dir leak when converting to absolute pathAndrzej Hunt via GitGitGadget, Mar 8, 2021
  11. Jeff KingMar 8, 2021
  12. 4/7 worktree: fix leak in dwim_branch()Andrzej Hunt via GitGitGadget, Mar 8, 2021
  13. Jeff KingMar 8, 2021
  14. Andrzej HuntMar 14, 2021
  15. 7/7 parse-options: don't leak alias help messagesAndrzej Hunt via GitGitGadget, Mar 8, 2021
  16. Jeff KingMar 8, 2021
  17. Andrzej HuntMar 14, 2021
  18. 5/7 init: remove git_init_db_config() while fixing leaksAndrzej Hunt via GitGitGadget, Mar 8, 2021
  19. Jeff KingMar 8, 2021
  20. Jeff KingMar 8, 2021
  21. Junio C HamanoMar 12, 2021
  22. Andrzej HuntMar 14, 2021
  23. Andrzej HuntMar 15, 2021
  24. Junio C HamanoMar 8, 2021
  25. Andrzej HuntMar 14, 2021
  26. 0/9 Fix all leaks in t0001Andrzej Hunt via GitGitGadget, Mar 14, 2021
  27. 8/9 parse-options: don't leak alias help messagesAndrzej Hunt via GitGitGadget, Mar 14, 2021
  28. Eric SunshineMar 14, 2021
  29. Andrzej HuntMar 15, 2021
  30. Andrzej HuntMar 14, 2021
  31. 1/9 symbolic-ref: don't leak shortened refname in check_symref()Andrzej Hunt via GitGitGadget, Mar 14, 2021
  32. 7/9 parse-options: convert bitfield values to use binary shiftAndrzej Hunt via GitGitGadget, Mar 14, 2021
  33. Martin ÅgrenMar 14, 2021
  34. Junio C HamanoMar 14, 2021
  35. Andrzej HuntMar 15, 2021
  36. 4/9 worktree: fix leak in dwim_branch()Andrzej Hunt via GitGitGadget, Mar 14, 2021
  37. 5/9 init: remove git_init_db_config() while fixing leaksAndrzej Hunt via GitGitGadget, Mar 14, 2021
  38. 3/9 clone: free or UNLEAK further pointers when finishedAndrzej Hunt via GitGitGadget, Mar 14, 2021
  39. 2/9 reset: free instead of leaking unneeded refAndrzej Hunt via GitGitGadget, Mar 14, 2021
  40. 9/9 transport: also free remote_refs in transport_disconnect()Andrzej Hunt via GitGitGadget, Mar 14, 2021
  41. 6/9 init-db: silence template_dir leak when converting to absolute pathAndrzej Hunt via GitGitGadget, Mar 14, 2021
  42. 0/9 Fix all leaks in t0001Andrzej Hunt via GitGitGadget, Mar 21, 2021
  43. 1/9 symbolic-ref: don't leak shortened refname in check_symref()Andrzej Hunt via GitGitGadget, Mar 21, 2021
  44. 2/9 reset: free instead of leaking unneeded refAndrzej Hunt via GitGitGadget, Mar 21, 2021
  45. 4/9 worktree: fix leak in dwim_branch()Andrzej Hunt via GitGitGadget, Mar 21, 2021
  46. 3/9 clone: free or UNLEAK further pointers when finishedAndrzej Hunt via GitGitGadget, Mar 21, 2021
  47. 7/9 parse-options: convert bitfield values to use binary shiftAndrzej Hunt via GitGitGadget, Mar 21, 2021
  48. 6/9 init-db: silence template_dir leak when converting to absolute pathAndrzej Hunt via GitGitGadget, Mar 21, 2021
  49. 5/9 init: remove git_init_db_config() while fixing leaksAndrzej Hunt via GitGitGadget, Mar 21, 2021
  50. 9/9 transport: also free remote_refs in transport_disconnect()Andrzej Hunt via GitGitGadget, Mar 21, 2021
  51. 8/9 parse-options: don't leak alias help messagesAndrzej Hunt via GitGitGadget, Mar 21, 2021
  52. Junio C HamanoMar 21, 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.