Re: [PATCH v2] wt-status: using of wt_status_state_free_buffers
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(+)
Show changes to 2 files +4 −0
builtin/checkout.c, ref-filter.c
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