fsmonitor: fix khash memory leak in do_handle_client
PATCH 1/1 fsmonitor: fix khash memory leak in do_handle_client
From: Paul Tarjan <[email protected]>
The do_handle_client() function allocates a khash table to de-duplicate pathnames when responding to client requests. Two issues existed:
1. kh_release_str() was used instead of kh_destroy_str(). The release function only frees internal arrays (flags, keys, vals) but not the struct itself (allocated by kh_init_str via xcalloc). This caused a 40-byte leak per request.
2. The khash was freed mid-function rather than in the cleanup section, so if the worker thread was interrupted before reaching that point during daemon shutdown, the memory would leak.
Fix both issues by:
- Initializing shown = NULL at declaration
- Using kh_destroy_str() which handles NULL and frees both internal arrays and the struct itself
- Moving the cleanup to the cleanup section so it runs on all exit paths
---
fsmonitor: fix khash memory leak in do_handle_client
The do_handle_client() function allocates a khash table to de-duplicate pathnames when responding to client requests. Two issues existed:
1. kh_release_str() was used instead of kh_destroy_str(). The release function only frees internal arrays (flags, keys, vals) but not the struct itself (allocated by kh_init_str via xcalloc). This caused a 40-byte leak per request.
2. The khash was freed mid-function rather than in the cleanup section, so if the worker thread was interrupted before reaching that point during daemon shutdown, the memory would leak.
Fix both issues by:
* Initializing shown = NULL at declaration
* Using kh_destroy_str() which handles NULL and frees both internal arrays and the struct itself
* Moving the cleanup to the cleanup section so it runs on all exit paths
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2148%2Fptarjan%2Fclaude%2Ffix-fsmonitor-hashmap-leak-gfDCU-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2148/ptarjan/claude/fix-fsmonitor-hashmap-leak-gfDCU-v1
Pull-Request: https://github.com/git/git/pull/2148
builtin/fsmonitor--daemon.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
builtin/fsmonitor--daemon.c +2 -3
@@ -671,7 +671,7 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,const struct fsmonitor_batch *batch;struct fsmonitor_batch *remainder =NULL ;intmax_t count =0 , duplicates =0 ; -kh_str_t *shown; +kh_str_t *shown =NULL ;int hash_ret;int do_trivial =0 ;int do_flush =0 ;
@@ -909,8 +909,6 @@ static int do_handle_client(struct fsmonitor_daemon_state *state, total_response_len += payload.len; } -kh_release_str (shown); -pthread_mutex_lock (&state->main_lock);if (token_data->client_ref_count >0 )
@@ -954,6 +952,7 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,trace2_data_intmax ("fsmonitor" , the_repository,"response/count/duplicates" , duplicates); cleanup: +kh_destroy_str (shown);strbuf_release (&response_token);strbuf_release (&requested_token_id);strbuf_release (&payload);
base-commit: 7c7698a654a7a0031f65b0ab0c1c4e438e95df60
Signature · 1 line
gitgitgadget
Quoted 24 lines · Paul Tarjan via GitGitGadget
From: Paul Tarjan <[email protected]>
The
do_handle_client()function allocates a khash table to de-duplicate pathnames when responding to client requests. Two issues existed:1.
kh_release_str()was used instead ofkh_destroy_str(). The release function only frees internal arrays (flags, keys, vals) but not the struct itself (allocated bykh_init_strvia xcalloc). This caused a 40-byte leak per request.2. The khash was freed mid-function rather than in the cleanup section, so if the worker thread was interrupted before reaching that point during daemon shutdown, the memory would leak.
Fix both issues by:
- Initializing shown = NULL at declaration
- Usingkh_destroy_str()which handles NULL and frees both internal arrays and the struct itself
- Moving the cleanup to the cleanup section so it runs on all exit pathsSigned-off-by Claude <[email protected]>---
fsmonitor: fix khash memory leak indo_handle_client
Quoted 7 lines
The
do_handle_client()function allocates a khash table to de-duplicate pathnames when responding to client requests. Two issues existed:1.
kh_release_str()was used instead ofkh_destroy_str(). The release function only frees internal arrays (flags, keys, vals) but not the struct itself (allocated bykh_init_strvia xcalloc). This caused a 40-byte leak per request.
Makes sense.
Quoted 4 lines
2. The khash was freed mid-function rather than in the cleanup section, so if the worker thread was interrupted before reaching that point during daemon shutdown, the memory would leak.
Really? Would an interrupted thread even reach its cleanup section?
Quoted 48 lines
Fix both issues by:
* Initializing shown = NULL at declaration
* Usingkh_destroy_str()which handles NULL and frees both internal arrays and the struct itself
* Moving the cleanup to the cleanup section so it runs on all exit pathsPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2148%2Fptarjan%2Fclaude%2Ffix-fsmonitor-hashmap-leak-gfDCU-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2148/ptarjan/claude/fix-fsmonitor-hashmap-leak-gfDCU-v1
Pull-Request: https://github.com/git/git/pull/2148builtin/fsmonitor--daemon.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)builtin/fsmonitor--daemon.c +2
-3@@ -671,7 +671,7 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,const struct fsmonitor_batch *batch;struct fsmonitor_batch *remainder =NULL ;intmax_t count =0 , duplicates =0 ; -kh_str_t *shown; +kh_str_t *shown =NULL ;int hash_ret;int do_trivial =0 ;int do_flush =0 ;@@ -909,8 +909,6 @@ static int do_handle_client(struct fsmonitor_daemon_state *state, total_response_len += payload.len; } -kh_release_str (shown); -pthread_mutex_lock (&state->main_lock);if (token_data->client_ref_count >0 )@@ -954,6 +952,7 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,trace2_data_intmax ("fsmonitor" , the_repository,"response/count/duplicates" , duplicates); cleanup: +kh_destroy_str (shown);strbuf_release (&response_token);strbuf_release (&requested_token_id);strbuf_release (&payload);base-commit:
7c7698a654a7a0031f65b0ab0c1c4e438e95df60
PATCH v2 1/1 fsmonitor: fix khash memory leak in do_handle_client
In reply to Paul Tarjan via GitGitGadgetFrom: Paul Tarjan <[email protected]>
The do_handle_client() function allocates a khash table to de-duplicate pathnames when responding to client requests. However, kh_release_str() was used instead of kh_destroy_str(). The release function only frees internal arrays (flags, keys, vals) but not the struct itself, which is allocated by kh_init_str() via xcalloc. This caused a 40-byte leak per client request.
Fix by using kh_destroy_str() which properly frees both internal arrays and the struct itself. Also move the cleanup to the cleanup section and initialize shown to NULL so that kh_destroy_str() is safe to call on all exit paths.
---
fsmonitor: fix khash memory leak in do_handle_client
The do_handle_client() function allocates a khash table to de-duplicate pathnames when responding to client requests. However, kh_release_str() was used instead of kh_destroy_str(). The release function only frees internal arrays (flags, keys, vals) but not the struct itself, which is allocated by kh_init_str() via xcalloc. This caused a 40-byte leak per client request.
Fix by using kh_destroy_str() which properly frees both internal arrays and the struct itself. Also move the cleanup to the cleanup section and initialize shown to NULL so that kh_destroy_str() is safe to call on all exit paths.
Changes since v1:
* Removed incorrect claim about interrupted threads reaching cleanup
* Simplified commit message to focus on the real bug (kh_release vs kh_destroy)
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2148%2Fptarjan%2Fclaude%2Ffix-fsmonitor-hashmap-leak-gfDCU-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2148/ptarjan/claude/fix-fsmonitor-hashmap-leak-gfDCU-v2
Pull-Request: https://github.com/git/git/pull/2148
Range-diff vs v1:
1: 18670d3230 ! 1: 0a754c7f09 fsmonitor: fix khash memory leak in do_handle_client
@@ Commit message
fsmonitor: fix khash memory leak in do_handle_client
The do_handle_client() function allocates a khash table to de-duplicate
- pathnames when responding to client requests. Two issues existed:
+ pathnames when responding to client requests. However, kh_release_str()
+ was used instead of kh_destroy_str(). The release function only frees
+ internal arrays (flags, keys, vals) but not the struct itself, which is
+ allocated by kh_init_str() via xcalloc. This caused a 40-byte leak per
+ client request.
- 1. kh_release_str() was used instead of kh_destroy_str(). The release
- function only frees internal arrays (flags, keys, vals) but not the
- struct itself (allocated by kh_init_str via xcalloc). This caused a
- 40-byte leak per request.
+ Fix by using kh_destroy_str() which properly frees both internal arrays
+ and the struct itself. Also move the cleanup to the cleanup section and
+ initialize shown to NULL so that kh_destroy_str() is safe to call on all
+ exit paths.
- 2. The khash was freed mid-function rather than in the cleanup section,
- so if the worker thread was interrupted before reaching that point
- during daemon shutdown, the memory would leak.
-
- Fix both issues by:
- - Initializing shown = NULL at declaration
- - Using kh_destroy_str() which handles NULL and frees both internal
- arrays and the struct itself
- - Moving the cleanup to the cleanup section so it runs on all exit paths
-
- Signed-off-by: Claude <[email protected]>
+ Signed-off-by: Paul Tarjan <[email protected]>
## builtin/fsmonitor--daemon.c ##
@@ builtin/fsmonitor--daemon.c: static int do_handle_client(struct fsmonitor_daemon_state *state,
builtin/fsmonitor--daemon.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
builtin/fsmonitor--daemon.c +2 -3
@@ -671,7 +671,7 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,const struct fsmonitor_batch *batch;struct fsmonitor_batch *remainder =NULL ;intmax_t count =0 , duplicates =0 ; -kh_str_t *shown; +kh_str_t *shown =NULL ;int hash_ret;int do_trivial =0 ;int do_flush =0 ;
@@ -909,8 +909,6 @@ static int do_handle_client(struct fsmonitor_daemon_state *state, total_response_len += payload.len; } -kh_release_str (shown); -pthread_mutex_lock (&state->main_lock);if (token_data->client_ref_count >0 )
@@ -954,6 +952,7 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,trace2_data_intmax ("fsmonitor" , the_repository,"response/count/duplicates" , duplicates); cleanup: +kh_destroy_str (shown);strbuf_release (&response_token);strbuf_release (&requested_token_id);strbuf_release (&payload);
base-commit: 7c7698a654a7a0031f65b0ab0c1c4e438e95df60
Signature · 1 line
gitgitgadget
Quoted 9 lines · Paul Tarjan via GitGitGadget
From: Paul Tarjan <[email protected]>
The
do_handle_client()function allocates a khash table to de-duplicate pathnames when responding to client requests. However,kh_release_str()was used instead ofkh_destroy_str(). The release function only frees internal arrays (flags, keys, vals) but not the struct itself, which is allocated bykh_init_str()via xcalloc. This caused a 40-byte leak per client request.
Quoted 7 lines
Fix by using
kh_destroy_str()which properly frees both internal arrays and the struct itself. Also move the cleanup to the cleanup section and initialize shown to NULL so thatkh_destroy_str()is safe to call on all exit paths.Signed-off-by Paul Tarjan <[email protected]>---
This is already in v4 of the other larger fsmonitor-linux patch, right?
Thanks.
Quoted 17 lines · Junio C Hamano
Quoted 14 lines · Paul Tarjan via GitGitGadget
From: Paul Tarjan <[email protected]>
The
do_handle_client()function allocates a khash table to de-duplicate pathnames when responding to client requests. However,kh_release_str()was used instead ofkh_destroy_str(). The release function only frees internal arrays (flags, keys, vals) but not the struct itself, which is allocated bykh_init_str()via xcalloc. This caused a 40-byte leak per client request.Fix by using
kh_destroy_str()which properly frees both internal arrays and the struct itself. Also move the cleanup to the cleanup section and initialize shown to NULL so thatkh_destroy_str()is safe to call on all exit paths.
Quoted 5 lines
Quoted 2 lines
Signed-off-by Paul Tarjan <[email protected]>---
This is already in v4 of the other larger fsmonitor-linux patch, right?
Correct. I sent it separately since it is currently a bug in existing code and you might want to merge it sooner.
Quoted 3 lines
Thanks.
Quoted 18 lines · Paul Tarjan
Quoted 17 lines · Junio C Hamano
Quoted 14 lines · Paul Tarjan via GitGitGadget
From: Paul Tarjan <[email protected]>
The
do_handle_client()function allocates a khash table to de-duplicate pathnames when responding to client requests. However,kh_release_str()was used instead ofkh_destroy_str(). The release function only frees internal arrays (flags, keys, vals) but not the struct itself, which is allocated bykh_init_str()via xcalloc. This caused a 40-byte leak per client request.Fix by using
kh_destroy_str()which properly frees both internal arrays and the struct itself. Also move the cleanup to the cleanup section and initialize shown to NULL so thatkh_destroy_str()is safe to call on all exit paths.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Signed-off-by Paul Tarjan <[email protected]>---
This is already in v4 of the other larger fsmonitor-linux patch, right?
Correct. I sent it separately since it is currently a bug in existing code and you might want to merge it sooner.
Thanks.