All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Lidong Yan via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Jeff King <peff@peff.net>, Taylor Blau <me@ttaylorr.com>,
	Lidong Yan <502024330056@smail.nju.edu.cn>
Subject: [PATCH v5 0/3] pack-bitmap: fix memory leak if load_bitmap failed
Date: Tue, 03 Jun 2025 03:14:01 +0000	[thread overview]
Message-ID: <pull.1962.v5.git.git.1748920444.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1962.v4.git.git.1748140983.gitgitgadget@gmail.com>

This patch prevents pack-bitmap.c:load_bitmap() from nulling
bitmap_git->bitmap when loading failed thus eliminates memory leak. This
patch also add a test case in t5310 which use clang leak sanitizer to detect
whether leak happens when loading failed.

Lidong Yan (2):
  pack-bitmap: reword comments in test_bitmap_commits()
  pack-bitmap: add load corrupt bitmap test

Taylor Blau (1):
  pack-bitmap: fix memory leak if load_bitmap() failed

 pack-bitmap.c           | 88 ++++++++++++++++++++++++++++++-----------
 pack-bitmap.h           |  1 +
 t/helper/test-bitmap.c  |  8 ++++
 t/t5310-pack-bitmaps.sh | 30 ++++++++++++++
 4 files changed, 103 insertions(+), 24 deletions(-)


base-commit: 845c48a16a7f7b2c44d8cb137b16a4a1f0140229
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1962%2Fbrandb97%2Ffix-pack-bitmap-leak-v5
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1962/brandb97/fix-pack-bitmap-leak-v5
Pull-Request: https://github.com/git/git/pull/1962

Range-diff vs v4:

 1:  b6b3a83a224 ! 1:  9ce2135df2a pack-bitmap: fix memory leak if load_bitmap() failed
     @@ Commit message
          its caller will always call free_bitmap_index() in case of an error.
      
          Signed-off-by: Taylor Blau <me@ttaylorr.com>
     +    Signed-off-by: Lidong Yan <502024330056@smail.nju.edu.cn>
      
       ## pack-bitmap.c ##
      @@ pack-bitmap.c: static int load_bitmap(struct repository *r, struct bitmap_index *bitmap_git,
 -:  ----------- > 2:  a75d0a3cc7f pack-bitmap: reword comments in test_bitmap_commits()
 2:  7876d9a9014 ! 3:  05140e2171d pack-bitmap: add load corrupt bitmap test
     @@ Commit message
      
       ## pack-bitmap.c ##
      @@ pack-bitmap.c: struct stored_bitmap {
     + 	struct object_id oid;
     + 	struct ewah_bitmap *root;
     + 	struct stored_bitmap *xor;
     ++	size_t map_pos;
       	int flags;
       };
       
     -+struct stored_bitmap_tag_pos {
     -+	struct stored_bitmap stored;
     -+	size_t map_pos;
     -+};
     -+
     - /*
     -  * The active bitmap index for a repository. By design, repositories only have
     -  * a single bitmap index available (the index for the biggest packfile in
     -@@ pack-bitmap.c: static int existing_bitmaps_hits_nr;
     - static int existing_bitmaps_misses_nr;
     - static int roots_with_bitmaps_nr;
     - static int roots_without_bitmaps_nr;
     -+static int tag_pos_on_bitmap;
     - 
     - static struct ewah_bitmap *lookup_stored_bitmap(struct stored_bitmap *st)
     - {
      @@ pack-bitmap.c: static struct stored_bitmap *store_bitmap(struct bitmap_index *index,
       					  struct ewah_bitmap *root,
       					  const struct object_id *oid,
     @@ pack-bitmap.c: static struct stored_bitmap *store_bitmap(struct bitmap_index *in
      +					  int flags, size_t map_pos)
       {
       	struct stored_bitmap *stored;
     -+	struct stored_bitmap_tag_pos *tagged;
       	khiter_t hash_pos;
       	int ret;
       
     --	stored = xmalloc(sizeof(struct stored_bitmap));
     -+	tagged = xmalloc(tag_pos_on_bitmap ? sizeof(struct stored_bitmap_tag_pos) :
     -+					     sizeof(struct stored_bitmap));
     -+	stored = &tagged->stored;
     -+	if (tag_pos_on_bitmap)
     -+		tagged->map_pos = map_pos;
     + 	stored = xmalloc(sizeof(struct stored_bitmap));
     ++	stored->map_pos = map_pos;
       	stored->root = root;
       	stored->xor = xor_with;
       	stored->flags = flags;
     @@ pack-bitmap.c: int test_bitmap_commits(struct repository *r)
       	return 0;
       }
       
     -+int test_bitmap_commits_offset(struct repository *r)
     ++int test_bitmap_commits_with_offset(struct repository *r)
      +{
      +	struct object_id oid;
     -+	struct stored_bitmap_tag_pos *tagged;
     ++	struct stored_bitmap *stored;
      +	struct bitmap_index *bitmap_git;
      +	size_t commit_idx_pos_map_pos, xor_offset_map_pos, flag_map_pos,
      +		ewah_bitmap_map_pos;
      +
     -+	tag_pos_on_bitmap = 1;
      +	bitmap_git = prepare_bitmap_git(r);
      +	if (!bitmap_git)
      +		die(_("failed to load bitmap indexes"));
      +
      +	/*
     -+	 * As this function is only used to print bitmap selected
     -+	 * commits, we don't have to read the commit table.
     ++	 * Since this function needs to know the position of each individual
     ++	 * bitmap, bypass the commit lookup table (if one exists) by forcing
     ++	 * the bitmap to eagerly load its entries.
      +	 */
      +	if (bitmap_git->table_lookup) {
      +		if (load_bitmap_entries_v1(bitmap_git) < 0)
      +			die(_("failed to load bitmap indexes"));
      +	}
      +
     -+	kh_foreach (bitmap_git->bitmaps, oid, tagged, {
     -+		commit_idx_pos_map_pos = tagged->map_pos;
     -+		xor_offset_map_pos = tagged->map_pos + sizeof(uint32_t);
     ++	kh_foreach (bitmap_git->bitmaps, oid, stored, {
     ++		commit_idx_pos_map_pos = stored->map_pos;
     ++		xor_offset_map_pos = stored->map_pos + sizeof(uint32_t);
      +		flag_map_pos = xor_offset_map_pos + sizeof(uint8_t);
      +		ewah_bitmap_map_pos = flag_map_pos + sizeof(uint8_t);
      +
     @@ pack-bitmap.h: void traverse_bitmap_commit_list(struct bitmap_index *,
       				 show_reachable_fn show_reachable);
       void test_bitmap_walk(struct rev_info *revs);
       int test_bitmap_commits(struct repository *r);
     -+int test_bitmap_commits_offset(struct repository *r);
     ++int test_bitmap_commits_with_offset(struct repository *r);
       int test_bitmap_hashes(struct repository *r);
       int test_bitmap_pseudo_merges(struct repository *r);
       int test_bitmap_pseudo_merge_commits(struct repository *r, uint32_t n);
     @@ t/helper/test-bitmap.c: static int bitmap_list_commits(void)
       	return test_bitmap_commits(the_repository);
       }
       
     -+static int bitmap_list_commits_offset(void)
     ++static int bitmap_list_commits_with_offset(void)
      +{
     -+	return test_bitmap_commits_offset(the_repository);
     ++	return test_bitmap_commits_with_offset(the_repository);
      +}
      +
       static int bitmap_dump_hashes(void)
     @@ t/helper/test-bitmap.c: int cmd__bitmap(int argc, const char **argv)
       
       	if (argc == 2 && !strcmp(argv[1], "list-commits"))
       		return bitmap_list_commits();
     -+	if (argc == 2 && !strcmp(argv[1], "list-commits-offset"))
     -+		return bitmap_list_commits_offset();
     ++	if (argc == 2 && !strcmp(argv[1], "list-commits-with-offset"))
     ++		return bitmap_list_commits_with_offset();
       	if (argc == 2 && !strcmp(argv[1], "dump-hashes"))
       		return bitmap_dump_hashes();
       	if (argc == 2 && !strcmp(argv[1], "dump-pseudo-merges"))
     @@ t/helper/test-bitmap.c: int cmd__bitmap(int argc, const char **argv)
       		return bitmap_dump_pseudo_merge_objects(atoi(argv[2]));
       
       	usage("\ttest-tool bitmap list-commits\n"
     -+	      "\ttest-tool bitmap list-commits-offset\n"
     ++	      "\ttest-tool bitmap list-commits-with-offset\n"
       	      "\ttest-tool bitmap dump-hashes\n"
       	      "\ttest-tool bitmap dump-pseudo-merges\n"
       	      "\ttest-tool bitmap dump-pseudo-merge-commits <n>\n"
     @@ t/t5310-pack-bitmaps.sh: test_bitmap_cases () {
      +			bitmap="$(ls .git/objects/pack/pack-*.bitmap)" &&
      +			chmod +w $bitmap &&
      +
     -+			read oid commit_off xor_off flag_off ewah_off <<-EOF &&
     -+				$(test-tool bitmap list-commits-offset | head -n 1)
     -+			EOF
     ++			test-tool bitmap list-commits-with-offset >offsets &&
     ++			xor_off=$(head -n1 offsets | awk "{print \$3}") &&
      +			printf '\161' |
      +				dd of=$bitmap count=1 bs=1 conv=notrunc seek=$xor_off &&
      +
     ++			git rev-list --objects --no-object-names HEAD >expect.raw &&
     ++			git rev-list --objects --use-bitmap-index --no-object-names HEAD \
     ++				>actual.raw &&
     ++
     ++			sort expect.raw >expect &&
     ++			sort actual.raw >actual &&
      +
     -+			git rev-list --count HEAD > expect &&
     -+			git rev-list --use-bitmap-index --count HEAD > actual &&
     -+			test_cmp expect actual
     ++		    test_cmp expect actual
      +		)
      +	'
       }

-- 
gitgitgadget

  parent reply	other threads:[~2025-06-03  3:14 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-12 12:22 [PATCH] pack-bitmap: fix memory leak if `load_bitmap_entries_v1` failed Lidong Yan via GitGitGadget
2025-05-12 13:13 ` Jeff King
2025-05-13 17:47   ` Taylor Blau
2025-05-14 13:18     ` Junio C Hamano
2025-05-14 18:03     ` Jeff King
2025-05-15  1:37       ` lidongyan
2025-05-20  9:23 ` [PATCH v2 0/3] pack-bitmap: fix memory leak if load_bitmap_entries_v1 failed Lidong Yan via GitGitGadget
2025-05-20  9:23   ` [PATCH v2 1/3] pack-bitmap: fix memory leak if `load_bitmap_entries_v1` failed Lidong Yan via GitGitGadget
2025-05-20  9:23   ` [PATCH v2 2/3] " Taylor Blau via GitGitGadget
2025-05-21 23:54     ` Taylor Blau
2025-05-22 15:15       ` lidongyan
2025-05-22 21:22       ` Junio C Hamano
2025-05-20  9:23   ` [PATCH v2 3/3] pack-bitmap: add loading corrupt bitmap_index test Lidong Yan via GitGitGadget
2025-05-22  0:08     ` Taylor Blau
2025-05-22 15:05       ` lidongyan
2025-05-23  0:31         ` Taylor Blau
2025-05-23  7:17           ` lidongyan
2025-05-25  2:06   ` [PATCH v3 0/2] pack-bitmap: fix memory leak if load_bitmap_entries_v1 failed Lidong Yan via GitGitGadget
2025-05-25  2:06     ` [PATCH v3 1/2] pack-bitmap: fix memory leak if `load_bitmap_entries_v1` failed Taylor Blau via GitGitGadget
2025-05-25  2:06     ` [PATCH v3 2/2] pack-bitmap: add load corrupt bitmap test Lidong Yan via GitGitGadget
2025-05-25  2:43     ` [PATCH v4 0/2] pack-bitmap: fix memory leak if load_bitmap failed Lidong Yan via GitGitGadget
2025-05-25  2:43       ` [PATCH v4 1/2] pack-bitmap: fix memory leak if load_bitmap() failed Taylor Blau via GitGitGadget
2025-05-29 15:33         ` Junio C Hamano
2025-05-29 19:57           ` Taylor Blau
2025-05-29 22:04             ` Junio C Hamano
2025-05-30  3:50           ` lidongyan
2025-05-25  2:43       ` [PATCH v4 2/2] pack-bitmap: add load corrupt bitmap test Lidong Yan via GitGitGadget
2025-05-29 15:45         ` Junio C Hamano
2025-05-29 21:21           ` Taylor Blau
2025-05-30  3:53           ` lidongyan
2025-05-29 21:20         ` Taylor Blau
2025-05-30  4:03           ` lidongyan
2025-06-03  3:14       ` Lidong Yan via GitGitGadget [this message]
2025-06-03  3:14         ` [PATCH v5 1/3] pack-bitmap: fix memory leak if load_bitmap() failed Taylor Blau via GitGitGadget
2025-06-03  3:14         ` [PATCH v5 2/3] pack-bitmap: reword comments in test_bitmap_commits() Lidong Yan via GitGitGadget
2025-06-03 22:13           ` Taylor Blau
2025-06-03  3:14         ` [PATCH v5 3/3] pack-bitmap: add load corrupt bitmap test Lidong Yan via GitGitGadget
2025-06-03 22:14         ` [PATCH v5 0/3] pack-bitmap: fix memory leak if load_bitmap failed Taylor Blau
2025-07-01  5:32         ` [PATCH v6 " Lidong Yan via GitGitGadget
2025-07-01  5:32           ` [PATCH v6 1/3] pack-bitmap: fix memory leak if load_bitmap() failed Taylor Blau via GitGitGadget
2025-07-01  5:32           ` [PATCH v6 2/3] pack-bitmap: reword comments in test_bitmap_commits() Lidong Yan via GitGitGadget
2025-07-01  5:32           ` [PATCH v6 3/3] pack-bitmap: add load corrupt bitmap test Lidong Yan via GitGitGadget
2025-07-07 22:53           ` [PATCH v6 0/3] pack-bitmap: fix memory leak if load_bitmap failed Junio C Hamano
2025-07-08 22:10             ` Taylor Blau
2025-07-08 22:35               ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=pull.1962.v5.git.git.1748920444.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=502024330056@smail.nju.edu.cn \
    --cc=git@vger.kernel.org \
    --cc=me@ttaylorr.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.