{"thread":{"id":"59092","subject":"Segmentation fault within git read-tree","startedAt":"2023-01-14T22:15:02Z","lastAt":"2023-01-15T21:49:15Z","messageCount":4,"participants":["Frédéric Fort","Christian Couder","Jeff King","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"470365","messageId":"d0f9520d-9ccc-a899-609e-fbbb4529e005@free.fr","threadId":"59092","inReplyTo":null,"subject":"Segmentation fault within git read-tree","fromName":"Frédéric Fort","fromEmail":"fortfrederic@free.fr","sentAt":"2023-01-14T22:14:51Z","receivedAt":"2023-01-14T22:15:02Z","isPatch":false,"sender":{"key":"fortfrederic@free.fr","avatar":null},"body":"Hello,\n\nI am doing some tests trying to do a sparse checkout of a partial clone \nwithin a subtree.\nHowever, I get a segfault when trying to run git read-tree as is done by \ngit subtree internally.\n\nMaybe what I am doing isn't supposed to work at all, but I suppose it \nshouldn't at least cause git read-tree to segfault.\n\nHere should be a MWE to reproduce my error:\n\n# Run this to create the repo that will become your subtree\ngit init subtree.git\ncd subtree.git\ntouch x y\ngit add .\ngit commit -m \"first commit\"\n\n# Run this to create the repo that has a sparse checkout of a partial \nclone within a subtree\ngit init repo\ncd repo\ngit commit --allow-empty \"first commit\"\ngit sparse-checkout set \"subtree/x\"\ngit remote add origin-subtree git@my.server:/with/the/subtree.git\ngit fetch --filter=blob:none origin-subtree\ngit rev-parse --verify \"FETCH_HEAD^{commit}\"\ngit read-tree --debug-unpack --prefix=\"subtree\" FETCH_HEAD\n\nYours sincerely,\nFrédéric Fort\n\n"},{"id":"470384","messageId":"CAP8UFD0pKZT57jpUOg7gckcr4stoq24YDB2Fu0-AwbGPrEweqg@mail.gmail.com","threadId":"59092","inReplyTo":"d0f9520d-9ccc-a899-609e-fbbb4529e005@free.fr","subject":"Re: Segmentation fault within git read-tree","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2023-01-15T11:53:25Z","receivedAt":"2023-01-15T11:53:42Z","isPatch":false,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Hi,\n\nOn Sat, Jan 14, 2023 at 11:22 PM Frédéric Fort <fortfrederic@free.fr> wrote:\n>\n> Hello,\n>\n> I am doing some tests trying to do a sparse checkout of a partial clone\n> within a subtree.\n> However, I get a segfault when trying to run git read-tree as is done by\n> git subtree internally.\n>\n> Maybe what I am doing isn't supposed to work at all, but I suppose it\n> shouldn't at least cause git read-tree to segfault.\n\nYeah, it shouldn't segfault. Thanks for the report!\n\n> Here should be a MWE to reproduce my error:\n\nI reproduced the issue using your steps with a few changes.\n\n> # Run this to create the repo that will become your subtree\n> git init subtree.git\n> cd subtree.git\n> touch x y\n> git add .\n> git commit -m \"first commit\"\n>\n> # Run this to create the repo that has a sparse checkout of a partial\n> clone within a subtree\n> git init repo\n> cd repo\n> git commit --allow-empty \"first commit\"\n\nI think the above command is missing '-m' before \"first commit\".\n\n> git sparse-checkout set \"subtree/x\"\n> git remote add origin-subtree git@my.server:/with/the/subtree.git\n\nI reproduced using a local remote like:\n\ngit remote add origin-subtree /path/to/subtree.git\n\n> git fetch --filter=blob:none origin-subtree\n> git rev-parse --verify \"FETCH_HEAD^{commit}\"\n> git read-tree --debug-unpack --prefix=\"subtree\" FETCH_HEAD\n\nYeah, I get the following under gdb:\n\nProgram received signal SIGSEGV, Segmentation fault.\ndebug_path (info=0x7fffffffc880) at unpack-trees.c:1395\n1395                    if (*info->prev->name)\n(gdb) bt\n#0  debug_path (info=0x7fffffffc880) at unpack-trees.c:1395\n#1  0x000055555587d917 in debug_unpack_callback (n=1, mask=1,\ndirmask=0, names=0x7fffffffc3b0, info=0x7fffffffc880) at\nunpack-trees.c:1417\n#2  0x000055555587dc48 in unpack_callback (n=1, mask=1, dirmask=0,\nnames=0x7fffffffc3b0, info=0x7fffffffc880) at unpack-trees.c:1491\n#3  0x00005555558779c2 in traverse_trees (istate=0x5555559f3b00\n<the_index>, n=1, t=0x7fffffffcb50, info=0x7fffffffc880) at\ntree-walk.c:536\n#4  0x000055555587ef85 in unpack_trees (len=1, t=0x7fffffffcb50,\no=0x7fffffffcd90) at unpack-trees.c:1979\n#5  0x000055555562ab45 in cmd_read_tree (argc=1, argv=0x7fffffffdc90,\ncmd_prefix=0x0) at builtin/read-tree.c:263\n#6  0x0000555555575a4d in run_builtin (p=0x5555559bf8f0\n<commands+2256>, argc=4, argv=0x7fffffffdc90) at git.c:445\n#7  0x0000555555575ed2 in handle_builtin (argc=4, argv=0x7fffffffdc90)\nat git.c:700\n#8  0x0000555555576179 in run_argv (argcp=0x7fffffffdaec,\nargv=0x7fffffffdae0) at git.c:764\n#9  0x0000555555576764 in cmd_main (argc=4, argv=0x7fffffffdc90) at git.c:899\n#10 0x0000555555682dfe in main (argc=5, argv=0x7fffffffdc88) at common-main.c:57\n\nFrom a very quick look, it seems that in setup_traverse_info() in\ntree-walk.c we do:\n\n    static struct traverse_info dummy;\n...\n    if (pathlen)\n        info->prev = &dummy;\n\nbut then later in debug_path() in unpack-trees.c we check\n*info->prev->name which segfaults.\n\nI am not very familiar with this code and don't have much time right\nnow, so I think I will leave it to others to investigate this further.\n\nBest,\nChristian.\n"},{"id":"470387","messageId":"Y8RHfjFFLRdW3WRh@coredump.intra.peff.net","threadId":"59092","inReplyTo":"CAP8UFD0pKZT57jpUOg7gckcr4stoq24YDB2Fu0-AwbGPrEweqg@mail.gmail.com","subject":"Re: Segmentation fault within git read-tree","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2023-01-15T18:35:42Z","receivedAt":"2023-01-15T18:35:48Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Jan 15, 2023 at 12:53:25PM +0100, Christian Couder wrote:\n\n> From a very quick look, it seems that in setup_traverse_info() in\n> tree-walk.c we do:\n> \n>     static struct traverse_info dummy;\n> ...\n>     if (pathlen)\n>         info->prev = &dummy;\n> \n> but then later in debug_path() in unpack-trees.c we check\n> *info->prev->name which segfaults.\n> \n> I am not very familiar with this code and don't have much time right\n> now, so I think I will leave it to others to investigate this further.\n\nI'm not sure if Frédéric is seeing another segfault in practice (when\nnot using --debug-unpack), but yeah, it is very easy to trigger this\nsegfault. It does not even have to do with sparse checkouts, etc. Here's\nan even more minimal example:\n\n  git init repo\n  cd repo\n  touch file\n  git add file\n  git commit -m added\n  git read-tree --debug-unpack --prefix=subtree HEAD\n\nI was going to bisect, but it looks like it was broken all the way back\nto Junio's ba655da537 (read-tree --debug-unpack, 2009-09-14).\n\n-Peff\n"},{"id":"470402","messageId":"xmqqedrvfoyz.fsf@gitster.g","threadId":"59092","inReplyTo":"Y8RHfjFFLRdW3WRh@coredump.intra.peff.net","subject":"Re: Segmentation fault within git read-tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-01-15T21:49:08Z","receivedAt":"2023-01-15T21:49:15Z","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> I'm not sure if Frédéric is seeing another segfault in practice (when\n> not using --debug-unpack), but yeah, it is very easy to trigger this\n> segfault. It does not even have to do with sparse checkouts, etc. Here's\n> an even more minimal example:\n>\n>   git init repo\n>   cd repo\n>   touch file\n>   git add file\n>   git commit -m added\n>   git read-tree --debug-unpack --prefix=subtree HEAD\n>\n> I was going to bisect, but it looks like it was broken all the way back\n> to Junio's ba655da537 (read-tree --debug-unpack, 2009-09-14).\n\nAs \"git read-tree --help\" does not even metnion \"--debug-unpack\", I\nhave no idea what it does, or how useful the debug information it\nproduces is.  As long as the same command without --debug-unpack\nworks OK, I'd throw this into \"does it hurt? don't do it, then\" bin.\n\n;-)\n"}]}