"git branch HEAD" dumps core when on detached head (NULL pointer dereference)
Running "git branch HEAD" may be a stupid thing to do. It actually was a mistake on my part. Still, I don't think git should dereference a NULL pointer.
Tested using git 1.8.1.4 adn 1.8.1.1.
Repeat by:
mkdir branchcrash || exit 1
cd branchcrash
git init
touch a; git add a; git commit -m"Added a".
touch b; git add b; git commit -m"Added b".
git checkout HEAD^
git branch HEAD
The last command dumps core. gdb session:
gdb /usr/local/bin/git core
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04 Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /usr/local/bin/git...done.
[New LWP 7174]
warning: Can't read pathname for load map: Input/output error. [Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Core was generated by `git branch HEAD'.
Program terminated with signal 11, Segmentation fault.
#0 cmd_branch (argc=1, argv=0x7fffe6e2a0f0, prefix=<optimized out>)
at builtin/branch.c:919
919 strbuf_addf(&buf, "refs/remotes/%s", branch->name);
(gdb) bt
#0 cmd_branch (argc=1, argv=0x7fffe6e2a0f0, prefix=<optimized out>)
at builtin/branch.c:919
#1 0x00000000004046ac in run_builtin (argv=0x7fffe6e2a0f0, argc=2,
p=<optimized out>) at git.c:273
#2 handle_internal_command (argc=2, argv=0x7fffe6e2a0f0) at git.c:434
#3 0x0000000000404df3 in run_argv (argv=0x7fffe6e29f90, argcp=0x7fffe6e29f9c)
at git.c:480#4 main (argc=2, argv=0x7fffe6e2a0f0) at git.c:555 (gdb) p branch
$1 = (struct branch *) 0x0
(gdb) quit
/ceder
PATCH 1/1 branch: segfault fixes and validation
branch_get() can return NULL (so far on detached HEAD only) but some code paths in builtin/branch.c cannot deal with that and cause segfaults. Fix it.
While at there, make sure to bail out when the user gives 2 or more arguments, but only the first one is processed.
--- builtin/branch.c | 20 ++++++++++++++++++++ t/t3200-branch.sh | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+)
builtin/branch.c +20 -0
@@ -889,6 +889,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix) }else if (new_upstream) {struct branch *branch =branch_get (argv[0 ]); +if (argc >1 ) +die (_ ("too many branches to set new upstream" )); + +if (!branch) +die (_ ("could not figure out the branch name from '%s'" ), + argc ==1 ? argv[0 ] :"HEAD" ); +if (!ref_exists (branch->refname))die (_ ("branch '%s' does not exist" ), branch->name);
@@ -901,6 +908,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)struct branch *branch =branch_get (argv[0 ]);struct strbuf buf =STRBUF_INIT ; +if (argc >1 ) +die (_ ("too many branches to unset upstream" )); + +if (!branch) +die (_ ("could not figure out the branch name from '%s'" ), + argc ==1 ? argv[0 ] :"HEAD" ); +if (!branch_has_merge_config (branch)) {die (_ ("Branch '%s' has no upstream information" ), branch->name); }
@@ -916,6 +930,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)int branch_existed =0 , remote_tracking =0 ;struct strbuf buf =STRBUF_INIT ; +if (!strcmp (argv[0 ],"HEAD" )) +die (_ ("it does not make sense to create 'HEAD' manually" )); + +if (!branch) +die (_ ("could not figure out the branch name from '%s'" ), argv[0 ]); +if (kinds !=REF_LOCAL_BRANCH )die (_ ("-a and -r options to 'git branch' do not make sense with a branch name" ));
t/t3200-branch.sh +21 -0
@@ -42,6 +42,10 @@ test_expect_success \ 'git branch a/b/c should create a branch' \ 'git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c' +test_expect_success \ + 'git branch HEAD should fail' \ + 'test_must_fail git branch HEAD' + cat >expect <<EOF $_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master EOF
@@ -388,6 +392,14 @@ test_expect_success \ 'git tag foobar && test_must_fail git branch --track my11 foobar' +test_expect_success '--set-upstream-to fails on multiple branches' \ + 'test_must_fail git branch --set-upstream-to master a b c' + +test_expect_success '--set-upstream-to fails on detached HEAD' \ + 'git checkout HEAD^{} && + test_must_fail git branch --set-upstream-to master && + git checkout -' + test_expect_success 'use --set-upstream-to modify HEAD' \ 'test_config branch.master.remote foo && test_config branch.master.merge foo &&
@@ -417,6 +429,15 @@ test_expect_success 'test --unset-upstream on HEAD' \ test_must_fail git branch --unset-upstream ' +test_expect_success '--unset-upstream should fail on multiple branches' \ + 'test_must_fail git branch --unset-upstream a b c' + +test_expect_success '--unset-upstream should fail on detached HEAD' \ + 'git checkout HEAD^{} && + test_must_fail git branch --unset-upstream && + git checkout - +' + test_expect_success 'test --unset-upstream on a particular branch' \ 'git branch my15 git branch --set-upstream-to master my14 &&
Signature · 1 line
1.8.1.2.536.gf441e6d
Re: [PATCH] branch: segfault fixes and validation
Quoted 1 line · Nguyễn Thái Ngọc Duy
branch_get()can return NULL (so far on detached HEAD only)...
Do you anticipate any other cases where the API call should validly return NULL? I offhand do not, ...
Quoted 19 lines
but some
code paths inbuiltin/branch.ccannot deal with that and cause segfaults. Fix it.While at there, make sure to bail out when the user gives 2 or more arguments, but only the first one is processed.
Reported-by Per Cederqvist <[email protected]>Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- builtin/branch.c | 20 ++++++++++++++++++++ t/t3200-branch.sh | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+)builtin/branch.c +0
-0
builtin/branch.c int cmd_branch(int argc, const char **argv, const char *prefix) · line 897
Quoted 9 lines
builtin/branch.c +6
-0@@ -889,6 +889,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix) }else if (new_upstream) {struct branch *branch =branch_get (argv[0 ]); +if (argc >1 ) +die (_ ("too many branches to set new upstream" )); + +if (!branch) +die (_ ("could not figure out the branch name from '%s'" ), + argc ==1 ? argv[0 ] :"HEAD" );
... and find this "could not figure out" very unfriendly to the user. Is it a bug in the implementation, silly Git failing to find what branch the user meant? What recourse does the user have at this point?
Or is it a user error to ask Git to operate on the branch pointed at by HEAD, when HEAD does not refer to any branch? If that is the case, then the message should say that there is no current branch to operate on because the user is on a detached HEAD. That would point the user in the right direction to correct the user error, no?
Of course, argv[0] may not be HEAD and in that case you may have to say "no such branch %s" % argv[0] or something. The point is that "could not figure out" feels a bit too lazy.
builtin/branch.c int cmd_branch(int argc, const char **argv, const char *prefix) · line 916
Quoted 10 lines
builtin/branch.c +6
-0@@ -901,6 +908,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)struct branch *branch =branch_get (argv[0 ]);struct strbuf buf =STRBUF_INIT ; +if (argc >1 ) +die (_ ("too many branches to unset upstream" )); + +if (!branch) +die (_ ("could not figure out the branch name from '%s'" ), + argc ==1 ? argv[0 ] :"HEAD" );
Likewise.
builtin/branch.c int cmd_branch(int argc, const char **argv, const char *prefix) · line 937
Quoted 9 lines
builtin/branch.c +5
-0@@ -916,6 +930,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)int branch_existed =0 , remote_tracking =0 ;struct strbuf buf =STRBUF_INIT ; +if (!strcmp (argv[0 ],"HEAD" )) +die (_ ("it does not make sense to create 'HEAD' manually" )); + +if (!branch) +die (_ ("could not figure out the branch name from '%s'" ), argv[0 ]);
Likewise.
Thanks.
PATCH v2 1/1 branch: segfault fixes and validation
branch_get() can return NULL (so far on detached HEAD only) but some code paths in builtin/branch.c cannot deal with that and cause segfaults. While at there, make sure we bail out when the user gives 2 or more arguments, but we only process the first one and silently ignore the rest.
---
Quoted 6 lines · Junio C Hamano
Quoted 1 line · Nguyễn Thái Ngọc Duy
branch_get()can return NULL (so far on detached HEAD only)...Do you anticipate any other cases where the API call should validly return NULL?
No. But I do not see any guarantee that it may never do that in future either. Which is why I was deliberately vague with "could not figure out...". But you also correctly observed my laziness there. So how about this? It makes a special case for HEAD but not insist on detached HEAD as the only cause.
builtin/branch.c | 24 ++++++++++++++++++++++++ t/t3200-branch.sh | 21 +++++++++++++++++++++ 2 files changed, 45 insertions(+)
builtin/branch.c +24 -0
@@ -889,6 +889,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix) }else if (new_upstream) {struct branch *branch =branch_get (argv[0 ]); +if (argc >1 ) +die (_ ("too many branches to set new upstream" )); + +if (!branch) { +if (!argc || !strcmp (argv[0 ],"HEAD" )) +die (_ ("HEAD does not point to any branch. Is it detached?" )); +die (_ ("no such branch '%s'" ), argv[0 ]); + } +if (!ref_exists (branch->refname))die (_ ("branch '%s' does not exist" ), branch->name);
@@ -901,6 +910,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix)struct branch *branch =branch_get (argv[0 ]);struct strbuf buf =STRBUF_INIT ; +if (argc >1 ) +die (_ ("too many branches to unset upstream" )); + +if (!branch) { +if (!argc || !strcmp (argv[0 ],"HEAD" )) +die (_ ("HEAD does not point to any branch. Is it detached?" )); +die (_ ("no such branch '%s'" ), argv[0 ]); + } +if (!branch_has_merge_config (branch)) {die (_ ("Branch '%s' has no upstream information" ), branch->name); }
@@ -916,6 +934,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)int branch_existed =0 , remote_tracking =0 ;struct strbuf buf =STRBUF_INIT ; +if (!strcmp (argv[0 ],"HEAD" )) +die (_ ("it does not make sense to create 'HEAD' manually" )); + +if (!branch) +die (_ ("no such branch '%s'" ), argv[0 ]); +if (kinds !=REF_LOCAL_BRANCH )die (_ ("-a and -r options to 'git branch' do not make sense with a branch name" ));
t/t3200-branch.sh +21 -0
@@ -42,6 +42,10 @@ test_expect_success \ 'git branch a/b/c should create a branch' \ 'git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c' +test_expect_success \ + 'git branch HEAD should fail' \ + 'test_must_fail git branch HEAD' + cat >expect <<EOF $_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master EOF
@@ -388,6 +392,14 @@ test_expect_success \ 'git tag foobar && test_must_fail git branch --track my11 foobar' +test_expect_success '--set-upstream-to fails on multiple branches' \ + 'test_must_fail git branch --set-upstream-to master a b c' + +test_expect_success '--set-upstream-to fails on detached HEAD' \ + 'git checkout HEAD^{} && + test_must_fail git branch --set-upstream-to master && + git checkout -' + test_expect_success 'use --set-upstream-to modify HEAD' \ 'test_config branch.master.remote foo && test_config branch.master.merge foo &&
@@ -417,6 +429,15 @@ test_expect_success 'test --unset-upstream on HEAD' \ test_must_fail git branch --unset-upstream ' +test_expect_success '--unset-upstream should fail on multiple branches' \ + 'test_must_fail git branch --unset-upstream a b c' + +test_expect_success '--unset-upstream should fail on detached HEAD' \ + 'git checkout HEAD^{} && + test_must_fail git branch --unset-upstream && + git checkout - +' + test_expect_success 'test --unset-upstream on a particular branch' \ 'git branch my15 git branch --set-upstream-to master my14 &&
Signature · 1 line
1.8.1.2.536.gf441e6d
Re: [PATCH v2] branch: segfault fixes and validation
Quoted 5 lines · Nguyễn Thái Ngọc Duy
branch_get()can return NULL (so far on detached HEAD only) but some code paths inbuiltin/branch.ccannot deal with that and cause segfaults. While at there, make sure we bail out when the user gives 2 or more arguments, but we only process the first one and silently ignore the rest.
Explain "2 or more arguments" in what context, perhaps? Otherwise it makes it sound as if "git branch foo bar baz" is covered with this patch, no?
Quoted 7 lines
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
Quoted 4 lines · Junio C Hamano
Quoted 1 line · Nguyễn Thái Ngọc Duy
branch_get()can return NULL (so far on detached HEAD only)...
Quoted 8 lines
Quoted 2 lines
Do you anticipate any other cases where the API call should validly return NULL?
No. But I do not see any guarantee that it may never do that in future either. Which is why I was deliberately vague with "could not figure out...". But you also correctly observed my laziness there. So how about this? It makes a special case for HEAD but not insist on detached HEAD as the only cause.
Sure. It looks better.
What you can do is to have a single helper function that can explain why branch_get() returned NULL (or extend branch_get() to serve that purpose as well); then you do not have to duplicate the logic twice on the caller's side (and there may be other callers that want to do the same).
Quoted 9 lines
builtin/branch.c +1
-0@@ -889,6 +889,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix) }else if (new_upstream) {struct branch *branch =branch_get (argv[0 ]); +if (argc >1 )
builtin/branch.c int cmd_branch(int argc, const char **argv, const char *prefix) · line 902
Quoted 10 lines
builtin/branch.c +8
-0+die (_ ("too many branches to set new upstream" )); + +if (!branch) { +if (!argc || !strcmp (argv[0 ],"HEAD" )) +die (_ ("HEAD does not point to any branch. Is it detached?" )); +die (_ ("no such branch '%s'" ), argv[0 ]); + } +if (!ref_exists (branch->refname))die (_ ("branch '%s' does not exist" ), branch->name);
The latter part of the new code triggers when branch_get() returns NULL while doing "git branch --set-upstream-to=X [Y]". When "Y" is string "HEAD" or missing, the first die() is triggered and says a funny thing. If HEAD does not point to any branch, by definition it is detached. The user may say "Yes, I know it is detached." but the message does not help the user to figure out what to do next.
Instead of asking "Is it detached?", perhaps we can say something like "You told me to set the upstream of HEAD to branch X, but " in front? At least, that will be a better explanation for the reason why the operation is failing.
The existing test might be wrong, by the way. Your HEAD may point at a branch Y but you may not have any commit on it yet, and you may want to allow setting the upstream of that to-be-born branch to another branch X with "branch --set-upstream-to=X [Y|HEAD]".
While I think it is insane to do anything before creating the first commit on your current branch (or using "checkout --orphan" in general) and it may not be worth our time to babysit users who do so, but the following sequence may feel natural to them:
git checkout --orphan X
git branch --set-upstream-to=master
... perhaps create an initial commit, perhaps not ...
git merge @{upstream}For that to work sanely, perhaps the pattern
branch = branch_get();
if (!branch)
die due to no branch;
if (!ref_exists(branch->refname))
die due to typo in branch namemay need to be fixed globally, replacing ref_exists(branch->refname) with branch_exists(branch) that returns true if branch->refname is an existing ref, or the branch in question was obtained by checking with current_branch (in remote.c), or something like that.
PATCH v3 1/1 branch: segfault fixes and validation
branch_get() can return NULL (so far on detached HEAD only) but some code paths in builtin/branch.c cannot deal with that and cause segfaults.
While at there, make sure to bail out when the user gives 2 or more branches with --set-upstream-to or --unset-upstream, where only the first branch is processed and the rest silently dropped.
---
Quoted 4 lines · Junio C Hamano
Instead of asking "Is it detached?", perhaps we can say something like "You told me to set the upstream of HEAD to branch X, but " in front? At least, that will be a better explanation for the reason why the operation is failing.
Fixed.
Quoted 5 lines
What you can do is to have a single helper function that can explain why
branch_get()returned NULL (or extendbranch_get()to serve that purpose as well); then you do not have to duplicate the logic twice on the caller's side (and there may be other callers that want to do the same).
The explanation mentions about the failed operation, which makes a helper less useful. We could still do the helper, but it may lead to i18n legos. So no helper in this version.
Quoted 4 lines
The existing test might be wrong, by the way. Your HEAD may point at a branch Y but you may not have any commit on it yet, and you may want to allow setting the upstream of that to-be-born branch to another branch X with "branch --set-upstream-to=X [Y|HEAD]".
It sounds complicated. I think we can revisit it when a user actually complains about it.
builtin/branch.c | 27 +++++++++++++++++++++++++++ t/t3200-branch.sh | 21 +++++++++++++++++++++ 2 files changed, 48 insertions(+)
builtin/branch.c +27 -0
@@ -889,6 +889,17 @@ int cmd_branch(int argc, const char **argv, const char *prefix) }else if (new_upstream) {struct branch *branch =branch_get (argv[0 ]); +if (argc >1 ) +die (_ ("too many branches to set new upstream" )); + +if (!branch) { +if (!argc || !strcmp (argv[0 ],"HEAD" )) +die (_ ("could not set upstream of HEAD to %s when " +"it does not point to any branch." ), + new_upstream); +die (_ ("no such branch '%s'" ), argv[0 ]); + } +if (!ref_exists (branch->refname))die (_ ("branch '%s' does not exist" ), branch->name);
@@ -901,6 +912,16 @@ int cmd_branch(int argc, const char **argv, const char *prefix)struct branch *branch =branch_get (argv[0 ]);struct strbuf buf =STRBUF_INIT ; +if (argc >1 ) +die (_ ("too many branches to unset upstream" )); + +if (!branch) { +if (!argc || !strcmp (argv[0 ],"HEAD" )) +die (_ ("could not unset upstream of HEAD when " +"it does not point to any branch." )); +die (_ ("no such branch '%s'" ), argv[0 ]); + } +if (!branch_has_merge_config (branch)) {die (_ ("Branch '%s' has no upstream information" ), branch->name); }
@@ -916,6 +937,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)int branch_existed =0 , remote_tracking =0 ;struct strbuf buf =STRBUF_INIT ; +if (!strcmp (argv[0 ],"HEAD" )) +die (_ ("it does not make sense to create 'HEAD' manually" )); + +if (!branch) +die (_ ("no such branch '%s'" ), argv[0 ]); +if (kinds !=REF_LOCAL_BRANCH )die (_ ("-a and -r options to 'git branch' do not make sense with a branch name" ));
t/t3200-branch.sh +21 -0
@@ -42,6 +42,10 @@ test_expect_success \ 'git branch a/b/c should create a branch' \ 'git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c' +test_expect_success \ + 'git branch HEAD should fail' \ + 'test_must_fail git branch HEAD' + cat >expect <<EOF $_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master EOF
@@ -388,6 +392,14 @@ test_expect_success \ 'git tag foobar && test_must_fail git branch --track my11 foobar' +test_expect_success '--set-upstream-to fails on multiple branches' \ + 'test_must_fail git branch --set-upstream-to master a b c' + +test_expect_success '--set-upstream-to fails on detached HEAD' \ + 'git checkout HEAD^{} && + test_must_fail git branch --set-upstream-to master && + git checkout -' + test_expect_success 'use --set-upstream-to modify HEAD' \ 'test_config branch.master.remote foo && test_config branch.master.merge foo &&
@@ -417,6 +429,15 @@ test_expect_success 'test --unset-upstream on HEAD' \ test_must_fail git branch --unset-upstream ' +test_expect_success '--unset-upstream should fail on multiple branches' \ + 'test_must_fail git branch --unset-upstream a b c' + +test_expect_success '--unset-upstream should fail on detached HEAD' \ + 'git checkout HEAD^{} && + test_must_fail git branch --unset-upstream && + git checkout - +' + test_expect_success 'test --unset-upstream on a particular branch' \ 'git branch my15 git branch --set-upstream-to master my14 &&
Signature · 1 line
1.8.1.2.536.gf441e6d
Re: [PATCH v3] branch: segfault fixes and validation
Quoted 9 lines · Nguyễn Thái Ngọc Duy
Quoted 5 lines
What you can do is to have a single helper function that can explain why
branch_get()returned NULL (or extendbranch_get()to serve that purpose as well); then you do not have to duplicate the logic twice on the caller's side (and there may be other callers that want to do the same).The explanation mentions about the failed operation, which makes a helper less useful. We could still do the helper, but it may lead to i18n legos. So no helper in this version.
Who said explanation has to be conveyed in human language to the caller of the helper? Since there are only two possible cases, at least for now, and I do not think there will be countless many in the future, for the branch_get() function to fail, you can still do:
int explain_error;
struct branch *branch = branch_get(argv[0], &explain_error);
switch (explain_error) {
case DEFAULT_HEAD_DETACHED:
case GIVEN_HEAD_DETACHED:
die(_("could not make %s upstream of the current branch "
"because you do not have one"), new_upstream);
break;
default:
break;
}and we could even fold the !ref_exists() check that is there for typo-detection purposes into the framework, e.g.
case GIVEN_BRANCH_DOES_NOT_EXIST:
die(_("you told me to make %s upstream of %s "
"but the latter does not exist yet"), new_upstream, argv[0]);
if we wanted to preserve what the current test does, no?
Quoted 7 lines
Quoted 4 lines
The existing test might be wrong, by the way. Your HEAD may point at a branch Y but you may not have any commit on it yet, and you may want to allow setting the upstream of that to-be-born branch to another branch X with "branch --set-upstream-to=X [Y|HEAD]".
It sounds complicated. I think we can revisit it when a user actually complains about it.
Yeah, will replace the previous one and queue this version.
Thanks.
Quoted 3 lines · Per Cederqvist
Running "git branch HEAD" may be a stupid thing to do. It actually was a mistake on my part. Still, I don't think git should dereference a NULL pointer.
We should not. Can you make a patch to fix it (with test cases)? You may want to fix the two preceding blocks, "if (new_upstream)" and "if (unset_upstream)", as well. They don't check for NULL branch either. I think we can say something like "detached HEAD is not valid for this operation" before exit.
Quoted 56 lines
Tested using git 1.8.1.4 adn 1.8.1.1.
Repeat by:
mkdir branchcrash || exit 1
cd branchcrash
git init
touch a; git add a; git commit -m"Added a".
touch b; git add b; git commit -m"Added b".
git checkout HEAD^
git branch HEADThe last command dumps core. gdb session:
gdb
/usr/local/bin/gitcore
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04 Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from/usr/local/bin/git...done.
[New LWP 7174]warning: Can't read pathname for load map: Input/output error. [Thread debugging using
libthread_dbenabled]
Using hostlibthread_dblibrary "/lib/x86_64-linux-gnu/libthread_db.so.1". Core was generated by `git branch HEAD'.
Program terminated with signal 11, Segmentation fault.
#0cmd_branch(argc=1, argv=0x7fffe6e2a0f0, prefix=<optimized out>)at builtin/branch.c:919 919 strbuf_addf(&buf, "refs/remotes/%s", branch->name); (gdb) bt #0 cmd_branch (argc=1, argv=0x7fffe6e2a0f0, prefix=<optimized out>) at builtin/branch.c:919 #1 0x00000000004046ac in run_builtin (argv=0x7fffe6e2a0f0, argc=2, p=<optimized out>) at git.c:273 #2 handle_internal_command (argc=2, argv=0x7fffe6e2a0f0) at git.c:434 #3 0x0000000000404df3 in run_argv (argv=0x7fffe6e29f90, argcp=0x7fffe6e29f9c) at git.c:480#4 main (argc=2, argv=0x7fffe6e2a0f0) at git.c:555 (gdb) p branch
$1 = (struct branch *)0x0
(gdb) quit/ceder
--
To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Duy
Quoted 10 lines · Duy Nguyen
Quoted 3 lines · Per Cederqvist
Running "git branch HEAD" may be a stupid thing to do. It actually was a mistake on my part. Still, I don't think git should dereference a NULL pointer.
We should not. Can you make a patch to fix it (with test cases)? You may want to fix the two preceding blocks, "if (
new_upstream)" and "if (unset_upstream)", as well. They don't check for NULL branch either. I think we can say something like "detached HEAD is not valid for this operation" before exit.
Sorry, but isolating the issue reporting it here is about as much time as I can spend on this issue. Learning the coding standard of Git and how to write test cases is not something I'm prepared to do, at least not at the moment. I hope there is a place for users and reporters of bugs in the Git community.
/ceder
Quoted 59 lines
Quoted 56 lines
Tested using git 1.8.1.4 adn 1.8.1.1.
Repeat by:
mkdir branchcrash || exit 1
cd branchcrash
git init
touch a; git add a; git commit -m"Added a".
touch b; git add b; git commit -m"Added b".
git checkout HEAD^
git branch HEADThe last command dumps core. gdb session:
gdb
/usr/local/bin/gitcore
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04 Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from/usr/local/bin/git...done.
[New LWP 7174]warning: Can't read pathname for load map: Input/output error. [Thread debugging using
libthread_dbenabled]
Using hostlibthread_dblibrary "/lib/x86_64-linux-gnu/libthread_db.so.1". Core was generated by `git branch HEAD'.
Program terminated with signal 11, Segmentation fault.
#0cmd_branch(argc=1, argv=0x7fffe6e2a0f0, prefix=<optimized out>)at builtin/branch.c:919 919 strbuf_addf(&buf, "refs/remotes/%s", branch->name); (gdb) bt #0 cmd_branch (argc=1, argv=0x7fffe6e2a0f0, prefix=<optimized out>) at builtin/branch.c:919 #1 0x00000000004046ac in run_builtin (argv=0x7fffe6e2a0f0, argc=2, p=<optimized out>) at git.c:273 #2 handle_internal_command (argc=2, argv=0x7fffe6e2a0f0) at git.c:434 #3 0x0000000000404df3 in run_argv (argv=0x7fffe6e29f90, argcp=0x7fffe6e29f9c) at git.c:480#4 main (argc=2, argv=0x7fffe6e2a0f0) at git.c:555 (gdb) p branch
$1 = (struct branch *)0x0
(gdb) quit/ceder
--
To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 5 lines · Per Cederqvist
Sorry, but isolating the issue reporting it here is about as much time as I can spend on this issue. Learning the coding standard of Git and how to write test cases is not something I'm prepared to do, at least not at the moment. I hope there is a place for users and reporters of bugs in the Git community.
Sure. No problem. I just thought you might want to finish it off. I'll look into it.
Signature · 1 line
Duy