{"thread":{"id":"42507","subject":"Segfault in the attr stack","startedAt":"2016-06-01T22:00:41Z","lastAt":"2016-06-02T16:56:42Z","messageCount":12,"participants":["Stefan Beller","Junio C Hamano","Duy Nguyen"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"288090","messageId":"CAGZ79ka_4vZfNhgOyMeFKdossO-S5Q7RVnvEzB8YAJNc1YQ+uQ@mail.gmail.com","threadId":"42507","inReplyTo":null,"subject":"Segfault in the attr stack","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-06-01T22:00:41Z","receivedAt":"2016-06-01T22:00:41Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"(running git-next)\n\nIn the Gerrit repo I did\n    $ echo \"/plugins/commit-message-length-validator sub-default\"\n>>.gitattributes\n    $ git status \":(attr:sub-default)\"\nSegmentation fault (core dumped)\n\nRunning this multiple times through gdb, this produces different back\ntraces as it seems that threads are involved? (So I don't attach a\nback trace here)\n\nAlso notable are:\n*** Error in `/usr/local/google/home/sbeller/bin/git': double free or\ncorruption (fasttop): 0x00007fffd80008f0 ***\n*** Error in `/usr/local/google/home/sbeller/bin/git': double free or\ncorruption (fasttop): 0x00007ffff0001000 ***\n\nWhen running another command `git status \":(attr:asdf)\"`, I get\ngit: attr.c:634: prepare_attr_stack: Assertion `attr_stack->origin' failed.\ngit: attr.c:634: prepare_attr_stack: Assertion `attr_stack->origin' failed.\ngit: attr.c:634: prepare_attr_stack: Assertion `attr_stack->origin' failed.\ngit: attr.c:634: prepare_attr_stack: Assertion `attr_stack->origin' failed.\nAborted (core dumped)\n\nThe failing assertions are an indication that sb/pathspec-label is\nusing the attrs incorrectly or\njc/attr added tighter assertions than I was aware of.\n\nStefan\n"},{"id":"288091","messageId":"xmqqpos0wodp.fsf@gitster.mtv.corp.google.com","threadId":"42507","inReplyTo":"CAGZ79ka_4vZfNhgOyMeFKdossO-S5Q7RVnvEzB8YAJNc1YQ+uQ@mail.gmail.com","subject":"Re: Segfault in the attr stack","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-06-01T22:11:30Z","receivedAt":"2016-06-01T22:11:30Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> In the Gerrit repo I did\n>     $ echo \"/plugins/commit-message-length-validator sub-default\"\n>>>.gitattributes\n>     $ git status \":(attr:sub-default)\"\n> Segmentation fault (core dumped)\n\nThanks.  I can reproduce this easily with git.git, e.g.\n\n\t$ cat >>.git/info/attributes <<-\\EOF\n\tDocumentation/git-merge.txt conflict-marker-size=32\n        Documentation/user-manual.txt conflict-marker-size=32\n\tEOF\n\t$ git status ':(attr:conflict-marker-size=32)'\n\nwould die (presumably) the same way.\n\nBy the way, I just noticed that the <specification> part of the\n':(attr:<specification>)' syntax would need to be rethought.  In the\n.gitattributes file everybody has, we see these lines:\n\n        *.[ch] whitespace=indent,trail,space\n        *.sh whitespace=indent,trail,space\n\nbut because comma is a special separator in the pathspec magic\nsystem, we cannot do\n\n\t$ git status ':(attr:whitespace=indent,trail,space)'\n\nI think we should introduce a quoting mechanism to hide these commas\nfrom the pathspec magic splitter, e.g.\n\nwhere attr_value_unquote() would copy string while unquoting some\nspecial characters (i.e. at least ' ' and ',' because they are used\nas syntactic elements in the higher level; there might be others).\n\ndiff --git a/pathspec.c b/pathspec.c\nindex 0a02255..fb22f28 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -132,7 +132,7 @@ static void parse_pathspec_attr_match(struct pathspec_item *item, const char *va\n \t\t\t\tam->match_mode = MATCH_SET;\n \t\t\telse {\n \t\t\t\tam->match_mode = MATCH_VALUE;\n-\t\t\t\tam->value = xstrdup(&attr[attr_len + 1]);\n+\t\t\t\tam->value = attr_value_unquote(&attr[attr_len + 1]);\n \t\t\t\tif (strchr(am->value, '\\\\'))\n \t\t\t\t\tdie(_(\"attr spec values must not contain backslashes\"));\n \t\t\t}\n"},{"id":"288092","messageId":"CAGZ79kbSKgS42nAShsK3JV78geam3k84=ipWRx7vbRODuHcmcA@mail.gmail.com","threadId":"42507","inReplyTo":"CAGZ79ka_4vZfNhgOyMeFKdossO-S5Q7RVnvEzB8YAJNc1YQ+uQ@mail.gmail.com","subject":"Re: Segfault in the attr stack","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-06-01T22:11:49Z","receivedAt":"2016-06-01T22:11:49Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"This can be reproduced on sb/pathspec-label in git.git as well.\n\nThe key difference I notice is `git ls-files` works perfectly (e.g. in\nthe tests)\nwhile `git status` fails.\n"},{"id":"288093","messageId":"CAPc5daXuQAeWvJAciRA_Kzyoxa=atEntGzKhqzjiN+ho6TnQyg@mail.gmail.com","threadId":"42507","inReplyTo":"CAGZ79kbSKgS42nAShsK3JV78geam3k84=ipWRx7vbRODuHcmcA@mail.gmail.com","subject":"Re: Segfault in the attr stack","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-06-01T22:17:24Z","receivedAt":"2016-06-01T22:17:24Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Gaah, of course.\n\nThis is coming from the cache preload codepath, where multiple threads\ntry to run ce_path_match().\nIt used to be OK because pathspec magic never looked at attributes,\nbut now it does, and attribute system is not thread-safe.\n\nOn Wed, Jun 1, 2016 at 3:11 PM, Stefan Beller <sbeller@google.com> wrote:\n> This can be reproduced on sb/pathspec-label in git.git as well.\n>\n> The key difference I notice is `git ls-files` works perfectly (e.g. in\n> the tests)\n> while `git status` fails.\n"},{"id":"288094","messageId":"CAGZ79kZ6dh7AP5b5N_2RRHQmq=OKpr05JEwyOCbfOj6KWjFC2A@mail.gmail.com","threadId":"42507","inReplyTo":"xmqqpos0wodp.fsf@gitster.mtv.corp.google.com","subject":"Re: Segfault in the attr stack","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-06-01T22:29:49Z","receivedAt":"2016-06-01T22:29:49Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Wed, Jun 1, 2016 at 3:11 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> By the way, I just noticed that the <specification> part of the\n> ':(attr:<specification>)' syntax would need to be rethought.  In the\n> .gitattributes file everybody has, we see these lines:\n>\n>         *.[ch] whitespace=indent,trail,space\n>         *.sh whitespace=indent,trail,space\n>\n> but because comma is a special separator in the pathspec magic\n> system, we cannot do\n>\n>         $ git status ':(attr:whitespace=indent,trail,space)'\n>\n\nRight. In [1] I wrote:\n\n>>\n>>> +     if (!item->attr_check)\n>>> +             item->attr_check = git_attr_check_alloc();\n>>\n>> Given more than one \"attr\" magic, e.g. \":(attr:A=a,attr:B)/path\",\n>> the check may not be empty when we process the second one; we just\n>> extend it without losing the existing contents.\n>\n> That is why I am not super happy with it though.\n>\n>    \":(attr:A=a,attr:B)/path\",\n>    \":(attr:A=a B)/path\",\n>\n> are the same for the user as well as in the internal data structures.\n> This \"wastes\" the white space as a possible convenient separator\n> character, e.g. for multiple values. On the other hand it will be easier\n> to type, specially for many attrs (read submodule groups).\n\nSo at that time I thought I had communicated the issue enough and we'd\nbe fine ignoring it for now. I propose to not escape commas, but use\nwhite spaces instead, i.e.\n\n    git status ':(attr:whitespace=indent trail space,attr:label=with\nmore values)' ':attr(attr:foo:bar)'\n\nwould match\n* all files that have the whitespace AND the label setting (matching\nexactly the values)\n* OR foo=bar attribute\n\nThis syntax would require to repeat \",attr:\" for multiple ANDed attributes,\nbut would save us from escaped commas, which may be a pain both in parsing as\nwell as doing the input on a shell?\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/294989/focus=295016\n\n> I think we should introduce a quoting mechanism to hide these commas\n> from the pathspec magic splitter, e.g.\n>\n> where attr_value_unquote() would copy string while unquoting some\n> special characters (i.e. at least ' ' and ',' because they are used\n> as syntactic elements in the higher level; there might be others).\n>\n> diff --git a/pathspec.c b/pathspec.c\n> index 0a02255..fb22f28 100644\n> --- a/pathspec.c\n> +++ b/pathspec.c\n> @@ -132,7 +132,7 @@ static void parse_pathspec_attr_match(struct pathspec_item *item, const char *va\n>                                 am->match_mode = MATCH_SET;\n>                         else {\n>                                 am->match_mode = MATCH_VALUE;\n> -                               am->value = xstrdup(&attr[attr_len + 1]);\n> +                               am->value = attr_value_unquote(&attr[attr_len + 1]);\n>                                 if (strchr(am->value, '\\\\'))\n>                                         die(_(\"attr spec values must not contain backslashes\"));\n>                         }\n>\n\nIf we go by whitespaces, we can implement attr_value_unquote as a `tr \" \" \",\"`\nconceptually, which seems easy.\n\nThanks,\nStefan\n"},{"id":"288095","messageId":"xmqqlh2ownab.fsf@gitster.mtv.corp.google.com","threadId":"42507","inReplyTo":"CAGZ79kZ6dh7AP5b5N_2RRHQmq=OKpr05JEwyOCbfOj6KWjFC2A@mail.gmail.com","subject":"Re: Segfault in the attr stack","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-06-01T22:35:08Z","receivedAt":"2016-06-01T22:35:08Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> I propose to not escape commas, but use\n> white spaces instead, i.e.\n>\n>     git status ':(attr:whitespace=indent trail space,attr:label=with\n> more values)' ':attr(attr:foo:bar)'\n>\n> would match\n> * all files that have the whitespace AND the label setting (matching\n> exactly the values)\n\n\"attr:whitespace=indent trail ..whatever other stuff..\" is already a\nnon-starter.  In the example in the message you are responding to, I\nwant to find paths whose \"whitespace\" attribute is set to the exact\nstring \"indent,trail,space\".  And I do not want the pathspec magic\ncode to know how the interpretation of \"whitespace\" attribute treats\ncomma in the string.  It may or may not have any special meaning, so\nif you meant \"whitespace=indent trail ..whatever other stuff..\"  to\nmean \"either whitespace is set to indent, or whitespace is set to\ntrail\", then that is already unacceptable.\n"},{"id":"288096","messageId":"xmqqh9dcwmrr.fsf@gitster.mtv.corp.google.com","threadId":"42507","inReplyTo":"CAPc5daXuQAeWvJAciRA_Kzyoxa=atEntGzKhqzjiN+ho6TnQyg@mail.gmail.com","subject":"Re: Segfault in the attr stack","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-06-01T22:46:16Z","receivedAt":"2016-06-01T22:46:16Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Gaah, of course.\n>\n> This is coming from the cache preload codepath, where multiple threads\n> try to run ce_path_match().\n> It used to be OK because pathspec magic never looked at attributes,\n> but now it does, and attribute system is not thread-safe.\n\nThe symlink check code has dealt with a similar issue in the past in\nthe codepath.  threaded_has_symlink_leading_path() is called with\nper-thread data structure called \"cache\", because the leading\nsymbolic link check uses a cache that is shared across different\ninvocations of the check.\n\nWe need something similar to duplicate the attribute stack per\nthread.  git_check_attrs() currently uses the singleton instance of\nattr_stack chain, that is rooted at the file scope global\n\"attr_stack\", and no wonder that would be clobbered when multiple\nthreads try to use it.  The result of attribute collection is also\naccumulated in a file scope global, which should probably be moved\nto the \"struct git_attr_check\" introduced in the jc/attr topic.\n\nWe need to teach the callchain that includes prepare_attr_stack()\nand bootstrap_attr_stack() to take a pointer to the attr_stack root,\ngive git_check_attr_threaded() that takes such root so that threaded\ncode can use per-thread attr stack, and for non-threaded\napplications use &the_default_attr just like the file scope global\n\"default_cache\" is used in symlinks.c.  Then a threaded attribute\nlookup can maintain its own attr_stack when running more than one\ninstance of lookup.\n"},{"id":"288100","messageId":"xmqq8tyowias.fsf@gitster.mtv.corp.google.com","threadId":"42507","inReplyTo":"xmqqh9dcwmrr.fsf@gitster.mtv.corp.google.com","subject":"Re: Segfault in the attr stack","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-06-02T00:22:51Z","receivedAt":"2016-06-02T00:22:51Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Gaah, of course.\n>>\n>> This is coming from the cache preload codepath, where multiple threads\n>> try to run ce_path_match().\n>> It used to be OK because pathspec magic never looked at attributes,\n>> but now it does, and attribute system is not thread-safe.\n>\n> The symlink check code has dealt with a similar issue in the past in\n> the codepath.  threaded_has_symlink_leading_path() is called with\n> per-thread data structure called \"cache\", because the leading\n> symbolic link check uses a cache that is shared across different\n> invocations of the check.\n>\n> We need something similar to duplicate the attribute stack per\n> thread.  git_check_attrs() currently uses the singleton instance of\n> attr_stack chain, that is rooted at the file scope global\n> \"attr_stack\", and no wonder that would be clobbered when multiple\n> threads try to use it.  The result of attribute collection is also\n> accumulated in a file scope global, which should probably be moved\n> to the \"struct git_attr_check\" introduced in the jc/attr topic.\n>\n> We need to teach the callchain that includes prepare_attr_stack()\n> and bootstrap_attr_stack() to take a pointer to the attr_stack root,\n> give git_check_attr_threaded() that takes such root so that threaded\n> code can use per-thread attr stack, and for non-threaded\n> applications use &the_default_attr just like the file scope global\n> \"default_cache\" is used in symlinks.c.  Then a threaded attribute\n> lookup can maintain its own attr_stack when running more than one\n> instance of lookup.\n\nAnother is the global attr dictionary.  It is like the global object\nhash, so the look-up and insertion into it need to be protected the\nsame way with mutex, just like builtin/pack-objects.c serializes the\nobject store access with locks.\n"},{"id":"288103","messageId":"CACsJy8A4gXRyx4LpBmM2Y=n2KB0NurKMiW42-tPnU7K89qj5bw@mail.gmail.com","threadId":"42507","inReplyTo":"CAPc5daXuQAeWvJAciRA_Kzyoxa=atEntGzKhqzjiN+ho6TnQyg@mail.gmail.com","subject":"Re: Segfault in the attr stack","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-06-02T01:02:48Z","receivedAt":"2016-06-02T01:02:48Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Jun 2, 2016 at 5:17 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Gaah, of course.\n>\n> This is coming from the cache preload codepath, where multiple threads\n> try to run ce_path_match().\n> It used to be OK because pathspec magic never looked at attributes,\n> but now it does, and attribute system is not thread-safe.\n\nOff topic. I wonder if we can annotate which functions are thread-safe\n(minority currently in git code base, I believe) and make gcc, clang\nor sparse spot them in threaded code?\n-- \nDuy\n"},{"id":"288104","messageId":"CACsJy8CCo1UC8KZNdap8K6_z1_kXOQ0qxhDEZusG62cAt4x_bQ@mail.gmail.com","threadId":"42507","inReplyTo":"CACsJy8A4gXRyx4LpBmM2Y=n2KB0NurKMiW42-tPnU7K89qj5bw@mail.gmail.com","subject":"Re: Segfault in the attr stack","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-06-02T01:04:25Z","receivedAt":"2016-06-02T01:04:25Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Jun 2, 2016 at 8:02 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Thu, Jun 2, 2016 at 5:17 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Gaah, of course.\n>>\n>> This is coming from the cache preload codepath, where multiple threads\n>> try to run ce_path_match().\n>> It used to be OK because pathspec magic never looked at attributes,\n>> but now it does, and attribute system is not thread-safe.\n>\n> Off topic. I wonder if we can annotate which functions are thread-safe\n> (minority currently in git code base, I believe) and make gcc, clang\n> or sparse spot them in threaded code?\n\nBy them I mean unannotated (i.e. not thread-safe) functions, of course.\n-- \nDuy\n"},{"id":"288131","messageId":"xmqqshwvvaxq.fsf@gitster.mtv.corp.google.com","threadId":"42507","inReplyTo":"xmqq8tyowias.fsf@gitster.mtv.corp.google.com","subject":"Re: Segfault in the attr stack","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-06-02T15:59:29Z","receivedAt":"2016-06-02T15:59:29Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>>> Gaah, of course.\n>>>\n>>> This is coming from the cache preload codepath, where multiple threads\n>>> try to run ce_path_match().\n>>> It used to be OK because pathspec magic never looked at attributes,\n>>> but now it does, and attribute system is not thread-safe.\n\nI'll look into teaching a threadble interface to the attribute\nsubsystem, but for now, this should get you unstuck, I think.\n\nOne of the ways preload codepath assures that multiple threads do\nnot stomp on the shared datastructure is by copying things that are\ninvolved in the operation, and there is copy_pathspec() call.  I\nthink the \"pathspec magic that limits with the attributes\" topic,\nwhich adds to the pathspec structure, needs to update the function\nso that its shared data structure is properly copied.  Before the\nseries, I think the pathspec structure only has either pointers to\nborrowed strings (e.g. raw) or scalars, and it was sufficient to do\na shallow copy with memcpy().  With the change, that is no longer\nthe case.\n\nWhich would mean we'd need to make sure that any codepath that calls\ncopy_pathspec() needs to think about how to clean it up.  Before the\nchange, preload-index codepath didn't have to, but with the change,\nit will.  We'd need pathspec_clear() or something like that.\n\n pathspec.c      | 12 ++++++++++++\n pathspec.h      |  2 ++\n preload-index.c |  4 ++++\n 3 files changed, 18 insertions(+)\n\ndiff --git a/pathspec.c b/pathspec.c\nindex 0a02255..326863a 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -208,6 +208,18 @@ static void eat_long_magic(struct pathspec_item *item, const char *elt,\n \t*copyfrom_ = copyfrom;\n }\n \n+int pathspec_is_non_threadable(const struct pathspec *pathspec)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < pathspec->nr; i++) {\n+\t\tconst struct pathspec_item *item = &pathspec->items[i];\n+\t\tif (item->attr_check)\n+\t\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n /*\n  * Take an element of a pathspec and check for magic signatures.\n  * Append the result to the prefix. Return the magic bitmap.\ndiff --git a/pathspec.h b/pathspec.h\nindex 5308137..07d21f0 100644\n--- a/pathspec.h\n+++ b/pathspec.h\n@@ -115,4 +115,6 @@ extern void add_pathspec_matches_against_index(const struct pathspec *pathspec,\n extern const char *check_path_for_gitlink(const char *path);\n extern void die_if_path_beyond_symlink(const char *path, const char *prefix);\n \n+extern int pathspec_is_non_threadable(const struct pathspec *);\n+\n #endif /* PATHSPEC_H */\ndiff --git a/preload-index.c b/preload-index.c\nindex c1fe3a3..af46878 100644\n--- a/preload-index.c\n+++ b/preload-index.c\n@@ -76,6 +76,10 @@ static void preload_index(struct index_state *index,\n \tif (!core_preload_index)\n \t\treturn;\n \n+\t/* Do not preload when pathspec uses non-threadable subsystems */\n+\tif (pathspec && pathspec_is_non_threadable(pathspec))\n+\t\treturn; /* for now ... */\n+\n \tthreads = index->cache_nr / THREAD_COST;\n \tif (threads < 2)\n \t\treturn;\n"},{"id":"288136","messageId":"CAGZ79ka7sXKwOdY4_WK15c3HHOp2pRtcUgeZ6rDAt8hSvcx1=Q@mail.gmail.com","threadId":"42507","inReplyTo":"xmqqshwvvaxq.fsf@gitster.mtv.corp.google.com","subject":"Re: Segfault in the attr stack","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-06-02T16:56:42Z","receivedAt":"2016-06-02T16:56:42Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Thu, Jun 2, 2016 at 8:59 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>>>> Gaah, of course.\n>>>>\n>>>> This is coming from the cache preload codepath, where multiple threads\n>>>> try to run ce_path_match().\n>>>> It used to be OK because pathspec magic never looked at attributes,\n>>>> but now it does, and attribute system is not thread-safe.\n>\n> I'll look into teaching a threadble interface to the attribute\n> subsystem, but for now, this should get you unstuck, I think.\n\nThanks for looking into this!\n(I was about to do that if you would not have stepped up, as the bug\nonly surfaces when using the pathspec labels.)\n\n>\n> +       /* Do not preload when pathspec uses non-threadable subsystems */\n> +       if (pathspec && pathspec_is_non_threadable(pathspec))\n> +               return; /* for now ... */\n\nThis fixes the problem for now; I'll look into the comma escaping then.\n\nThanks,\nStefan\n"}]}