{"thread":{"id":"29328","subject":"leaky cherry-pick","startedAt":"2012-01-09T22:37:37Z","lastAt":"2012-01-12T03:05:03Z","messageCount":11,"participants":["Pete Wyckoff","Junio C Hamano","Nguyen Thai Ngoc Duy","Ramkumar Ramachandra","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"182187","messageId":"20120109223737.GA1589@padd.com","threadId":"29328","inReplyTo":null,"subject":"leaky cherry-pick","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2012-01-09T22:37:37Z","receivedAt":"2012-01-09T22:37:37Z","isPatch":false,"sender":{"key":"pw@padd.com","avatar":null},"body":"I've got a big tree, and rebased 200 commits today using\ncherry-pick.  It ran out of memory.  Both 1.7.4 and recent\nmaster (eac2d83 (Git 1.7.9-rc0, 2012-01-06)) behave similarly.\n\nHere's a valgrind dump for rebasing just 9 commits, if someone is\ninterested to track this down.  This was invoked as:\n\n    valgrind --log-file=/tmp/vg.out --leak-check=full \\\n    /home/pw/src/git/git cherry-pick 8d535b6^..2cf53a0\n\nI can re-test if you like, or provide more detail if this seems\nunusual.\n\nScroll to the end to see the biggest leaks.\n\n\t\t-- Pete\n\n==18789== Memcheck, a memory error detector\n==18789== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.\n==18789== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info\n==18789== Command: /home/pw/src/git/git cherry-pick 8d535b6^..2cf53a0\n==18789== Parent PID: 2325\n==18789== \n==18789== Conditional jump or move depends on uninitialised value(s)\n==18789==    at 0x4E37290: inflateReset2 (in /usr/lib/libz.so.1.2.3.4)\n==18789==    by 0x4E3737F: inflateInit2_ (in /usr/lib/libz.so.1.2.3.4)\n==18789==    by 0x5260FB: git_inflate_init (zlib.c:72)\n==18789==    by 0x5025B2: unpack_sha1_header (sha1_file.c:1320)\n==18789==    by 0x5028A1: unpack_sha1_file (sha1_file.c:1426)\n==18789==    by 0x50447D: read_object (sha1_file.c:2220)\n==18789==    by 0x504512: read_sha1_file_extended (sha1_file.c:2245)\n==18789==    by 0x4D3880: read_sha1_file (cache.h:760)\n==18789==    by 0x4D3E9F: parse_object (object.c:194)\n==18789==    by 0x494A13: lookup_commit_reference_gently (commit.c:31)\n==18789==    by 0x494A6C: lookup_commit_reference (commit.c:40)\n==18789==    by 0x50691A: get_parent (sha1_name.c:371)\n==18789== \n==18789== Conditional jump or move depends on uninitialised value(s)\n==18789==    at 0x4E37290: inflateReset2 (in /usr/lib/libz.so.1.2.3.4)\n==18789==    by 0x4E3737F: inflateInit2_ (in /usr/lib/libz.so.1.2.3.4)\n==18789==    by 0x5260FB: git_inflate_init (zlib.c:72)\n==18789==    by 0x502E9E: unpack_compressed_entry (sha1_file.c:1629)\n==18789==    by 0x503810: unpack_entry (sha1_file.c:1880)\n==18789==    by 0x5030B5: cache_or_unpack_entry (sha1_file.c:1690)\n==18789==    by 0x5041E4: read_packed_sha1 (sha1_file.c:2162)\n==18789==    by 0x50442F: read_object (sha1_file.c:2215)\n==18789==    by 0x504512: read_sha1_file_extended (sha1_file.c:2245)\n==18789==    by 0x494981: read_sha1_file (cache.h:760)\n==18789==    by 0x49561E: parse_commit (commit.c:317)\n==18789==    by 0x4F52DC: add_parents_to_list (revision.c:543)\n==18789== \n==18789== Warning: set address range perms: large range [0x133a0000, 0x37dad000) (defined)\n==18789== Warning: set address range perms: large range [0x4c438000, 0x7b85a000) (defined)\n==18789== Conditional jump or move depends on uninitialised value(s)\n==18789==    at 0x537450F: __strspn_sse42 (strspn-c.c:126)\n==18789==    by 0x488910: parse_attr (attr.c:189)\n==18789==    by 0x488ABC: parse_attr_line (attr.c:232)\n==18789==    by 0x488CFB: handle_attr_line (attr.c:320)\n==18789==    by 0x488E86: read_attr_from_file (attr.c:358)\n==18789==    by 0x489130: read_attr (attr.c:428)\n==18789==    by 0x489335: bootstrap_attr_stack (attr.c:525)\n==18789==    by 0x48940F: prepare_attr_stack (attr.c:568)\n==18789==    by 0x489A27: collect_all_attrs (attr.c:725)\n==18789==    by 0x489AED: git_check_attr (attr.c:739)\n==18789==    by 0x49E314: convert_attrs (convert.c:730)\n==18789==    by 0x49F230: get_stream_filter (convert.c:1247)\n==18789== \n==18789== Conditional jump or move depends on uninitialised value(s)\n==18789==    at 0x488AC6: parse_attr_line (attr.c:233)\n==18789==    by 0x488CFB: handle_attr_line (attr.c:320)\n==18789==    by 0x488E86: read_attr_from_file (attr.c:358)\n==18789==    by 0x489130: read_attr (attr.c:428)\n==18789==    by 0x489335: bootstrap_attr_stack (attr.c:525)\n==18789==    by 0x48940F: prepare_attr_stack (attr.c:568)\n==18789==    by 0x489A27: collect_all_attrs (attr.c:725)\n==18789==    by 0x489AED: git_check_attr (attr.c:739)\n==18789==    by 0x49E314: convert_attrs (convert.c:730)\n==18789==    by 0x49F230: get_stream_filter (convert.c:1247)\n==18789==    by 0x4B69B1: write_entry (entry.c:191)\n==18789==    by 0x4B6FDD: checkout_entry (entry.c:318)\n==18789== \n==18789== Use of uninitialised value of size 8\n==18789==    at 0x488ADA: parse_attr_line (attr.c:231)\n==18789==    by 0x488CFB: handle_attr_line (attr.c:320)\n==18789==    by 0x488E86: read_attr_from_file (attr.c:358)\n==18789==    by 0x489130: read_attr (attr.c:428)\n==18789==    by 0x489335: bootstrap_attr_stack (attr.c:525)\n==18789==    by 0x48940F: prepare_attr_stack (attr.c:568)\n==18789==    by 0x489A27: collect_all_attrs (attr.c:725)\n==18789==    by 0x489AED: git_check_attr (attr.c:739)\n==18789==    by 0x49E314: convert_attrs (convert.c:730)\n==18789==    by 0x49F230: get_stream_filter (convert.c:1247)\n==18789==    by 0x4B69B1: write_entry (entry.c:191)\n==18789==    by 0x4B6FDD: checkout_entry (entry.c:318)\n==18789== \n==18789== Conditional jump or move depends on uninitialised value(s)\n==18789==    at 0x537450F: __strspn_sse42 (strspn-c.c:126)\n==18789==    by 0x488910: parse_attr (attr.c:189)\n==18789==    by 0x488BD1: parse_attr_line (attr.c:253)\n==18789==    by 0x488CFB: handle_attr_line (attr.c:320)\n==18789==    by 0x488E86: read_attr_from_file (attr.c:358)\n==18789==    by 0x489130: read_attr (attr.c:428)\n==18789==    by 0x489335: bootstrap_attr_stack (attr.c:525)\n==18789==    by 0x48940F: prepare_attr_stack (attr.c:568)\n==18789==    by 0x489A27: collect_all_attrs (attr.c:725)\n==18789==    by 0x489AED: git_check_attr (attr.c:739)\n==18789==    by 0x49E314: convert_attrs (convert.c:730)\n==18789==    by 0x49F230: get_stream_filter (convert.c:1247)\n==18789== \n==18789== Use of uninitialised value of size 8\n==18789==    at 0x488BDE: parse_attr_line (attr.c:252)\n==18789==    by 0x488CFB: handle_attr_line (attr.c:320)\n==18789==    by 0x488E86: read_attr_from_file (attr.c:358)\n==18789==    by 0x489130: read_attr (attr.c:428)\n==18789==    by 0x489335: bootstrap_attr_stack (attr.c:525)\n==18789==    by 0x48940F: prepare_attr_stack (attr.c:568)\n==18789==    by 0x489A27: collect_all_attrs (attr.c:725)\n==18789==    by 0x489AED: git_check_attr (attr.c:739)\n==18789==    by 0x49E314: convert_attrs (convert.c:730)\n==18789==    by 0x49F230: get_stream_filter (convert.c:1247)\n==18789==    by 0x4B69B1: write_entry (entry.c:191)\n==18789==    by 0x4B6FDD: checkout_entry (entry.c:318)\n==18789== \n==18789== \n==18789== HEAP SUMMARY:\n==18789==     in use at exit: 511,786,999 bytes in 3,954,180 blocks\n==18789==   total heap usage: 6,352,564 allocs, 2,398,384 frees, 2,610,529,433 bytes allocated\n==18789== \n==18789== 1 bytes in 1 blocks are definitely lost in loss record 2 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x52DC421: strdup (strdup.c:43)\n==18789==    by 0x51FDC8: xstrdup (wrapper.c:23)\n==18789==    by 0x4B7181: expand_namespace (environment.c:104)\n==18789==    by 0x4B7480: setup_git_env (environment.c:144)\n==18789==    by 0x4B750B: get_git_dir (environment.c:162)\n==18789==    by 0x4D918B: git_vsnpath (path.c:53)\n==18789==    by 0x4D93D8: git_pathdup (path.c:85)\n==18789==    by 0x499E96: git_config (config.c:925)\n==18789==    by 0x4047A4: check_pager_config (git.c:48)\n==18789==    by 0x40522D: run_builtin (git.c:293)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789== \n==18789== 5 bytes in 1 blocks are definitely lost in loss record 6 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x52DC421: strdup (strdup.c:43)\n==18789==    by 0x51FDC8: xstrdup (wrapper.c:23)\n==18789==    by 0x4986C9: git_config_string (config.c:475)\n==18789==    by 0x4990B4: git_default_core_config (config.c:646)\n==18789==    by 0x499955: git_default_config (config.c:796)\n==18789==    by 0x497E22: get_value (config.c:222)\n==18789==    by 0x498150: git_parse_file (config.c:330)\n==18789==    by 0x499BFB: git_config_from_file (config.c:847)\n==18789==    by 0x499DD5: git_config_early (config.c:896)\n==18789==    by 0x499EB1: git_config (config.c:926)\n==18789==    by 0x476839: cmd_cherry_pick (revert.c:1160)\n==18789== \n==18789== 11 bytes in 1 blocks are definitely lost in loss record 8 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n==18789==    by 0x4B73F8: setup_git_env (environment.c:136)\n==18789==    by 0x4B750B: get_git_dir (environment.c:162)\n==18789==    by 0x4D918B: git_vsnpath (path.c:53)\n==18789==    by 0x4D93D8: git_pathdup (path.c:85)\n==18789==    by 0x499E96: git_config (config.c:925)\n==18789==    by 0x4047A4: check_pager_config (git.c:48)\n==18789==    by 0x40522D: run_builtin (git.c:293)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789==    by 0x40558E: run_argv (git.c:513)\n==18789==    by 0x40571B: main (git.c:588)\n==18789== \n==18789== 13 bytes in 1 blocks are definitely lost in loss record 10 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n==18789==    by 0x4B737B: setup_git_env (environment.c:131)\n==18789==    by 0x4B750B: get_git_dir (environment.c:162)\n==18789==    by 0x4D918B: git_vsnpath (path.c:53)\n==18789==    by 0x4D93D8: git_pathdup (path.c:85)\n==18789==    by 0x499E96: git_config (config.c:925)\n==18789==    by 0x4047A4: check_pager_config (git.c:48)\n==18789==    by 0x40522D: run_builtin (git.c:293)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789==    by 0x40558E: run_argv (git.c:513)\n==18789==    by 0x40571B: main (git.c:588)\n==18789== \n==18789== 16 bytes in 1 blocks are definitely lost in loss record 14 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n==18789==    by 0x49578D: commit_list_insert (commit.c:356)\n==18789==    by 0x495886: commit_list_insert_by_date (commit.c:390)\n==18789==    by 0x4F51BC: commit_list_insert_by_date_cached (revision.c:508)\n==18789==    by 0x4F5344: add_parents_to_list (revision.c:550)\n==18789==    by 0x4F5C62: limit_list (revision.c:836)\n==18789==    by 0x4FA49B: prepare_revision_walk (revision.c:2068)\n==18789==    by 0x47522F: prepare_revs (revert.c:650)\n==18789==    by 0x475B6D: walk_revs_populate_todo (revert.c:855)\n==18789==    by 0x4766BF: pick_revisions (revert.c:1123)\n==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n==18789== \n==18789== 17 bytes in 1 blocks are definitely lost in loss record 17 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x52DC421: strdup (strdup.c:43)\n==18789==    by 0x51FDC8: xstrdup (wrapper.c:23)\n==18789==    by 0x4D93E7: git_pathdup (path.c:87)\n==18789==    by 0x4B744E: setup_git_env (environment.c:141)\n==18789==    by 0x4B750B: get_git_dir (environment.c:162)\n==18789==    by 0x4D918B: git_vsnpath (path.c:53)\n==18789==    by 0x4D93D8: git_pathdup (path.c:85)\n==18789==    by 0x499E96: git_config (config.c:925)\n==18789==    by 0x4047A4: check_pager_config (git.c:48)\n==18789==    by 0x40522D: run_builtin (git.c:293)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789== \n==18789== 24 bytes in 1 blocks are definitely lost in loss record 21 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x4C27927: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FFCD: xrealloc (wrapper.c:82)\n==18789==    by 0x509A01: strbuf_grow (strbuf.c:72)\n==18789==    by 0x50A03A: strbuf_add (strbuf.c:190)\n==18789==    by 0x4D9CB4: expand_user_path (path.c:255)\n==18789==    by 0x49870C: git_config_pathname (config.c:483)\n==18789==    by 0x499186: git_default_core_config (config.c:655)\n==18789==    by 0x499955: git_default_config (config.c:796)\n==18789==    by 0x497E22: get_value (config.c:222)\n==18789==    by 0x498150: git_parse_file (config.c:330)\n==18789==    by 0x499BFB: git_config_from_file (config.c:847)\n==18789== \n==18789== 40 bytes in 8 blocks are definitely lost in loss record 23 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x52DC421: strdup (strdup.c:43)\n==18789==    by 0x51FDC8: xstrdup (wrapper.c:23)\n==18789==    by 0x4986C9: git_config_string (config.c:475)\n==18789==    by 0x4990B4: git_default_core_config (config.c:646)\n==18789==    by 0x499955: git_default_config (config.c:796)\n==18789==    by 0x525EBD: git_xmerge_config (xdiff-interface.c:362)\n==18789==    by 0x4CD25A: merge_recursive_config (merge-recursive.c:2032)\n==18789==    by 0x497E22: get_value (config.c:222)\n==18789==    by 0x498150: git_parse_file (config.c:330)\n==18789==    by 0x499BFB: git_config_from_file (config.c:847)\n==18789==    by 0x499DD5: git_config_early (config.c:896)\n==18789== \n==18789== 65 bytes in 1 blocks are definitely lost in loss record 30 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x4C27927: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FFCD: xrealloc (wrapper.c:82)\n==18789==    by 0x509A01: strbuf_grow (strbuf.c:72)\n==18789==    by 0x50A1E3: strbuf_vaddf (strbuf.c:216)\n==18789==    by 0x50A1AA: strbuf_addf (strbuf.c:206)\n==18789==    by 0x475CAF: save_head (revert.c:884)\n==18789==    by 0x476737: pick_revisions (revert.c:1131)\n==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n==18789==    by 0x4052E1: run_builtin (git.c:308)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789==    by 0x40558E: run_argv (git.c:513)\n==18789== \n==18789== 144 (16 direct, 128 indirect) bytes in 1 blocks are definitely lost in loss record 41 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n==18789==    by 0x47536C: commit_list_append (revert.c:692)\n==18789==    by 0x475B8A: walk_revs_populate_todo (revert.c:859)\n==18789==    by 0x4766BF: pick_revisions (revert.c:1123)\n==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n==18789==    by 0x4052E1: run_builtin (git.c:308)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789==    by 0x40558E: run_argv (git.c:513)\n==18789==    by 0x40571B: main (git.c:588)\n==18789== \n==18789== 192 bytes in 8 blocks are definitely lost in loss record 48 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x4C27927: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FFCD: xrealloc (wrapper.c:82)\n==18789==    by 0x509A01: strbuf_grow (strbuf.c:72)\n==18789==    by 0x50A03A: strbuf_add (strbuf.c:190)\n==18789==    by 0x4D9CB4: expand_user_path (path.c:255)\n==18789==    by 0x49870C: git_config_pathname (config.c:483)\n==18789==    by 0x499186: git_default_core_config (config.c:655)\n==18789==    by 0x499955: git_default_config (config.c:796)\n==18789==    by 0x525EBD: git_xmerge_config (xdiff-interface.c:362)\n==18789==    by 0x4CD25A: merge_recursive_config (merge-recursive.c:2032)\n==18789==    by 0x497E22: get_value (config.c:222)\n==18789== \n==18789== 281 bytes in 2 blocks are possibly lost in loss record 51 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n==18789==    by 0x4E483E: create_from_disk (read-cache.c:1255)\n==18789==    by 0x4E4B7F: read_index_from (read-cache.c:1328)\n==18789==    by 0x4E4758: read_index (read-cache.c:1224)\n==18789==    by 0x47469F: do_recursive_merge (revert.c:411)\n==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n==18789==    by 0x47635D: pick_commits (revert.c:1022)\n==18789==    by 0x476756: pick_revisions (revert.c:1133)\n==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n==18789==    by 0x4052E1: run_builtin (git.c:308)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789== \n==18789== 704 bytes in 8 blocks are definitely lost in loss record 58 of 97\n==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x520084: xcalloc (wrapper.c:98)\n==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789==    by 0x51C1F5: unpack_trees (unpack-trees.c:1063)\n==18789==    by 0x4A46BD: diff_cache (diff-lib.c:474)\n==18789==    by 0x4A46FC: run_diff_index (diff-lib.c:482)\n==18789==    by 0x4A48DA: index_differs_from (diff-lib.c:517)\n==18789==    by 0x474AC2: do_pick_commit (revert.c:503)\n==18789==    by 0x47635D: pick_commits (revert.c:1022)\n==18789== \n==18789== 1,107 bytes in 9 blocks are definitely lost in loss record 62 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n==18789==    by 0x519DCD: setup_unpack_trees_porcelain (unpack-trees.c:79)\n==18789==    by 0x4C8160: git_merge_trees (merge-recursive.c:235)\n==18789==    by 0x4CC907: merge_trees (merge-recursive.c:1817)\n==18789==    by 0x4747B8: do_recursive_merge (revert.c:425)\n==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n==18789==    by 0x47635D: pick_commits (revert.c:1022)\n==18789==    by 0x476756: pick_revisions (revert.c:1133)\n==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n==18789==    by 0x4052E1: run_builtin (git.c:308)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789== \n==18789== 1,143 bytes in 9 blocks are definitely lost in loss record 63 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n==18789==    by 0x519E8F: setup_unpack_trees_porcelain (unpack-trees.c:82)\n==18789==    by 0x4C8160: git_merge_trees (merge-recursive.c:235)\n==18789==    by 0x4CC907: merge_trees (merge-recursive.c:1817)\n==18789==    by 0x4747B8: do_recursive_merge (revert.c:425)\n==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n==18789==    by 0x47635D: pick_commits (revert.c:1022)\n==18789==    by 0x476756: pick_revisions (revert.c:1133)\n==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n==18789==    by 0x4052E1: run_builtin (git.c:308)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789== \n==18789== 1,269 bytes in 9 blocks are definitely lost in loss record 64 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n==18789==    by 0x519CE0: setup_unpack_trees_porcelain (unpack-trees.c:66)\n==18789==    by 0x4C8160: git_merge_trees (merge-recursive.c:235)\n==18789==    by 0x4CC907: merge_trees (merge-recursive.c:1817)\n==18789==    by 0x4747B8: do_recursive_merge (revert.c:425)\n==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n==18789==    by 0x47635D: pick_commits (revert.c:1022)\n==18789==    by 0x476756: pick_revisions (revert.c:1133)\n==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n==18789==    by 0x4052E1: run_builtin (git.c:308)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789== \n==18789== 1,316 bytes in 10 blocks are possibly lost in loss record 65 of 97\n==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x520084: xcalloc (wrapper.c:98)\n==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789== \n==18789== 1,728 bytes in 9 blocks are definitely lost in loss record 67 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x4C27927: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FFCD: xrealloc (wrapper.c:82)\n==18789==    by 0x488D5B: handle_attr_line (attr.c:325)\n==18789==    by 0x488DDD: read_attr_from_array (attr.c:340)\n==18789==    by 0x48924E: bootstrap_attr_stack (attr.c:501)\n==18789==    by 0x48940F: prepare_attr_stack (attr.c:568)\n==18789==    by 0x489A27: collect_all_attrs (attr.c:725)\n==18789==    by 0x489AED: git_check_attr (attr.c:739)\n==18789==    by 0x49E314: convert_attrs (convert.c:730)\n==18789==    by 0x49F230: get_stream_filter (convert.c:1247)\n==18789==    by 0x4B69B1: write_entry (entry.c:191)\n==18789== \n==18789== 2,072 (1,496 direct, 576 indirect) bytes in 1 blocks are definitely lost in loss record 70 of 97\n==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n==18789==    by 0x473F5B: parse_args (revert.c:228)\n==18789==    by 0x47684E: cmd_cherry_pick (revert.c:1161)\n==18789==    by 0x4052E1: run_builtin (git.c:308)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789==    by 0x40558E: run_argv (git.c:513)\n==18789==    by 0x40571B: main (git.c:588)\n==18789== \n==18789== 2,376 bytes in 27 blocks are definitely lost in loss record 72 of 97\n==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x520084: xcalloc (wrapper.c:98)\n==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789==    by 0x51C1F5: unpack_trees (unpack-trees.c:1063)\n==18789==    by 0x4C81C2: git_merge_trees (merge-recursive.c:241)\n==18789==    by 0x4CC907: merge_trees (merge-recursive.c:1817)\n==18789==    by 0x4747B8: do_recursive_merge (revert.c:425)\n==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n==18789==    by 0x47635D: pick_commits (revert.c:1022)\n==18789== \n==18789== 7,726 (4,320 direct, 3,406 indirect) bytes in 9 blocks are definitely lost in loss record 77 of 97\n==18789==    at 0x4C27882: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FFCD: xrealloc (wrapper.c:82)\n==18789==    by 0x488D5B: handle_attr_line (attr.c:325)\n==18789==    by 0x488E86: read_attr_from_file (attr.c:358)\n==18789==    by 0x489130: read_attr (attr.c:428)\n==18789==    by 0x489335: bootstrap_attr_stack (attr.c:525)\n==18789==    by 0x48940F: prepare_attr_stack (attr.c:568)\n==18789==    by 0x489A27: collect_all_attrs (attr.c:725)\n==18789==    by 0x489AED: git_check_attr (attr.c:739)\n==18789==    by 0x49E314: convert_attrs (convert.c:730)\n==18789==    by 0x49F230: get_stream_filter (convert.c:1247)\n==18789==    by 0x4B69B1: write_entry (entry.c:191)\n==18789== \n==18789== 744,353 bytes in 7,493 blocks are definitely lost in loss record 88 of 97\n==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x520084: xcalloc (wrapper.c:98)\n==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789==    by 0x51C1F5: unpack_trees (unpack-trees.c:1063)\n==18789==    by 0x4A46BD: diff_cache (diff-lib.c:474)\n==18789==    by 0x4A46FC: run_diff_index (diff-lib.c:482)\n==18789== \n==18789== 1,865,981 bytes in 18,806 blocks are definitely lost in loss record 90 of 97\n==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x520084: xcalloc (wrapper.c:98)\n==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789==    by 0x51C1F5: unpack_trees (unpack-trees.c:1063)\n==18789==    by 0x4C81C2: git_merge_trees (merge-recursive.c:241)\n==18789==    by 0x4CC907: merge_trees (merge-recursive.c:1817)\n==18789== \n==18789== 8,386,453 (1,031,576 direct, 7,354,877 indirect) bytes in 1 blocks are definitely lost in loss record 91 of 97\n==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x520084: xcalloc (wrapper.c:98)\n==18789==    by 0x4E4B38: read_index_from (read-cache.c:1319)\n==18789==    by 0x4E4758: read_index (read-cache.c:1224)\n==18789==    by 0x4DB50F: read_index_preload (preload-index.c:105)\n==18789==    by 0x4752A1: read_and_refresh_cache (revert.c:661)\n==18789==    by 0x47657B: pick_revisions (revert.c:1081)\n==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n==18789==    by 0x4052E1: run_builtin (git.c:308)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789==    by 0x40558E: run_argv (git.c:513)\n==18789==    by 0x40571B: main (git.c:588)\n==18789== \n==18789== 69,782,106 (6,793,984 direct, 62,988,122 indirect) bytes in 8 blocks are definitely lost in loss record 94 of 97\n==18789==    at 0x4C27882: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x51FFCD: xrealloc (wrapper.c:82)\n==18789==    by 0x4E3D7C: add_index_entry (read-cache.c:976)\n==18789==    by 0x519FFE: add_entry (unpack-trees.c:119)\n==18789==    by 0x51D0A6: merged_entry (unpack-trees.c:1501)\n==18789==    by 0x51D444: threeway_merge (unpack-trees.c:1615)\n==18789==    by 0x51A645: call_unpack_fn (unpack-trees.c:289)\n==18789==    by 0x51B1E2: unpack_nondirectories (unpack-trees.c:586)\n==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n==18789== \n==18789== 105,619,300 (9,284,184 direct, 96,335,116 indirect) bytes in 9 blocks are definitely lost in loss record 96 of 97\n==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x520084: xcalloc (wrapper.c:98)\n==18789==    by 0x4E4B38: read_index_from (read-cache.c:1319)\n==18789==    by 0x4E4758: read_index (read-cache.c:1224)\n==18789==    by 0x47469F: do_recursive_merge (revert.c:411)\n==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n==18789==    by 0x47635D: pick_commits (revert.c:1022)\n==18789==    by 0x476756: pick_revisions (revert.c:1133)\n==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n==18789==    by 0x4052E1: run_builtin (git.c:308)\n==18789==    by 0x405474: handle_internal_command (git.c:467)\n==18789==    by 0x40558E: run_argv (git.c:513)\n==18789== \n==18789== 313,333,787 bytes in 2,509,382 blocks are definitely lost in loss record 97 of 97\n==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n==18789==    by 0x520084: xcalloc (wrapper.c:98)\n==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n==18789== \n==18789== LEAK SUMMARY:\n==18789==    definitely lost: 333,068,408 bytes in 2,535,805 blocks\n==18789==    indirectly lost: 166,682,225 bytes in 1,331,950 blocks\n==18789==      possibly lost: 1,597 bytes in 12 blocks\n==18789==    still reachable: 12,034,769 bytes in 86,413 blocks\n==18789==         suppressed: 0 bytes in 0 blocks\n==18789== Reachable blocks (those to which a pointer was found) are not shown.\n==18789== To see them, rerun with: --leak-check=full --show-reachable=yes\n==18789== \n==18789== For counts of detected and suppressed errors, rerun with: -v\n==18789== Use --track-origins=yes to see where uninitialised values come from\n==18789== ERROR SUMMARY: 241596 errors from 34 contexts (suppressed: 4 from 4)\n"},{"id":"182191","messageId":"7vk450cvl1.fsf@alter.siamese.dyndns.org","threadId":"29328","inReplyTo":"20120109223737.GA1589@padd.com","subject":"Re: leaky cherry-pick","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-09T23:19:54Z","receivedAt":"2012-01-09T23:19:54Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pete Wyckoff <pw@padd.com> writes:\n\n> I've got a big tree, and rebased 200 commits today using\n> cherry-pick.  It ran out of memory....\n>\n>     valgrind --log-file=/tmp/vg.out --leak-check=full \\\n>     /home/pw/src/git/git cherry-pick 8d535b6^..2cf53a0\n\nThe cherry-pick and revert machinery was written to be single-shot and the\nmulti-pick feature was bolted on to it later; I am not so surprised if\nnobody carefully looked at the memory usage when that happened.\n\nRam?\n"},{"id":"182196","messageId":"CACsJy8DpOY6UUVBjPK4k5BbvbfAckc+N5hoDTwRq5c7koZ=OgQ@mail.gmail.com","threadId":"29328","inReplyTo":"20120109223737.GA1589@padd.com","subject":"Re: leaky cherry-pick","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-01-10T01:38:30Z","receivedAt":"2012-01-10T01:38:30Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, Jan 10, 2012 at 5:37 AM, Pete Wyckoff <pw@padd.com> wrote:\n> I've got a big tree, and rebased 200 commits today using\n> cherry-pick.  It ran out of memory.  Both 1.7.4 and recent\n> master (eac2d83 (Git 1.7.9-rc0, 2012-01-06)) behave similarly.\n>\n> Here's a valgrind dump for rebasing just 9 commits, if someone is\n> interested to track this down.  This was invoked as:\n>\n>    valgrind --log-file=/tmp/vg.out --leak-check=full \\\n>    /home/pw/src/git/git cherry-pick 8d535b6^..2cf53a0\n>\n> I can re-test if you like, or provide more detail if this seems\n> unusual.\n>\n> Scroll to the end to see the biggest leaks.\n\nIndex entries are leaked since probably forever because we allocated\nentries in bulk and could not release them individually, until debed2a\n(read-cache.c: allocate index entries individually). Putting\ndiscard_index() to read_and_refresh_cache() might help, I think.\n-- \nDuy\n"},{"id":"182208","messageId":"CALkWK0nwE0c6qVvbauPrjmb3NX4NDeGSrvrC2ry2bjMeM4Hr0A@mail.gmail.com","threadId":"29328","inReplyTo":"20120109223737.GA1589@padd.com","subject":"Re: leaky cherry-pick","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2012-01-10T05:28:45Z","receivedAt":"2012-01-10T05:28:45Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Hi,\n\nPete Wyckoff wrote:\n> ==18789== HEAP SUMMARY:\n> ==18789==     in use at exit: 511,786,999 bytes in 3,954,180 blocks\n> ==18789==   total heap usage: 6,352,564 allocs, 2,398,384 frees, 2,610,529,433 bytes allocated\n\nThis is disturbing, to say the least.  Let me try to chomp through the\nValgrind output to see what I understand.\n\n[Re-ordering for convenience]\n> [...]\n\nIgnoring small losses from strdup(), parse_args() and other unrelated\nthings for the moment.\n\n> ==18789== 16 bytes in 1 blocks are definitely lost in loss record 14 of 97\n> ==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n> ==18789==    by 0x49578D: commit_list_insert (commit.c:356)\n> ==18789==    by 0x495886: commit_list_insert_by_date (commit.c:390)\n> ==18789==    by 0x4F51BC: commit_list_insert_by_date_cached (revision.c:508)\n> ==18789==    by 0x4F5344: add_parents_to_list (revision.c:550)\n> ==18789==    by 0x4F5C62: limit_list (revision.c:836)\n> ==18789==    by 0x4FA49B: prepare_revision_walk (revision.c:2068)\n> ==18789==    by 0x47522F: prepare_revs (revert.c:650)\n> ==18789==    by 0x475B6D: walk_revs_populate_todo (revert.c:855)\n> ==18789==    by 0x4766BF: pick_revisions (revert.c:1123)\n> ==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n> ==18789==\n> ==18789== 144 (16 direct, 128 indirect) bytes in 1 blocks are definitely lost in loss record 41 of 97\n> ==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n> ==18789==    by 0x47536C: commit_list_append (revert.c:692)\n> ==18789==    by 0x475B8A: walk_revs_populate_todo (revert.c:859)\n> ==18789==    by 0x4766BF: pick_revisions (revert.c:1123)\n> ==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n> ==18789==    by 0x4052E1: run_builtin (git.c:308)\n> ==18789==    by 0x405474: handle_internal_command (git.c:467)\n> ==18789==    by 0x40558E: run_argv (git.c:513)\n> ==18789==    by 0x40571B: main (git.c:588)\n\nUgh, I never free the commit_list I build up in commit_list_append().\nRough sketch of fix (caution: untested):\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex 0d8020c..76be0e3 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -770,8 +770,11 @@ static int parse_insn_buffer(char *buf, struct\ncommit_list **todo_list,\n \tfor (i = 1; *p; i++) {\n \t\tchar *eol = strchrnul(p, '\\n');\n \t\tcommit = parse_insn_line(p, eol, opts);\n-\t\tif (!commit)\n+\t\tif (!commit) {\n+\t\t\tif (*todo_list)\n+\t\t\t\tfree_commit_list(*todo_list);\n \t\t\treturn error(_(\"Could not parse line %d.\"), i);\n+\t\t}\n \t\tnext = commit_list_append(commit, next);\n \t\tp = *eol ? eol + 1 : eol;\n \t}\n@@ -1020,14 +1023,17 @@ static int pick_commits(struct commit_list\n*todo_list, struct replay_opts *opts)\n \tfor (cur = todo_list; cur; cur = cur->next) {\n \t\tsave_todo(cur, opts);\n \t\tres = do_pick_commit(cur->item, opts);\n-\t\tif (res)\n+\t\tif (res) {\n+\t\t\tfree_commit_list(todo_list);\n \t\t\treturn res;\n+\t\t}\n \t}\n\n \t/*\n \t * Sequence of picks finished successfully; cleanup by\n \t * removing the .git/sequencer directory\n \t */\n+\tfree_commit_list(todo_list);\n \tremove_sequencer_state();\n \treturn 0;\n }\n--\n\n> ==18789== 1,728 bytes in 9 blocks are definitely lost in loss record 67 of 97\n> ==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x4C27927: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x51FFCD: xrealloc (wrapper.c:82)\n> ==18789==    by 0x488D5B: handle_attr_line (attr.c:325)\n> ==18789==    by 0x488DDD: read_attr_from_array (attr.c:340)\n> ==18789==    by 0x48924E: bootstrap_attr_stack (attr.c:501)\n> ==18789==    by 0x48940F: prepare_attr_stack (attr.c:568)\n> ==18789==    by 0x489A27: collect_all_attrs (attr.c:725)\n> ==18789==    by 0x489AED: git_check_attr (attr.c:739)\n> ==18789==    by 0x49E314: convert_attrs (convert.c:730)\n> ==18789==    by 0x49F230: get_stream_filter (convert.c:1247)\n> ==18789==    by 0x4B69B1: write_entry (entry.c:191)\n> ==18789==\n> ==18789== 7,726 (4,320 direct, 3,406 indirect) bytes in 9 blocks are definitely lost in loss record 77 of 97\n> ==18789==    at 0x4C27882: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x51FFCD: xrealloc (wrapper.c:82)\n> ==18789==    by 0x488D5B: handle_attr_line (attr.c:325)\n> ==18789==    by 0x488E86: read_attr_from_file (attr.c:358)\n> ==18789==    by 0x489130: read_attr (attr.c:428)\n> ==18789==    by 0x489335: bootstrap_attr_stack (attr.c:525)\n> ==18789==    by 0x48940F: prepare_attr_stack (attr.c:568)\n> ==18789==    by 0x489A27: collect_all_attrs (attr.c:725)\n> ==18789==    by 0x489AED: git_check_attr (attr.c:739)\n> ==18789==    by 0x49E314: convert_attrs (convert.c:730)\n> ==18789==    by 0x49F230: get_stream_filter (convert.c:1247)\n> ==18789==    by 0x4B69B1: write_entry (entry.c:191)\n\nInteresting- I wonder where .gitattributes parsing code fits into all\nthis.  The purpose of bootstrap _attr_stack() is to populate\nattr_stack for its callers.  Lots of memory allocation happening in\nhandle_attr_line() -- that information is returned to\nbootstrap_attr_stack().  We have to keep backtracking until that\ninformation is provably useless and free it.  Hm, convert_attrs() (in\nconvert.c) is a common caller in both cases, but the populated\nattr_stack is local to attr.c; I wonder if this is the problem.  If my\nhunch is right, it should be a trivial fix (caution: untested):\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n\ndiff --git a/attr.c b/attr.c\nindex 76b079f..12e3824 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -745,6 +745,7 @@ int git_check_attr(const char *path, int num,\nstruct git_attr_check *check)\n \t\tcheck[i].value = value;\n \t}\n\n+\tdrop_attr_stack();\n \treturn 0;\n }\n --\n\n> ==18789== 1,107 bytes in 9 blocks are definitely lost in loss record 62 of 97\n> ==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n> ==18789==    by 0x519DCD: setup_unpack_trees_porcelain (unpack-trees.c:79)\n> ==18789==    by 0x4C8160: git_merge_trees (merge-recursive.c:235)\n> ==18789==    by 0x4CC907: merge_trees (merge-recursive.c:1817)\n> ==18789==    by 0x4747B8: do_recursive_merge (revert.c:425)\n> ==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n> ==18789==    by 0x47635D: pick_commits (revert.c:1022)\n> ==18789==    by 0x476756: pick_revisions (revert.c:1133)\n> ==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n> ==18789==    by 0x4052E1: run_builtin (git.c:308)\n> ==18789==    by 0x405474: handle_internal_command (git.c:467)\n> ==18789==\n> ==18789== 1,143 bytes in 9 blocks are definitely lost in loss record 63 of 97\n> ==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n> ==18789==    by 0x519E8F: setup_unpack_trees_porcelain (unpack-trees.c:82)\n> ==18789==    by 0x4C8160: git_merge_trees (merge-recursive.c:235)\n> ==18789==    by 0x4CC907: merge_trees (merge-recursive.c:1817)\n> ==18789==    by 0x4747B8: do_recursive_merge (revert.c:425)\n> ==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n> ==18789==    by 0x47635D: pick_commits (revert.c:1022)\n> ==18789==    by 0x476756: pick_revisions (revert.c:1133)\n> ==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n> ==18789==    by 0x4052E1: run_builtin (git.c:308)\n> ==18789==    by 0x405474: handle_internal_command (git.c:467)\n> ==18789==\n> ==18789== 1,269 bytes in 9 blocks are definitely lost in loss record 64 of 97\n> ==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n> ==18789==    by 0x519CE0: setup_unpack_trees_porcelain (unpack-trees.c:66)\n> ==18789==    by 0x4C8160: git_merge_trees (merge-recursive.c:235)\n> ==18789==    by 0x4CC907: merge_trees (merge-recursive.c:1817)\n> ==18789==    by 0x4747B8: do_recursive_merge (revert.c:425)\n> ==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n> ==18789==    by 0x47635D: pick_commits (revert.c:1022)\n> ==18789==    by 0x476756: pick_revisions (revert.c:1133)\n> ==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n> ==18789==    by 0x4052E1: run_builtin (git.c:308)\n> ==18789==    by 0x405474: handle_internal_command (git.c:467)\n> ==18789==\n> ==18789== 704 bytes in 8 blocks are definitely lost in loss record 58 of 97\n> ==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x520084: xcalloc (wrapper.c:98)\n> ==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n> ==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n> ==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==    by 0x51C1F5: unpack_trees (unpack-trees.c:1063)\n> ==18789==    by 0x4A46BD: diff_cache (diff-lib.c:474)\n> ==18789==    by 0x4A46FC: run_diff_index (diff-lib.c:482)\n> ==18789==    by 0x4A48DA: index_differs_from (diff-lib.c:517)\n> ==18789==    by 0x474AC2: do_pick_commit (revert.c:503)\n> ==18789==    by 0x47635D: pick_commits (revert.c:1022)\n> ==18789==\n> ==18789== 1,316 bytes in 10 blocks are possibly lost in loss record 65 of 97\n> ==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x520084: xcalloc (wrapper.c:98)\n> ==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n> ==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n> ==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n> ==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n> ==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==\n> ==18789== 2,376 bytes in 27 blocks are definitely lost in loss record 72 of 97\n> ==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x520084: xcalloc (wrapper.c:98)\n> ==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n> ==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n> ==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==    by 0x51C1F5: unpack_trees (unpack-trees.c:1063)\n> ==18789==    by 0x4C81C2: git_merge_trees (merge-recursive.c:241)\n> ==18789==    by 0x4CC907: merge_trees (merge-recursive.c:1817)\n> ==18789==    by 0x4747B8: do_recursive_merge (revert.c:425)\n> ==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n> ==18789==    by 0x47635D: pick_commits (revert.c:1022)\n> ==18789==\n> ==18789== 744,353 bytes in 7,493 blocks are definitely lost in loss record 88 of 97\n> ==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x520084: xcalloc (wrapper.c:98)\n> ==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n> ==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n> ==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n> ==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==    by 0x51C1F5: unpack_trees (unpack-trees.c:1063)\n> ==18789==    by 0x4A46BD: diff_cache (diff-lib.c:474)\n> ==18789==    by 0x4A46FC: run_diff_index (diff-lib.c:482)\n> ==18789==\n> ==18789== 1,865,981 bytes in 18,806 blocks are definitely lost in loss record 90 of 97\n> ==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x520084: xcalloc (wrapper.c:98)\n> ==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n> ==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n> ==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n> ==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==    by 0x51C1F5: unpack_trees (unpack-trees.c:1063)\n> ==18789==    by 0x4C81C2: git_merge_trees (merge-recursive.c:241)\n> ==18789==    by 0x4CC907: merge_trees (merge-recursive.c:1817)\n> ==18789==\n> ==18789== 313,333,787 bytes in 2,509,382 blocks are definitely lost in loss record 97 of 97\n> ==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x520084: xcalloc (wrapper.c:98)\n> ==18789==    by 0x51AFD1: create_ce_entry (unpack-trees.c:532)\n> ==18789==    by 0x51B1AE: unpack_nondirectories (unpack-trees.c:582)\n> ==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n> ==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n> ==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n\nSo many issues with unpack-trees!  Let's try to look for some common\npatterns, and see where the problems are occurring.  I can see two\ndistinct patterns: backtraces that include\nsetup_unpack_trees_porcelain() and those that include\ncreate_ce_entry().  Let's go with create_ce_entry() first: it\nallocates quite a bit of memory according to cache.h:247.  And it\nreturns the memory back to unpack_nondirectories().  What's worse?\nunpack_nondirectories() calls create_ce_entry() in a loop and stuffs\nall this new memory into a cache_entry provided by unpack_callback().\nIn the end, all the calls boil down to git_merge_trees(): I don't see\nthe ton of memory allocated higher in the callstack being passed down\nin any way.  I don't understand- why doesn't unpack_callback() clean\nup the memory in \"struct cache_entry *src\" after it's done?\n\n> ==18789== 281 bytes in 2 blocks are possibly lost in loss record 51 of 97\n> ==18789==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x51FE4E: xmalloc (wrapper.c:35)\n> ==18789==    by 0x4E483E: create_from_disk (read-cache.c:1255)\n> ==18789==    by 0x4E4B7F: read_index_from (read-cache.c:1328)\n> ==18789==    by 0x4E4758: read_index (read-cache.c:1224)\n> ==18789==    by 0x47469F: do_recursive_merge (revert.c:411)\n> ==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n> ==18789==    by 0x47635D: pick_commits (revert.c:1022)\n> ==18789==    by 0x476756: pick_revisions (revert.c:1133)\n> ==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n> ==18789==    by 0x4052E1: run_builtin (git.c:308)\n> ==18789==    by 0x405474: handle_internal_command (git.c:467)\n> ==18789==\n> ==18789== 8,386,453 (1,031,576 direct, 7,354,877 indirect) bytes in 1 blocks are definitely lost in loss record 91 of 97\n> ==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x520084: xcalloc (wrapper.c:98)\n> ==18789==    by 0x4E4B38: read_index_from (read-cache.c:1319)\n> ==18789==    by 0x4E4758: read_index (read-cache.c:1224)\n> ==18789==    by 0x4DB50F: read_index_preload (preload-index.c:105)\n> ==18789==    by 0x4752A1: read_and_refresh_cache (revert.c:661)\n> ==18789==    by 0x47657B: pick_revisions (revert.c:1081)\n> ==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n> ==18789==    by 0x4052E1: run_builtin (git.c:308)\n> ==18789==    by 0x405474: handle_internal_command (git.c:467)\n> ==18789==    by 0x40558E: run_argv (git.c:513)\n> ==18789==    by 0x40571B: main (git.c:588)\n> ==18789==\n> ==18789== 69,782,106 (6,793,984 direct, 62,988,122 indirect) bytes in 8 blocks are definitely lost in loss record 94 of 97\n> ==18789==    at 0x4C27882: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x51FFCD: xrealloc (wrapper.c:82)\n> ==18789==    by 0x4E3D7C: add_index_entry (read-cache.c:976)\n> ==18789==    by 0x519FFE: add_entry (unpack-trees.c:119)\n> ==18789==    by 0x51D0A6: merged_entry (unpack-trees.c:1501)\n> ==18789==    by 0x51D444: threeway_merge (unpack-trees.c:1615)\n> ==18789==    by 0x51A645: call_unpack_fn (unpack-trees.c:289)\n> ==18789==    by 0x51B1E2: unpack_nondirectories (unpack-trees.c:586)\n> ==18789==    by 0x51B843: unpack_callback (unpack-trees.c:772)\n> ==18789==    by 0x5190F8: traverse_trees (tree-walk.c:407)\n> ==18789==    by 0x51AD8D: traverse_trees_recursive (unpack-trees.c:460)\n> ==18789==    by 0x51B973: unpack_callback (unpack-trees.c:809)\n> ==18789==\n> ==18789== 105,619,300 (9,284,184 direct, 96,335,116 indirect) bytes in 9 blocks are definitely lost in loss record 96 of 97\n> ==18789==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n> ==18789==    by 0x520084: xcalloc (wrapper.c:98)\n> ==18789==    by 0x4E4B38: read_index_from (read-cache.c:1319)\n> ==18789==    by 0x4E4758: read_index (read-cache.c:1224)\n> ==18789==    by 0x47469F: do_recursive_merge (revert.c:411)\n> ==18789==    by 0x474FA5: do_pick_commit (revert.c:598)\n> ==18789==    by 0x47635D: pick_commits (revert.c:1022)\n> ==18789==    by 0x476756: pick_revisions (revert.c:1133)\n> ==18789==    by 0x47685A: cmd_cherry_pick (revert.c:1162)\n> ==18789==    by 0x4052E1: run_builtin (git.c:308)\n> ==18789==    by 0x405474: handle_internal_command (git.c:467)\n> ==18789==    by 0x40558E: run_argv (git.c:513)\n\nWill investigate read-cache the context of Duy's comment- it looks\nlike I have to read through some more history to understand what's\ngoing on.\n\nThanks.\n\n-- Ram\n"},{"id":"182275","messageId":"20120110195017.GA19961@sigill.intra.peff.net","threadId":"29328","inReplyTo":"CALkWK0nwE0c6qVvbauPrjmb3NX4NDeGSrvrC2ry2bjMeM4Hr0A@mail.gmail.com","subject":"Re: leaky cherry-pick","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-01-10T19:50:17Z","receivedAt":"2012-01-10T19:50:17Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Jan 10, 2012 at 10:58:45AM +0530, Ramkumar Ramachandra wrote:\n\n> Interesting- I wonder where .gitattributes parsing code fits into all\n> this.  The purpose of bootstrap _attr_stack() is to populate\n> attr_stack for its callers.  Lots of memory allocation happening in\n> handle_attr_line() -- that information is returned to\n> bootstrap_attr_stack().  We have to keep backtracking until that\n> information is provably useless and free it.  Hm, convert_attrs() (in\n> convert.c) is a common caller in both cases, but the populated\n> attr_stack is local to attr.c; I wonder if this is the problem.  If my\n> hunch is right, it should be a trivial fix (caution: untested):\n> \n> Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n> \n> diff --git a/attr.c b/attr.c\n> index 76b079f..12e3824 100644\n> --- a/attr.c\n> +++ b/attr.c\n> @@ -745,6 +745,7 @@ int git_check_attr(const char *path, int num,\n> struct git_attr_check *check)\n>  \t\tcheck[i].value = value;\n>  \t}\n> \n> +\tdrop_attr_stack();\n>  \treturn 0;\n>  }\n\nI don't think this is right. The attr_stack is intentionally kept in\nplace after a lookup as a cache, because callers are very likely to\nlookup nearby filenames. The first thing we do is pop unrelated parts of\nthe stack, keep the early bits, and then push any new needed\ndirectories.\n\nSo if you do a lookup for \"foo/bar/baz/file1\", the stack afterwards would\nbe:\n\n  $GIT_DIR/info/attributes\n  foo/bar/baz/.gitattributes\n  foo/bar/.gitattributes\n  foo/.gitattributes\n  .gitattributes\n  [builtins]\n\nIf you then do a lookup for \"foo/bar/baz/file2\", it can use the exact\nsame stack without looking for or reparsing the attribute files. If you\nthen do a lookup for \"foo/bar/bleep/file\", it pops only the entry for\n\"foo/bar/baz/.gitattributes\", and pushes only the entry for\n\"foo/bar/bleep/.gitattributes\".\n\nThe calling code _could_ say \"btw, I am done with attributes now, so\nfree the memory\". But we don't bother, since it's a small amount of\nmemory, and other parts of the code may want it later.\n\n-Peff\n"},{"id":"182307","messageId":"CALkWK0kDnxjtQ+ihH_dif_7yivHLd=pibao4KPs_PDXfc2UMOA@mail.gmail.com","threadId":"29328","inReplyTo":"20120110195017.GA19961@sigill.intra.peff.net","subject":"Re: leaky cherry-pick","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2012-01-11T03:30:11Z","receivedAt":"2012-01-11T03:30:11Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Hi Jeff,\n\nJeff King wrote:\n> On Tue, Jan 10, 2012 at 10:58:45AM +0530, Ramkumar Ramachandra wrote:\n>> diff --git a/attr.c b/attr.c\n>> index 76b079f..12e3824 100644\n>> --- a/attr.c\n>> +++ b/attr.c\n>> @@ -745,6 +745,7 @@ int git_check_attr(const char *path, int num,\n>> struct git_attr_check *check)\n>>               check[i].value = value;\n>>       }\n>>\n>> +     drop_attr_stack();\n>>       return 0;\n>>  }\n>\n> I don't think this is right.\n\nYeah, I figured it wasn't right by running the testsuite.  I was\nstruggling to figure out why.\n\n> The attr_stack is intentionally kept in\n> place after a lookup as a cache, because callers are very likely to\n> lookup nearby filenames. The first thing we do is pop unrelated parts of\n> the stack, keep the early bits, and then push any new needed\n> directories.\n>\n> So if you do a lookup for \"foo/bar/baz/file1\", the stack afterwards would\n> be:\n>\n>  $GIT_DIR/info/attributes\n>  foo/bar/baz/.gitattributes\n>  foo/bar/.gitattributes\n>  foo/.gitattributes\n>  .gitattributes\n>  [builtins]\n>\n> If you then do a lookup for \"foo/bar/baz/file2\", it can use the exact\n> same stack without looking for or reparsing the attribute files. If you\n> then do a lookup for \"foo/bar/bleep/file\", it pops only the entry for\n> \"foo/bar/baz/.gitattributes\", and pushes only the entry for\n> \"foo/bar/bleep/.gitattributes\".\n\nI see.  Thanks for the excellent explanation-  I'll try implementing\nthis scheme.\n\n-- Ram\n"},{"id":"182329","messageId":"7vipki7ix9.fsf@alter.siamese.dyndns.org","threadId":"29328","inReplyTo":"CALkWK0kDnxjtQ+ihH_dif_7yivHLd=pibao4KPs_PDXfc2UMOA@mail.gmail.com","subject":"Re: leaky cherry-pick","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-11T08:16:50Z","receivedAt":"2012-01-11T08:16:50Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n>> If you then do a lookup for \"foo/bar/baz/file2\", it can use the exact\n>> same stack without looking for or reparsing the attribute files. If you\n>> then do a lookup for \"foo/bar/bleep/file\", it pops only the entry for\n>> \"foo/bar/baz/.gitattributes\", and pushes only the entry for\n>> \"foo/bar/bleep/.gitattributes\".\n>\n> I see.  Thanks for the excellent explanation-  I'll try implementing\n> this scheme.\n\nI somehow have a feeling that you did not read the conclusion in Peff's\nmessage correctly.  The code only keeps data from one active path of\nper-directory .gitattributes files to the leaf of a working tree and\nreleases unneeded data (IOW, it \"pops\" the attr_stack elements) when it\ngoes on to look at the next path, so my understanding is that there is\nnothing to \"try implementing\" here.\n\nUnless attr.c::free_attr_elem() is leaky, that is. If that were the case,\nsuch a leak will accumulate and would make a difference.\n"},{"id":"182330","messageId":"CALkWK0m+okqJk05BMQAEMww6FNLxaLVhAM92WmUDeA_J-drOdg@mail.gmail.com","threadId":"29328","inReplyTo":"7vipki7ix9.fsf@alter.siamese.dyndns.org","subject":"Re: leaky cherry-pick","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2012-01-11T09:00:16Z","receivedAt":"2012-01-11T09:00:16Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n> Ramkumar Ramachandra <artagnon@gmail.com> writes:\n>\n>>> If you then do a lookup for \"foo/bar/baz/file2\", it can use the exact\n>>> same stack without looking for or reparsing the attribute files. If you\n>>> then do a lookup for \"foo/bar/bleep/file\", it pops only the entry for\n>>> \"foo/bar/baz/.gitattributes\", and pushes only the entry for\n>>> \"foo/bar/bleep/.gitattributes\".\n>>\n>> I see.  Thanks for the excellent explanation-  I'll try implementing\n>> this scheme.\n>\n> I somehow have a feeling that you did not read the conclusion in Peff's\n> message correctly.  The code only keeps data from one active path of\n> per-directory .gitattributes files to the leaf of a working tree and\n> releases unneeded data (IOW, it \"pops\" the attr_stack elements) when it\n> goes on to look at the next path, so my understanding is that there is\n> nothing to \"try implementing\" here.\n\nMy bad-  I thought the current implementation doesn't release the\nunneeded data.  So, does the entire 7 KB of leaked data come from one\nactive path?\n\n-- Ram\n"},{"id":"182374","messageId":"20120111195605.GB12333@sigill.intra.peff.net","threadId":"29328","inReplyTo":"CALkWK0m+okqJk05BMQAEMww6FNLxaLVhAM92WmUDeA_J-drOdg@mail.gmail.com","subject":"Re: leaky cherry-pick","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-01-11T19:56:05Z","receivedAt":"2012-01-11T19:56:05Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jan 11, 2012 at 02:30:16PM +0530, Ramkumar Ramachandra wrote:\n\n> > I somehow have a feeling that you did not read the conclusion in Peff's\n> > message correctly.  The code only keeps data from one active path of\n> > per-directory .gitattributes files to the leaf of a working tree and\n> > releases unneeded data (IOW, it \"pops\" the attr_stack elements) when it\n> > goes on to look at the next path, so my understanding is that there is\n> > nothing to \"try implementing\" here.\n> \n> My bad-  I thought the current implementation doesn't release the\n> unneeded data.  So, does the entire 7 KB of leaked data come from one\n> active path?\n\nHmm. Actually, I think there is a leak. Because the strategy I described\nleaves the memory reachable from the global attr_stack variable, which\nmeans valgrind will only show it if \"--show-reachable\" is turned on.\n\nMaybe this?\n\ndiff --git a/attr.c b/attr.c\nindex 76b079f..1656db4 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -301,6 +301,7 @@ static void free_attr_elem(struct attr_stack *e)\n \t\t}\n \t\tfree(a);\n \t}\n+\tfree(e->attrs);\n \tfree(e);\n }\n \n\n-Peff\n"},{"id":"182394","messageId":"7v7h0x6b89.fsf@alter.siamese.dyndns.org","threadId":"29328","inReplyTo":"20120111195605.GB12333@sigill.intra.peff.net","subject":"Re: leaky cherry-pick","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-12T00:00:38Z","receivedAt":"2012-01-12T00:00:38Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> Maybe this?\n>\n> diff --git a/attr.c b/attr.c\n> index 76b079f..1656db4 100644\n> --- a/attr.c\n> +++ b/attr.c\n> @@ -301,6 +301,7 @@ static void free_attr_elem(struct attr_stack *e)\n>  \t\t}\n>  \t\tfree(a);\n>  \t}\n> +\tfree(e->attrs);\n>  \tfree(e);\n>  }\n\nYeah, that is definitely a leak.\n"},{"id":"182409","messageId":"20120112030503.GA26363@sigill.intra.peff.net","threadId":"29328","inReplyTo":"7v7h0x6b89.fsf@alter.siamese.dyndns.org","subject":"Re: leaky cherry-pick","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-01-12T03:05:03Z","receivedAt":"2012-01-12T03:05:03Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jan 11, 2012 at 04:00:38PM -0800, Junio C Hamano wrote:\n\n> Yeah, that is definitely a leak.\n\nHere it is with a commit message. \"valgrind git cherry-pick\" reports no\nleaks in the attr code after this (but unfortunately still lots of leaks\nfrom unpack-trees).\n\n-Peff\n\n-- >8 --\nSubject: [PATCH] attr: fix leak in free_attr_elem\n\nThis function frees the individual \"struct match_attr\"s we\nhave allocated, but forgot to free the array holding their\npointers, leading to a very minor memory leak.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n attr.c |    1 +\n 1 files changed, 1 insertions(+), 0 deletions(-)\n\ndiff --git a/attr.c b/attr.c\nindex 96eda0e..303751f 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -301,6 +301,7 @@ static void free_attr_elem(struct attr_stack *e)\n \t\t}\n \t\tfree(a);\n \t}\n+\tfree(e->attrs);\n \tfree(e);\n }\n \n-- \n1.7.9.rc0.33.gd3c17\n"}]}