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

Re: [PATCH v2] wt-status: using of wt_status_state_free_buffers

From
Rubén Justo <rjusto@gmail.com>
Date
Oct 8, 2022, 00:35 UTC
Message-ID
<b6be0af4-8b47-d89d-13fe-a307c0e96797@gmail.com>
In-Reply-To
<6ff29e96-7f8d-c354-dced-b1b363e54467@gmail.com>

In 2708ce62d2 (branch: sort detached HEAD based on a flag, 2021-01-07) a call to wt_status_state_free_buffers, responsible of freeing the resources that could be allocated in the local struct wt_status_state state, was eliminated.

That introduced a leak that occurs with "branch list" in a detached HEAD state. The number of leaks depends on the references to "refname" in --sort and --format. With defaults, 3 are leaked: default sort is by "refname" and default format needs two references of "refname": %(refname:lstrip=2) and %(refname:rstrip-2).

This doesn't leak:
    $ git branch --sort objectname --format '%(objectname)'
This leak once:
    $ git branch --sort refname --format '%(refname)'
This leak twice:
    $ git branch --sort refname --format '%(refname:lstrip=2)'
Note that each different "atom" is only resolved once (see ref-filter.c).

The call to wt_status_state_free_buffers was introduced in 962dd7ebc3 (wt-status: introduce wt_status_state_free_buffers(), 2020-09-27). Bring back that call in get_head_description.

Ævar Arnfjörð pointed out [1] that a similar leak is present in builtin/checkout.c:die_if_some_operation_in_progress(void), since c45f0f525de (switch: reject if some operation is in progress, 2019-03-29). The leak occurs once with "switch" while bisecting.

Lets call to wc_status_state_free_buffers() there too.
[1] 220926.86bkr24kjw.gmgdl@evledraar.gmail.com
Signed-off-by: Rubén Justo <rjusto@gmail.com>
---
Changes since v1:
	- Add details about the leak
	- Fix the leak in builtin/checkout.c
Range-diff:
1:  86b7803955 ! 1:  3fa1ddbb30 ref-filter.c: fix a leak in get_head_description
    @@ Commit message
         resources that could be allocated in the local struct wt_status_state
         state, was eliminated.
     
    +    That introduced a leak that occurs with "branch list" in a detached HEAD
    +    state.  The number of leaks depends on the references to "refname" in
    +    --sort and --format.  With defaults, 3 are leaked: default sort is by
    +    "refname" and default format needs two references of "refname",
    +    %(refname:lstrip=2) and %(refname:rstrip-2).
    +
    +    This doesn't leak:
    +        $ git branch --sort objectname --format '%(objectname)'
    +
    +    This leak once:
    +        $ git branch --sort refname --format '%(refname)'
    +
    +    This leak twice:
    +        $ git branch --sort refname --format '%(refname:lstrip=2)'
    +
    +    Note that each different "atom" is only resolved once (see ref-filter.c).
    +
         The call to wt_status_state_free_buffers was introduced in 962dd7ebc3
    -    (wt-status: introduce wt_status_state_free_buffers(), 2020-09-27).  This
    -    commit brings back that call in get_head_description.
    +    (wt-status: introduce wt_status_state_free_buffers(), 2020-09-27).
    +    Bring back that call in get_head_description.
    +
    +    Ævar Arnfjörð pointed out [1] that a similar leak is present in
    +    builtin/checkout.c:die_if_some_operation_in_progress(void), since
    +    c45f0f525de (switch: reject if some operation is in progress,
    +    2019-03-29).  The leak ocurrs once with checkout while bisecting.
    +
    +    Lets call to wc_status_state_free_buffers() there too.
    +
    +    [1] 220926.86bkr24kjw.gmgdl@evledraar.gmail.com
     
         Signed-off-by: Rubén Justo <rjusto@gmail.com>
     
    + ## builtin/checkout.c ##
    +@@ builtin/checkout.c: static void die_if_some_operation_in_progress(void)
    + 		      "or \"git worktree add\"."));
    + 	if (state.bisect_in_progress)
    + 		warning(_("you are switching branch while bisecting"));
    ++
    ++	wt_status_state_free_buffers(&state);
    + }
    + 
    + static int checkout_branch(struct checkout_opts *opts,
    +
      ## ref-filter.c ##
     @@ ref-filter.c: char *get_head_description(void)
      	} else
 builtin/checkout.c | 2 ++
 ref-filter.c       | 2 ++
 2 files changed, 4 insertions(+)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 2a132392fb..659dd5c430 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1470,6 +1470,8 @@ static void die_if_some_operation_in_progress(void)
 		      "or \"git worktree add\"."));
 	if (state.bisect_in_progress)
 		warning(_("you are switching branch while bisecting"));
+
+	wt_status_state_free_buffers(&state);
 }
 
 static int checkout_branch(struct checkout_opts *opts,
diff --git a/ref-filter.c b/ref-filter.c
index fd1cb14b0f..914908fac5 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -1722,6 +1722,8 @@ char *get_head_description(void)
 	} else
 		strbuf_addstr(&desc, _("(no branch)"));
 
+	wt_status_state_free_buffers(&state);
+
 	return strbuf_detach(&desc, NULL);
 }
 
-- 
2.32.0
Previous: Rubén Justo
Message 7 of 7 in “ref-filter.c: fix a leak in get_head_description”
  1. ref-filter.c: fix a leak in get_head_descriptionRubén Justo, Sep 24, 2022
  2. Martin ÅgrenSep 26, 2022
  3. Junio C HamanoSep 26, 2022
  4. Martin ÅgrenSep 27, 2022
  5. Ævar Arnfjörð BjarmasonSep 26, 2022
  6. Rubén JustoSep 26, 2022
  7. Rubén JustoOct 8, 2022

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.