* Bug: git bus error (stack blowout)
@ 2011-12-04 22:50 Venkatesh Srinivas
2011-12-05 4:58 ` Nguyen Thai Ngoc Duy
0 siblings, 1 reply; 2+ messages in thread
From: Venkatesh Srinivas @ 2011-12-04 22:50 UTC (permalink / raw
To: git
Hi,
When using git 1.7.6.3 from NetBSD's pkgsrc, on this git tree:
http://gitweb.dragonflybsd.org/pkgsrcv2.git, I got a bus error when
switching from the pkgsrc-2011q3 branch to the master branch. I have a
core file and the git binary if it'd be helpful; it looks like
mark_parents_uninteresting() was called recursively entirely too many
times (>60,000), originally from prepare_revision_walk(), from
stat_tracking_info(), from format_tracking_info(),
update_revs_for_switch(), from cmd_checkout().
Thanks,
-- vs;
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Bug: git bus error (stack blowout)
2011-12-04 22:50 Bug: git bus error (stack blowout) Venkatesh Srinivas
@ 2011-12-05 4:58 ` Nguyen Thai Ngoc Duy
0 siblings, 0 replies; 2+ messages in thread
From: Nguyen Thai Ngoc Duy @ 2011-12-05 4:58 UTC (permalink / raw
To: vsrinivas; +Cc: git
On Sun, Dec 04, 2011 at 05:50:19PM -0500, Venkatesh Srinivas wrote:
> Hi,
>
> When using git 1.7.6.3 from NetBSD's pkgsrc, on this git tree:
> http://gitweb.dragonflybsd.org/pkgsrcv2.git, I got a bus error when
> switching from the pkgsrc-2011q3 branch to the master branch. I have a
> core file and the git binary if it'd be helpful; it looks like
> mark_parents_uninteresting() was called recursively entirely too many
> times (>60,000), originally from prepare_revision_walk(), from
> stat_tracking_info(), from format_tracking_info(),
> update_revs_for_switch(), from cmd_checkout().
This patch may fix it for you, although it'd be interesting to
understand how you get into this (I'm still cloning pkgsrcv2.git).
-- 8< --
Subject: [PATCH] Eliminate recursion in setting/clearing marks in commit list
Recursion in a DAG is generally a bad idea because it could be very
deep. Be defensive and avoid recursion in mark_parents_uninteresting()
and clear_commit_marks().
mark_parents_uninteresting() learns a trick from clear_commit_marks()
to avoid malloc() in (dorminant) single-parent case.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
commit.c | 31 ++++++++++++++++++++-----------
revision.c | 45 +++++++++++++++++++++++++++++----------------
2 files changed, 49 insertions(+), 27 deletions(-)
diff --git a/commit.c b/commit.c
index 0775eec..cd19a69 100644
--- a/commit.c
+++ b/commit.c
@@ -423,22 +423,31 @@ struct commit *pop_most_recent_commit(struct commit_list **list,
void clear_commit_marks(struct commit *commit, unsigned int mark)
{
- while (commit) {
- struct commit_list *parents;
+ struct commit_list *list = NULL, *l;
+ commit_list_insert(commit, &list);
+ while (list) {
+ commit = list->item;
+ l = list;
+ list = list->next;
+ free(l);
- if (!(mark & commit->object.flags))
- return;
+ while (commit) {
+ struct commit_list *parents;
- commit->object.flags &= ~mark;
+ if (!(mark & commit->object.flags))
+ break;
- parents = commit->parents;
- if (!parents)
- return;
+ commit->object.flags &= ~mark;
+
+ parents = commit->parents;
+ if (!parents)
+ break;
- while ((parents = parents->next))
- clear_commit_marks(parents->item, mark);
+ while ((parents = parents->next))
+ commit_list_insert(parents->item, &list);
- commit = commit->parents->item;
+ commit = commit->parents->item;
+ }
}
}
diff --git a/revision.c b/revision.c
index 0aa3638..8d4069e 100644
--- a/revision.c
+++ b/revision.c
@@ -139,11 +139,32 @@ void mark_tree_uninteresting(struct tree *tree)
void mark_parents_uninteresting(struct commit *commit)
{
- struct commit_list *parents = commit->parents;
+ struct commit_list *parents = NULL, *l;
+
+ for (l = commit->parents; l; l = l->next)
+ commit_list_insert(l->item, &parents);
while (parents) {
struct commit *commit = parents->item;
- if (!(commit->object.flags & UNINTERESTING)) {
+ l = parents;
+ parents = parents->next;
+ free(l);
+
+ while (commit) {
+ /*
+ * A missing commit is ok iff its parent is marked
+ * uninteresting.
+ *
+ * We just mark such a thing parsed, so that when
+ * it is popped next time around, we won't be trying
+ * to parse it and get an error.
+ */
+ if (!has_sha1_file(commit->object.sha1))
+ commit->object.parsed = 1;
+
+ if (commit->object.flags & UNINTERESTING)
+ break;
+
commit->object.flags |= UNINTERESTING;
/*
@@ -154,21 +175,13 @@ void mark_parents_uninteresting(struct commit *commit)
* wasn't uninteresting), in which case we need
* to mark its parents recursively too..
*/
- if (commit->parents)
- mark_parents_uninteresting(commit);
- }
+ if (!commit->parents)
+ break;
- /*
- * A missing commit is ok iff its parent is marked
- * uninteresting.
- *
- * We just mark such a thing parsed, so that when
- * it is popped next time around, we won't be trying
- * to parse it and get an error.
- */
- if (!has_sha1_file(commit->object.sha1))
- commit->object.parsed = 1;
- parents = parents->next;
+ for (l = commit->parents->next; l; l = l->next)
+ commit_list_insert(l->item, &parents);
+ commit = commit->parents->item;
+ }
}
}
--
1.7.8.36.g69ee2
-- 8< --
--
Duy
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-12-05 4:58 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-04 22:50 Bug: git bus error (stack blowout) Venkatesh Srinivas
2011-12-05 4:58 ` Nguyen Thai Ngoc Duy
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).