* regression in 92392b4
@ 2008-07-22 23:17 Pierre Habouzit
2008-07-22 23:34 ` Johannes Schindelin
` (2 more replies)
0 siblings, 3 replies; 24+ messages in thread
From: Pierre Habouzit @ 2008-07-22 23:17 UTC (permalink / raw)
To: spearce; +Cc: Git ML, Junio C Hamano
[-- Attachment #1: Type: text/plain, Size: 2098 bytes --]
Hi, here is a manual painful down-secting (opposed to a bisect ;P) I
did, since git in next cannot fetch on a regular basis for me. The
culprit seems to be commit 92392b4:
┌─(1:11)──<~/dev/scm/git 92392b4...>──
└[artemis] git fetch
remote: Counting objects: 461, done.
remote: Compressing objects: 100% (141/141), done.
remote: Total 263 (delta 227), reused 155 (delta 121)
Receiving objects: 100% (263/263), 95.55 KiB, done.
fatal: Out of memory, malloc failed
fatal: index-pack failed
[2] 16674 abort (core dumped) git fetch
┌─(1:12)──<~/dev/scm/git 92392b4...>──
└[artemis] git checkout -m HEAD~1; make git-index-pack
Previous HEAD position was 92392b4... index-pack: Honor core.deltaBaseCacheLimit when resolving deltas
HEAD is now at 03993e1... index-pack: Track the object_entry that creates each base_data
GIT_VERSION = 1.5.6.3.3.g03993
CC index-pack.o
LINK git-index-pack
┌─(1:12)──<~/dev/scm/git 03993e1...>──
└[artemis] git fetch
remote: Counting objects: 461, done.
remote: Compressing objects: 100% (141/141), done.
remote: Total 263 (delta 227), reused 155 (delta 121)
Receiving objects: 100% (263/263), 95.55 KiB, done.
Resolving deltas: 100% (227/227), completed with 153 local objects.
From git://git.kernel.org/pub/scm/git/git
5ba2c22..0868a30 html -> origin/html
2857e17..abeeabe man -> origin/man
93310a4..95f8ebb master -> origin/master
559998f..e8bf351 next -> origin/next
You can see the commit sha's in the prompt. 03993e1 is fine, 92392b4 is
broken, I've absolutely no clue about what happens.
All I can say is that at some point in get_data_from_pack, obj[1].idx
points to something that is *not* a sha so it's probably corrupted.
(from index-pack.c).
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: regression in 92392b4 2008-07-22 23:17 regression in 92392b4 Pierre Habouzit @ 2008-07-22 23:34 ` Johannes Schindelin 2008-07-23 0:41 ` Shawn O. Pearce 2008-07-22 23:37 ` Pierre Habouzit 2008-07-23 10:14 ` Björn Steinbrink 2 siblings, 1 reply; 24+ messages in thread From: Johannes Schindelin @ 2008-07-22 23:34 UTC (permalink / raw) To: Pierre Habouzit; +Cc: spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: TEXT/PLAIN, Size: 2507 bytes --] Hi, On Wed, 23 Jul 2008, Pierre Habouzit wrote: > Hi, here is a manual painful down-secting (opposed to a bisect ;P) I > did, since git in next cannot fetch on a regular basis for me. The > culprit seems to be commit 92392b4: > > ┌─(1:11)──<~/dev/scm/git 92392b4...>── > └[artemis] git fetch > remote: Counting objects: 461, done. > remote: Compressing objects: 100% (141/141), done. > remote: Total 263 (delta 227), reused 155 (delta 121) > Receiving objects: 100% (263/263), 95.55 KiB, done. > fatal: Out of memory, malloc failed > fatal: index-pack failed > [2] 16674 abort (core dumped) git fetch > > ┌─(1:12)──<~/dev/scm/git 92392b4...>── > └[artemis] git checkout -m HEAD~1; make git-index-pack > Previous HEAD position was 92392b4... index-pack: Honor core.deltaBaseCacheLimit when resolving deltas > HEAD is now at 03993e1... index-pack: Track the object_entry that creates each base_data > GIT_VERSION = 1.5.6.3.3.g03993 > CC index-pack.o > LINK git-index-pack > > ┌─(1:12)──<~/dev/scm/git 03993e1...>── > └[artemis] git fetch > remote: Counting objects: 461, done. > remote: Compressing objects: 100% (141/141), done. > remote: Total 263 (delta 227), reused 155 (delta 121) > Receiving objects: 100% (263/263), 95.55 KiB, done. > Resolving deltas: 100% (227/227), completed with 153 local objects. > From git://git.kernel.org/pub/scm/git/git > 5ba2c22..0868a30 html -> origin/html > 2857e17..abeeabe man -> origin/man > 93310a4..95f8ebb master -> origin/master > 559998f..e8bf351 next -> origin/next > > You can see the commit sha's in the prompt. 03993e1 is fine, 92392b4 is > broken, I've absolutely no clue about what happens. > > All I can say is that at some point in get_data_from_pack, obj[1].idx > points to something that is *not* a sha so it's probably corrupted. > (from index-pack.c). Just a guess: -- snipsnap -- [PATCH] index-pack: set base_data's data member to NULL after freeing it Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> --- index-pack.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/index-pack.c b/index-pack.c index ac20a46..19c39e5 100644 --- a/index-pack.c +++ b/index-pack.c @@ -257,6 +257,7 @@ static void unlink_base_data(struct base_data *c) base_cache = NULL; if (c->data) { free(c->data); + c->data = NULL; base_cache_used -= c->size; } } ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-22 23:34 ` Johannes Schindelin @ 2008-07-23 0:41 ` Shawn O. Pearce 2008-07-23 0:58 ` Johannes Schindelin 2008-07-23 1:09 ` Pierre Habouzit 0 siblings, 2 replies; 24+ messages in thread From: Shawn O. Pearce @ 2008-07-23 0:41 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Pierre Habouzit, Git ML, Junio C Hamano Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > On Wed, 23 Jul 2008, Pierre Habouzit wrote: > > > Hi, here is a manual painful down-secting (opposed to a bisect ;P) I > > did, since git in next cannot fetch on a regular basis for me. The > > culprit seems to be commit 92392b4: > > > > ┌─(1:11)──<~/dev/scm/git 92392b4...>── > > └[artemis] git fetch > > remote: Counting objects: 461, done. > > remote: Compressing objects: 100% (141/141), done. > > remote: Total 263 (delta 227), reused 155 (delta 121) > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > fatal: Out of memory, malloc failed > > fatal: index-pack failed > > [2] 16674 abort (core dumped) git fetch ... > > Just a guess: ... > diff --git a/index-pack.c b/index-pack.c > index ac20a46..19c39e5 100644 > --- a/index-pack.c > +++ b/index-pack.c > @@ -257,6 +257,7 @@ static void unlink_base_data(struct base_data *c) > base_cache = NULL; > if (c->data) { > free(c->data); > + c->data = NULL; > base_cache_used -= c->size; > } > } Oh. This is a pointless assignment. If you look at any call sites for unlink_base_data() you will find that the struct passed in as "c" here is going out of scope after unlink_base_data() returns. In no such case does the value of c->data get tested once this free is complete. We need the if (c->data) guard because we only want to decrement base_cache_used if the memory is still allocated. It may have been released earlier, in which case base_cache_used has already been decreased and we don't want to double-decrement it. This patch makes the code more obvious, so Ack I guess, but it is not a solution to Pierre's woes. Something else is wrong. Reading above shows we got a "fatal: Out of memory, malloc failed" right before the segfault. What's odd is we segfaulted after we ran out of memory and should have die'd. There's at least two bugs in the above output: a) index-pack ran out of memory on a small pull (95 KiB). b) fetch segfaulted when index-pack failed. And this patch will unfortunately address neither of them. :-| I've had a long past couple of days, and another one tomorrow. I'm not going to be able to debug this myself until perhaps Thursday or Friday. Sorry. If nobody beats me to it, I will put this on the top of the pile and try to fix it once I get back online at my new home. -- Shawn. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-23 0:41 ` Shawn O. Pearce @ 2008-07-23 0:58 ` Johannes Schindelin 2008-07-23 1:09 ` Pierre Habouzit 1 sibling, 0 replies; 24+ messages in thread From: Johannes Schindelin @ 2008-07-23 0:58 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Pierre Habouzit, Git ML, Junio C Hamano Hi, On Tue, 22 Jul 2008, Shawn O. Pearce wrote: > Reading above shows we got a "fatal: Out of memory, malloc failed" right > before the segfault. What's odd is we segfaulted after we ran out of > memory and should have die'd. > > There's at least two bugs in the above output: > > a) index-pack ran out of memory on a small pull (95 KiB). > b) fetch segfaulted when index-pack failed. > > And this patch will unfortunately address neither of them. :-| Yeah, I thought I had something, but no matter what I tried, I could not find a breakage. Not even valgrind complains. But as I said: it was just a guess. Maybe it will be easier to reproduce by patching the code to malloc() everything that is available first, and then continuing. Ciao, Dscho ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-23 0:41 ` Shawn O. Pearce 2008-07-23 0:58 ` Johannes Schindelin @ 2008-07-23 1:09 ` Pierre Habouzit 2008-07-23 1:20 ` Johannes Schindelin 1 sibling, 1 reply; 24+ messages in thread From: Pierre Habouzit @ 2008-07-23 1:09 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Johannes Schindelin, Git ML, Junio C Hamano [-- Attachment #1: Type: text/plain, Size: 3351 bytes --] On Wed, Jul 23, 2008 at 12:41:08AM +0000, Shawn O. Pearce wrote: > Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > > On Wed, 23 Jul 2008, Pierre Habouzit wrote: > > > > > Hi, here is a manual painful down-secting (opposed to a bisect ;P) I > > > did, since git in next cannot fetch on a regular basis for me. The > > > culprit seems to be commit 92392b4: > > > > > > ┌─(1:11)──<~/dev/scm/git 92392b4....>── > > > └[artemis] git fetch > > > remote: Counting objects: 461, done. > > > remote: Compressing objects: 100% (141/141), done. > > > remote: Total 263 (delta 227), reused 155 (delta 121) > > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > > fatal: Out of memory, malloc failed > > > fatal: index-pack failed > > > [2] 16674 abort (core dumped) git fetch > .... > > > > Just a guess: > .... > > diff --git a/index-pack.c b/index-pack.c > > index ac20a46..19c39e5 100644 > > --- a/index-pack.c > > +++ b/index-pack.c > > @@ -257,6 +257,7 @@ static void unlink_base_data(struct base_data *c) > > base_cache = NULL; > > if (c->data) { > > free(c->data); > > + c->data = NULL; > > base_cache_used -= c->size; > > } > > } > > Oh. This is a pointless assignment. If you look at any call sites > for unlink_base_data() you will find that the struct passed in as > "c" here is going out of scope after unlink_base_data() returns. In > no such case does the value of c->data get tested once this free is > complete. > > We need the if (c->data) guard because we only want to decrement > base_cache_used if the memory is still allocated. It may have been > released earlier, in which case base_cache_used has already been > decreased and we don't want to double-decrement it. > > This patch makes the code more obvious, so Ack I guess, but it is > not a solution to Pierre's woes. Something else is wrong. > > Reading above shows we got a "fatal: Out of memory, malloc failed" > right before the segfault. What's odd is we segfaulted after we > ran out of memory and should have die'd. > > There's at least two bugs in the above output: > > a) index-pack ran out of memory on a small pull (95 KiB). > b) fetch segfaulted when index-pack failed. > > And this patch will unfortunately address neither of them. :-| > > I've had a long past couple of days, and another one tomorrow. > I'm not going to be able to debug this myself until perhaps Thursday > or Friday. Sorry. If nobody beats me to it, I will put this on > the top of the pile and try to fix it once I get back online at my > new home. Like I said, I had a core that I stupidly lost, but I remember that the broken malloc was: static void *get_data_from_pack(struct object_entry *obj) { off_t from = obj[0].idx.offset + obj[0].hdr_size; unsigned long len = obj[1].idx.offset - from; unsigned long rdy = 0; unsigned char *src, *data; z_stream stream; int st; src = xmalloc(len); ^^^^^^^^^^^^^^^^^^ len was horribly big, and outputing obj[1].idx showed that `sha1` had text in it. I mean something like "could not\r\n han" IIRC. I don't remember the rest of the backtrace, and have stupidly not kept any ways of reproducing it. [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-23 1:09 ` Pierre Habouzit @ 2008-07-23 1:20 ` Johannes Schindelin 0 siblings, 0 replies; 24+ messages in thread From: Johannes Schindelin @ 2008-07-23 1:20 UTC (permalink / raw) To: Pierre Habouzit; +Cc: Shawn O. Pearce, Git ML, Junio C Hamano Hi, On Wed, 23 Jul 2008, Pierre Habouzit wrote: > I had a core that I stupidly lost, but I remember that the broken malloc > was: > > > static void *get_data_from_pack(struct object_entry *obj) > { > off_t from = obj[0].idx.offset + obj[0].hdr_size; > unsigned long len = obj[1].idx.offset - from; > unsigned long rdy = 0; > unsigned char *src, *data; > z_stream stream; > int st; > > src = xmalloc(len); > ^^^^^^^^^^^^^^^^^^ > > len was horribly big, and outputing obj[1].idx showed that `sha1` had > text in it. I mean something like "could not\r\n han" IIRC. > > I don't remember the rest of the backtrace, and have stupidly not kept > any ways of reproducing it. That would not have helped. The memory corruption almost _certainly_ took place way before that. Ciao, Dscho ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-22 23:17 regression in 92392b4 Pierre Habouzit 2008-07-22 23:34 ` Johannes Schindelin @ 2008-07-22 23:37 ` Pierre Habouzit 2008-07-23 10:14 ` Björn Steinbrink 2 siblings, 0 replies; 24+ messages in thread From: Pierre Habouzit @ 2008-07-22 23:37 UTC (permalink / raw) To: spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: text/plain, Size: 3092 bytes --] On Tue, Jul 22, 2008 at 11:17:45PM +0000, Pierre Habouzit wrote: > Hi, here is a manual painful down-secting (opposed to a bisect ;P) I > did, since git in next cannot fetch on a regular basis for me. The > culprit seems to be commit 92392b4: > > ┌─(1:11)──<~/dev/scm/git 92392b4...>── > └[artemis] git fetch > remote: Counting objects: 461, done. > remote: Compressing objects: 100% (141/141), done. > remote: Total 263 (delta 227), reused 155 (delta 121) > Receiving objects: 100% (263/263), 95.55 KiB, done. > fatal: Out of memory, malloc failed > fatal: index-pack failed > [2] 16674 abort (core dumped) git fetch > > ┌─(1:12)──<~/dev/scm/git 92392b4...>── > └[artemis] git checkout -m HEAD~1; make git-index-pack > Previous HEAD position was 92392b4... index-pack: Honor core.deltaBaseCacheLimit when resolving deltas > HEAD is now at 03993e1... index-pack: Track the object_entry that creates each base_data > GIT_VERSION = 1.5.6.3.3.g03993 > CC index-pack.o > LINK git-index-pack > > ┌─(1:12)──<~/dev/scm/git 03993e1...>── > └[artemis] git fetch > remote: Counting objects: 461, done. > remote: Compressing objects: 100% (141/141), done. > remote: Total 263 (delta 227), reused 155 (delta 121) > Receiving objects: 100% (263/263), 95.55 KiB, done. > Resolving deltas: 100% (227/227), completed with 153 local objects. > From git://git.kernel.org/pub/scm/git/git > 5ba2c22..0868a30 html -> origin/html > 2857e17..abeeabe man -> origin/man > 93310a4..95f8ebb master -> origin/master > 559998f..e8bf351 next -> origin/next > > You can see the commit sha's in the prompt. 03993e1 is fine, 92392b4 is > broken, I've absolutely no clue about what happens. > > All I can say is that at some point in get_data_from_pack, obj[1].idx > points to something that is *not* a sha so it's probably corrupted. > (from index-pack.c). Though reading the code, we trust c->data NULL-iness to mean we have no data, and there is one code path that fails to reset it. The problem is I'm not able to reproduce the bug, because I foolishly didn't backuped the git repository that exhibited the failure, so I cannot know if that can be the problem: --- snip --- From c3749f7bc50c642c5d437b2746d4ba589b7d9739 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit <madcoder@debian.org> Date: Wed, 23 Jul 2008 01:35:11 +0200 Subject: [PATCH] index-pack: missing pointer reset to NULL. Signed-off-by: Pierre Habouzit <madcoder@debian.org> --- index-pack.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/index-pack.c b/index-pack.c index ac20a46..19c39e5 100644 --- a/index-pack.c +++ b/index-pack.c @@ -257,6 +257,7 @@ static void unlink_base_data(struct base_data *c) base_cache = NULL; if (c->data) { free(c->data); + c->data = NULL; base_cache_used -= c->size; } } -- 1.6.0.rc0.153.ge8bf3.dirty [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-22 23:17 regression in 92392b4 Pierre Habouzit 2008-07-22 23:34 ` Johannes Schindelin 2008-07-22 23:37 ` Pierre Habouzit @ 2008-07-23 10:14 ` Björn Steinbrink 2008-07-23 10:22 ` Pierre Habouzit ` (2 more replies) 2 siblings, 3 replies; 24+ messages in thread From: Björn Steinbrink @ 2008-07-23 10:14 UTC (permalink / raw) To: Pierre Habouzit, spearce, Git ML, Junio C Hamano On 2008.07.23 01:17:45 +0200, Pierre Habouzit wrote: > Hi, here is a manual painful down-secting (opposed to a bisect ;P) I > did, since git in next cannot fetch on a regular basis for me. The > culprit seems to be commit 92392b4: > > ┌─(1:11)──<~/dev/scm/git 92392b4...>── > └[artemis] git fetch > remote: Counting objects: 461, done. > remote: Compressing objects: 100% (141/141), done. > remote: Total 263 (delta 227), reused 155 (delta 121) > Receiving objects: 100% (263/263), 95.55 KiB, done. > fatal: Out of memory, malloc failed > fatal: index-pack failed > [2] 16674 abort (core dumped) git fetch > > ┌─(1:12)──<~/dev/scm/git 92392b4...>── > └[artemis] git checkout -m HEAD~1; make git-index-pack > Previous HEAD position was 92392b4... index-pack: Honor core.deltaBaseCacheLimit when resolving deltas > HEAD is now at 03993e1... index-pack: Track the object_entry that creates each base_data > GIT_VERSION = 1.5.6.3.3.g03993 > CC index-pack.o > LINK git-index-pack > > ┌─(1:12)──<~/dev/scm/git 03993e1...>── > └[artemis] git fetch > remote: Counting objects: 461, done. > remote: Compressing objects: 100% (141/141), done. > remote: Total 263 (delta 227), reused 155 (delta 121) > Receiving objects: 100% (263/263), 95.55 KiB, done. > Resolving deltas: 100% (227/227), completed with 153 local objects. > From git://git.kernel.org/pub/scm/git/git > 5ba2c22..0868a30 html -> origin/html > 2857e17..abeeabe man -> origin/man > 93310a4..95f8ebb master -> origin/master > 559998f..e8bf351 next -> origin/next > > You can see the commit sha's in the prompt. 03993e1 is fine, 92392b4 is > broken, I've absolutely no clue about what happens. > > All I can say is that at some point in get_data_from_pack, obj[1].idx > points to something that is *not* a sha so it's probably corrupted. > (from index-pack.c). Here's how to reproduce: #!/bin/bash [ -d git-bug ] || \ git clone git://git.kernel.org/pub/scm/git/git git-bug cd git-bug git update-ref refs/remotes/origin/html 5ba2c22 git update-ref refs/remotes/origin/man 2857e17 git update-ref refs/remotes/origin/maint 2d9c572 git update-ref refs/remotes/origin/master 93310a4 git update-ref refs/remotes/origin/next 559998f git update-ref refs/remotes/origin/pu 010581c8 git reset --hard origin/master sleep 1 git reflog expire --expire=0 --all git repack -A -d -f --depth=10 --window=10 git prune git config core.deltaBaseCacheLimit 100 git fetch The values for html, man, master and next are taken from Pierre's output, those for maint and pu are from a repo that works for reproducing the bug, just in case that future output of those branches manage to break the reproducability. Might be, that any fetch will fail if deltaBaseCacheLimit is low enough, but I'm too lazy to test that as well, now that I realized it. My head seems not to be working correctly anyway, can't even manage to get a core dump... Stupid flu... HTH Björn ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-23 10:14 ` Björn Steinbrink @ 2008-07-23 10:22 ` Pierre Habouzit 2008-07-23 10:38 ` Pierre Habouzit 2008-07-23 10:49 ` Johannes Schindelin 2 siblings, 0 replies; 24+ messages in thread From: Pierre Habouzit @ 2008-07-23 10:22 UTC (permalink / raw) To: Björn Steinbrink; +Cc: spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: text/plain, Size: 3258 bytes --] On Wed, Jul 23, 2008 at 10:14:15AM +0000, Björn Steinbrink wrote: > On 2008.07.23 01:17:45 +0200, Pierre Habouzit wrote: > > Hi, here is a manual painful down-secting (opposed to a bisect ;P) I > > did, since git in next cannot fetch on a regular basis for me. The > > culprit seems to be commit 92392b4: > > > > ┌─(1:11)──<~/dev/scm/git 92392b4...>── > > └[artemis] git fetch > > remote: Counting objects: 461, done. > > remote: Compressing objects: 100% (141/141), done. > > remote: Total 263 (delta 227), reused 155 (delta 121) > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > fatal: Out of memory, malloc failed > > fatal: index-pack failed > > [2] 16674 abort (core dumped) git fetch > > > > ┌─(1:12)──<~/dev/scm/git 92392b4...>── > > └[artemis] git checkout -m HEAD~1; make git-index-pack > > Previous HEAD position was 92392b4... index-pack: Honor core.deltaBaseCacheLimit when resolving deltas > > HEAD is now at 03993e1... index-pack: Track the object_entry that creates each base_data > > GIT_VERSION = 1.5.6.3.3.g03993 > > CC index-pack.o > > LINK git-index-pack > > > > ┌─(1:12)──<~/dev/scm/git 03993e1...>── > > └[artemis] git fetch > > remote: Counting objects: 461, done. > > remote: Compressing objects: 100% (141/141), done. > > remote: Total 263 (delta 227), reused 155 (delta 121) > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > Resolving deltas: 100% (227/227), completed with 153 local objects. > > From git://git.kernel.org/pub/scm/git/git > > 5ba2c22..0868a30 html -> origin/html > > 2857e17..abeeabe man -> origin/man > > 93310a4..95f8ebb master -> origin/master > > 559998f..e8bf351 next -> origin/next > > > > You can see the commit sha's in the prompt. 03993e1 is fine, 92392b4 is > > broken, I've absolutely no clue about what happens. > > > > All I can say is that at some point in get_data_from_pack, obj[1].idx > > points to something that is *not* a sha so it's probably corrupted. > > (from index-pack.c). > > Here's how to reproduce: > > #!/bin/bash > > [ -d git-bug ] || \ > git clone git://git.kernel.org/pub/scm/git/git git-bug > cd git-bug > > git update-ref refs/remotes/origin/html 5ba2c22 > git update-ref refs/remotes/origin/man 2857e17 > git update-ref refs/remotes/origin/maint 2d9c572 > git update-ref refs/remotes/origin/master 93310a4 > git update-ref refs/remotes/origin/next 559998f > git update-ref refs/remotes/origin/pu 010581c8 > > git reset --hard origin/master > > sleep 1 > > git reflog expire --expire=0 --all > > git repack -A -d -f --depth=10 --window=10 > git prune > > git config core.deltaBaseCacheLimit 100 > > git fetch *THANKS* I was missing the "git config core.deltaBaseCacheLimit". I did the same as you but it wasn't failing here. FWIW I don't have deltaBaseCacheLimit set in my config, but oh well. -- ·O· Pierre Habouzit ··O madcoder@debian.org OOO http://www.madism.org [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-23 10:14 ` Björn Steinbrink 2008-07-23 10:22 ` Pierre Habouzit @ 2008-07-23 10:38 ` Pierre Habouzit 2008-07-23 10:49 ` Johannes Schindelin 2 siblings, 0 replies; 24+ messages in thread From: Pierre Habouzit @ 2008-07-23 10:38 UTC (permalink / raw) To: Björn Steinbrink; +Cc: spearce, Git ML, Junio C Hamano [-- Attachment #1.1: Type: text/plain, Size: 1598 bytes --] On Wed, Jul 23, 2008 at 10:14:15AM +0000, Björn Steinbrink wrote: > Here's how to reproduce: > > #!/bin/bash > > [ -d git-bug ] || \ > git clone git://git.kernel.org/pub/scm/git/git git-bug > cd git-bug > > git update-ref refs/remotes/origin/html 5ba2c22 > git update-ref refs/remotes/origin/man 2857e17 > git update-ref refs/remotes/origin/maint 2d9c572 > git update-ref refs/remotes/origin/master 93310a4 > git update-ref refs/remotes/origin/next 559998f > git update-ref refs/remotes/origin/pu 010581c8 > > git reset --hard origin/master > > sleep 1 > > git reflog expire --expire=0 --all > > git repack -A -d -f --depth=10 --window=10 > git prune > > git config core.deltaBaseCacheLimit 100 > > git fetch interestingly, replacing git-index-pack with: #!/bin/sh exec valgrind --log-file=trace.$$ $(dirname $0)/git-index-pack2 "$@" it yields a different error in the console: remote: Counting objects: 461, done. remote: Compressing objects: 100% (141/141), done. remote: Total 263 (delta 227), reused 155 (delta 121) Receiving objects: 100% (263/263), 95.55 KiB | 71 KiB/s, done. fatal: serious inflate inconsistency fatal: index-pack failed git fetch 2,63s user 0,08s system 51% cpu 5,275 total the valgrind log is attached, and my index-pack.c as well since I did the c->data = NULL change which may mess up line counts. -- ·O· Pierre Habouzit ··O madcoder@debian.org OOO http://www.madism.org [-- Attachment #1.2: index-pack.c --] [-- Type: text/plain, Size: 26656 bytes --] #include "cache.h" #include "delta.h" #include "pack.h" #include "csum-file.h" #include "blob.h" #include "commit.h" #include "tag.h" #include "tree.h" #include "progress.h" #include "fsck.h" static const char index_pack_usage[] = "git index-pack [-v] [-o <index-file>] [{ ---keep | --keep=<msg> }] [--strict] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }"; struct object_entry { struct pack_idx_entry idx; unsigned long size; unsigned int hdr_size; enum object_type type; enum object_type real_type; }; union delta_base { unsigned char sha1[20]; off_t offset; }; struct base_data { struct base_data *base; struct base_data *child; struct object_entry *obj; void *data; unsigned long size; }; /* * Even if sizeof(union delta_base) == 24 on 64-bit archs, we really want * to memcmp() only the first 20 bytes. */ #define UNION_BASE_SZ 20 #define FLAG_LINK (1u<<20) #define FLAG_CHECKED (1u<<21) struct delta_entry { union delta_base base; int obj_no; }; static struct object_entry *objects; static struct delta_entry *deltas; static struct base_data *base_cache; static size_t base_cache_used; static int nr_objects; static int nr_deltas; static int nr_resolved_deltas; static int from_stdin; static int strict; static int verbose; static struct progress *progress; /* We always read in 4kB chunks. */ static unsigned char input_buffer[4096]; static unsigned int input_offset, input_len; static off_t consumed_bytes; static SHA_CTX input_ctx; static uint32_t input_crc32; static int input_fd, output_fd, pack_fd; static int mark_link(struct object *obj, int type, void *data) { if (!obj) return -1; if (type != OBJ_ANY && obj->type != type) die("object type mismatch at %s", sha1_to_hex(obj->sha1)); obj->flags |= FLAG_LINK; return 0; } /* The content of each linked object must have been checked or it must be already present in the object database */ static void check_object(struct object *obj) { if (!obj) return; if (!(obj->flags & FLAG_LINK)) return; if (!(obj->flags & FLAG_CHECKED)) { unsigned long size; int type = sha1_object_info(obj->sha1, &size); if (type != obj->type || type <= 0) die("object of unexpected type"); obj->flags |= FLAG_CHECKED; return; } } static void check_objects(void) { unsigned i, max; max = get_max_object_index(); for (i = 0; i < max; i++) check_object(get_indexed_object(i)); } /* Discard current buffer used content. */ static void flush(void) { if (input_offset) { if (output_fd >= 0) write_or_die(output_fd, input_buffer, input_offset); SHA1_Update(&input_ctx, input_buffer, input_offset); memmove(input_buffer, input_buffer + input_offset, input_len); input_offset = 0; } } /* * Make sure at least "min" bytes are available in the buffer, and * return the pointer to the buffer. */ static void *fill(int min) { if (min <= input_len) return input_buffer + input_offset; if (min > sizeof(input_buffer)) die("cannot fill %d bytes", min); flush(); do { ssize_t ret = xread(input_fd, input_buffer + input_len, sizeof(input_buffer) - input_len); if (ret <= 0) { if (!ret) die("early EOF"); die("read error on input: %s", strerror(errno)); } input_len += ret; if (from_stdin) display_throughput(progress, consumed_bytes + input_len); } while (input_len < min); return input_buffer; } static void use(int bytes) { if (bytes > input_len) die("used more bytes than were available"); input_crc32 = crc32(input_crc32, input_buffer + input_offset, bytes); input_len -= bytes; input_offset += bytes; /* make sure off_t is sufficiently large not to wrap */ if (consumed_bytes > consumed_bytes + bytes) die("pack too large for current definition of off_t"); consumed_bytes += bytes; } static char *open_pack_file(char *pack_name) { if (from_stdin) { input_fd = 0; if (!pack_name) { static char tmpfile[PATH_MAX]; snprintf(tmpfile, sizeof(tmpfile), "%s/tmp_pack_XXXXXX", get_object_directory()); output_fd = xmkstemp(tmpfile); pack_name = xstrdup(tmpfile); } else output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600); if (output_fd < 0) die("unable to create %s: %s\n", pack_name, strerror(errno)); pack_fd = output_fd; } else { input_fd = open(pack_name, O_RDONLY); if (input_fd < 0) die("cannot open packfile '%s': %s", pack_name, strerror(errno)); output_fd = -1; pack_fd = input_fd; } SHA1_Init(&input_ctx); return pack_name; } static void parse_pack_header(void) { struct pack_header *hdr = fill(sizeof(struct pack_header)); /* Header consistency check */ if (hdr->hdr_signature != htonl(PACK_SIGNATURE)) die("pack signature mismatch"); if (!pack_version_ok(hdr->hdr_version)) die("pack version %"PRIu32" unsupported", ntohl(hdr->hdr_version)); nr_objects = ntohl(hdr->hdr_entries); use(sizeof(struct pack_header)); } static void bad_object(unsigned long offset, const char *format, ...) NORETURN __attribute__((format (printf, 2, 3))); static void bad_object(unsigned long offset, const char *format, ...) { va_list params; char buf[1024]; va_start(params, format); vsnprintf(buf, sizeof(buf), format, params); va_end(params); die("pack has bad object at offset %lu: %s", offset, buf); } static void prune_base_data(struct base_data *retain) { struct base_data *b = base_cache; for (b = base_cache; base_cache_used > delta_base_cache_limit && b; b = b->child) { if (b->data && b != retain) { free(b->data); b->data = NULL; base_cache_used -= b->size; } } } static void link_base_data(struct base_data *base, struct base_data *c) { if (base) base->child = c; else base_cache = c; c->base = base; c->child = NULL; base_cache_used += c->size; prune_base_data(c); } static void unlink_base_data(struct base_data *c) { struct base_data *base = c->base; if (base) base->child = NULL; else base_cache = NULL; if (c->data) { free(c->data); c->data = NULL; base_cache_used -= c->size; } } static void *unpack_entry_data(unsigned long offset, unsigned long size) { z_stream stream; void *buf = xmalloc(size); memset(&stream, 0, sizeof(stream)); stream.next_out = buf; stream.avail_out = size; stream.next_in = fill(1); stream.avail_in = input_len; inflateInit(&stream); for (;;) { int ret = inflate(&stream, 0); use(input_len - stream.avail_in); if (stream.total_out == size && ret == Z_STREAM_END) break; if (ret != Z_OK) bad_object(offset, "inflate returned %d", ret); stream.next_in = fill(1); stream.avail_in = input_len; } inflateEnd(&stream); return buf; } static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_base) { unsigned char *p, c; unsigned long size; off_t base_offset; unsigned shift; void *data; obj->idx.offset = consumed_bytes; input_crc32 = crc32(0, Z_NULL, 0); p = fill(1); c = *p; use(1); obj->type = (c >> 4) & 7; size = (c & 15); shift = 4; while (c & 0x80) { p = fill(1); c = *p; use(1); size += (c & 0x7fUL) << shift; shift += 7; } obj->size = size; switch (obj->type) { case OBJ_REF_DELTA: hashcpy(delta_base->sha1, fill(20)); use(20); break; case OBJ_OFS_DELTA: memset(delta_base, 0, sizeof(*delta_base)); p = fill(1); c = *p; use(1); base_offset = c & 127; while (c & 128) { base_offset += 1; if (!base_offset || MSB(base_offset, 7)) bad_object(obj->idx.offset, "offset value overflow for delta base object"); p = fill(1); c = *p; use(1); base_offset = (base_offset << 7) + (c & 127); } delta_base->offset = obj->idx.offset - base_offset; if (delta_base->offset >= obj->idx.offset) bad_object(obj->idx.offset, "delta base offset is out of bound"); break; case OBJ_COMMIT: case OBJ_TREE: case OBJ_BLOB: case OBJ_TAG: break; default: bad_object(obj->idx.offset, "unknown object type %d", obj->type); } obj->hdr_size = consumed_bytes - obj->idx.offset; data = unpack_entry_data(obj->idx.offset, obj->size); obj->idx.crc32 = input_crc32; return data; } static void *get_data_from_pack(struct object_entry *obj) { off_t from = obj[0].idx.offset + obj[0].hdr_size; unsigned long len = obj[1].idx.offset - from; unsigned long rdy = 0; unsigned char *src, *data; z_stream stream; int st; src = xmalloc(len); data = src; do { ssize_t n = pread(pack_fd, data + rdy, len - rdy, from + rdy); if (n <= 0) die("cannot pread pack file: %s", strerror(errno)); rdy += n; } while (rdy < len); data = xmalloc(obj->size); memset(&stream, 0, sizeof(stream)); stream.next_out = data; stream.avail_out = obj->size; stream.next_in = src; stream.avail_in = len; inflateInit(&stream); while ((st = inflate(&stream, Z_FINISH)) == Z_OK); inflateEnd(&stream); if (st != Z_STREAM_END || stream.total_out != obj->size) die("serious inflate inconsistency"); free(src); return data; } static int find_delta(const union delta_base *base) { int first = 0, last = nr_deltas; while (first < last) { int next = (first + last) / 2; struct delta_entry *delta = &deltas[next]; int cmp; cmp = memcmp(base, &delta->base, UNION_BASE_SZ); if (!cmp) return next; if (cmp < 0) { last = next; continue; } first = next+1; } return -first-1; } static int find_delta_children(const union delta_base *base, int *first_index, int *last_index) { int first = find_delta(base); int last = first; int end = nr_deltas - 1; if (first < 0) return -1; while (first > 0 && !memcmp(&deltas[first - 1].base, base, UNION_BASE_SZ)) --first; while (last < end && !memcmp(&deltas[last + 1].base, base, UNION_BASE_SZ)) ++last; *first_index = first; *last_index = last; return 0; } static void sha1_object(const void *data, unsigned long size, enum object_type type, unsigned char *sha1) { hash_sha1_file(data, size, typename(type), sha1); if (has_sha1_file(sha1)) { void *has_data; enum object_type has_type; unsigned long has_size; has_data = read_sha1_file(sha1, &has_type, &has_size); if (!has_data) die("cannot read existing object %s", sha1_to_hex(sha1)); if (size != has_size || type != has_type || memcmp(data, has_data, size) != 0) die("SHA1 COLLISION FOUND WITH %s !", sha1_to_hex(sha1)); free(has_data); } if (strict) { if (type == OBJ_BLOB) { struct blob *blob = lookup_blob(sha1); if (blob) blob->object.flags |= FLAG_CHECKED; else die("invalid blob object %s", sha1_to_hex(sha1)); } else { struct object *obj; int eaten; void *buf = (void *) data; /* * we do not need to free the memory here, as the * buf is deleted by the caller. */ obj = parse_object_buffer(sha1, type, size, buf, &eaten); if (!obj) die("invalid %s", typename(type)); if (fsck_object(obj, 1, fsck_error_function)) die("Error in object"); if (fsck_walk(obj, mark_link, 0)) die("Not all child objects of %s are reachable", sha1_to_hex(obj->sha1)); if (obj->type == OBJ_TREE) { struct tree *item = (struct tree *) obj; item->buffer = NULL; } if (obj->type == OBJ_COMMIT) { struct commit *commit = (struct commit *) obj; commit->buffer = NULL; } obj->flags |= FLAG_CHECKED; } } } static void *get_base_data(struct base_data *c) { if (!c->data) { struct object_entry *obj = c->obj; if (obj->type == OBJ_REF_DELTA || obj->type == OBJ_OFS_DELTA) { void *base = get_base_data(c->base); void *raw = get_data_from_pack(obj); c->data = patch_delta( base, c->base->size, raw, obj->size, &c->size); free(raw); if (!c->data) bad_object(obj->idx.offset, "failed to apply delta"); } else c->data = get_data_from_pack(obj); base_cache_used += c->size; prune_base_data(c); } return c->data; } static void resolve_delta(struct object_entry *delta_obj, struct base_data *base_obj, enum object_type type) { void *delta_data; unsigned long delta_size; union delta_base delta_base; int j, first, last; struct base_data result; delta_obj->real_type = type; delta_data = get_data_from_pack(delta_obj); delta_size = delta_obj->size; result.data = patch_delta(get_base_data(base_obj), base_obj->size, delta_data, delta_size, &result.size); free(delta_data); if (!result.data) bad_object(delta_obj->idx.offset, "failed to apply delta"); sha1_object(result.data, result.size, type, delta_obj->idx.sha1); nr_resolved_deltas++; result.obj = delta_obj; link_base_data(base_obj, &result); hashcpy(delta_base.sha1, delta_obj->idx.sha1); if (!find_delta_children(&delta_base, &first, &last)) { for (j = first; j <= last; j++) { struct object_entry *child = objects + deltas[j].obj_no; if (child->real_type == OBJ_REF_DELTA) resolve_delta(child, &result, type); } } memset(&delta_base, 0, sizeof(delta_base)); delta_base.offset = delta_obj->idx.offset; if (!find_delta_children(&delta_base, &first, &last)) { for (j = first; j <= last; j++) { struct object_entry *child = objects + deltas[j].obj_no; if (child->real_type == OBJ_OFS_DELTA) resolve_delta(child, &result, type); } } unlink_base_data(&result); } static int compare_delta_entry(const void *a, const void *b) { const struct delta_entry *delta_a = a; const struct delta_entry *delta_b = b; return memcmp(&delta_a->base, &delta_b->base, UNION_BASE_SZ); } /* Parse all objects and return the pack content SHA1 hash */ static void parse_pack_objects(unsigned char *sha1) { int i; struct delta_entry *delta = deltas; struct stat st; /* * First pass: * - find locations of all objects; * - calculate SHA1 of all non-delta objects; * - remember base (SHA1 or offset) for all deltas. */ if (verbose) progress = start_progress( from_stdin ? "Receiving objects" : "Indexing objects", nr_objects); for (i = 0; i < nr_objects; i++) { struct object_entry *obj = &objects[i]; void *data = unpack_raw_entry(obj, &delta->base); obj->real_type = obj->type; if (obj->type == OBJ_REF_DELTA || obj->type == OBJ_OFS_DELTA) { nr_deltas++; delta->obj_no = i; delta++; } else sha1_object(data, obj->size, obj->type, obj->idx.sha1); free(data); display_progress(progress, i+1); } objects[i].idx.offset = consumed_bytes; stop_progress(&progress); /* Check pack integrity */ flush(); SHA1_Final(sha1, &input_ctx); if (hashcmp(fill(20), sha1)) die("pack is corrupted (SHA1 mismatch)"); use(20); /* If input_fd is a file, we should have reached its end now. */ if (fstat(input_fd, &st)) die("cannot fstat packfile: %s", strerror(errno)); if (S_ISREG(st.st_mode) && lseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size) die("pack has junk at the end"); if (!nr_deltas) return; /* Sort deltas by base SHA1/offset for fast searching */ qsort(deltas, nr_deltas, sizeof(struct delta_entry), compare_delta_entry); /* * Second pass: * - for all non-delta objects, look if it is used as a base for * deltas; * - if used as a base, uncompress the object and apply all deltas, * recursively checking if the resulting object is used as a base * for some more deltas. */ if (verbose) progress = start_progress("Resolving deltas", nr_deltas); for (i = 0; i < nr_objects; i++) { struct object_entry *obj = &objects[i]; union delta_base base; int j, ref, ref_first, ref_last, ofs, ofs_first, ofs_last; struct base_data base_obj; if (obj->type == OBJ_REF_DELTA || obj->type == OBJ_OFS_DELTA) continue; hashcpy(base.sha1, obj->idx.sha1); ref = !find_delta_children(&base, &ref_first, &ref_last); memset(&base, 0, sizeof(base)); base.offset = obj->idx.offset; ofs = !find_delta_children(&base, &ofs_first, &ofs_last); if (!ref && !ofs) continue; base_obj.data = get_data_from_pack(obj); base_obj.size = obj->size; base_obj.obj = obj; link_base_data(NULL, &base_obj); if (ref) for (j = ref_first; j <= ref_last; j++) { struct object_entry *child = objects + deltas[j].obj_no; if (child->real_type == OBJ_REF_DELTA) resolve_delta(child, &base_obj, obj->type); } if (ofs) for (j = ofs_first; j <= ofs_last; j++) { struct object_entry *child = objects + deltas[j].obj_no; if (child->real_type == OBJ_OFS_DELTA) resolve_delta(child, &base_obj, obj->type); } unlink_base_data(&base_obj); display_progress(progress, nr_resolved_deltas); } } static int write_compressed(int fd, void *in, unsigned int size, uint32_t *obj_crc) { z_stream stream; unsigned long maxsize; void *out; memset(&stream, 0, sizeof(stream)); deflateInit(&stream, zlib_compression_level); maxsize = deflateBound(&stream, size); out = xmalloc(maxsize); /* Compress it */ stream.next_in = in; stream.avail_in = size; stream.next_out = out; stream.avail_out = maxsize; while (deflate(&stream, Z_FINISH) == Z_OK); deflateEnd(&stream); size = stream.total_out; write_or_die(fd, out, size); *obj_crc = crc32(*obj_crc, out, size); free(out); return size; } static struct object_entry *append_obj_to_pack( const unsigned char *sha1, void *buf, unsigned long size, enum object_type type) { struct object_entry *obj = &objects[nr_objects++]; unsigned char header[10]; unsigned long s = size; int n = 0; unsigned char c = (type << 4) | (s & 15); s >>= 4; while (s) { header[n++] = c | 0x80; c = s & 0x7f; s >>= 7; } header[n++] = c; write_or_die(output_fd, header, n); obj[0].idx.crc32 = crc32(0, Z_NULL, 0); obj[0].idx.crc32 = crc32(obj[0].idx.crc32, header, n); obj[1].idx.offset = obj[0].idx.offset + n; obj[1].idx.offset += write_compressed(output_fd, buf, size, &obj[0].idx.crc32); hashcpy(obj->idx.sha1, sha1); return obj; } static int delta_pos_compare(const void *_a, const void *_b) { struct delta_entry *a = *(struct delta_entry **)_a; struct delta_entry *b = *(struct delta_entry **)_b; return a->obj_no - b->obj_no; } static void fix_unresolved_deltas(int nr_unresolved) { struct delta_entry **sorted_by_pos; int i, n = 0; /* * Since many unresolved deltas may well be themselves base objects * for more unresolved deltas, we really want to include the * smallest number of base objects that would cover as much delta * as possible by picking the * trunc deltas first, allowing for other deltas to resolve without * additional base objects. Since most base objects are to be found * before deltas depending on them, a good heuristic is to start * resolving deltas in the same order as their position in the pack. */ sorted_by_pos = xmalloc(nr_unresolved * sizeof(*sorted_by_pos)); for (i = 0; i < nr_deltas; i++) { if (objects[deltas[i].obj_no].real_type != OBJ_REF_DELTA) continue; sorted_by_pos[n++] = &deltas[i]; } qsort(sorted_by_pos, n, sizeof(*sorted_by_pos), delta_pos_compare); for (i = 0; i < n; i++) { struct delta_entry *d = sorted_by_pos[i]; enum object_type type; int j, first, last; struct base_data base_obj; if (objects[d->obj_no].real_type != OBJ_REF_DELTA) continue; base_obj.data = read_sha1_file(d->base.sha1, &type, &base_obj.size); if (!base_obj.data) continue; if (check_sha1_signature(d->base.sha1, base_obj.data, base_obj.size, typename(type))) die("local object %s is corrupt", sha1_to_hex(d->base.sha1)); base_obj.obj = append_obj_to_pack(d->base.sha1, base_obj.data, base_obj.size, type); link_base_data(NULL, &base_obj); find_delta_children(&d->base, &first, &last); for (j = first; j <= last; j++) { struct object_entry *child = objects + deltas[j].obj_no; if (child->real_type == OBJ_REF_DELTA) resolve_delta(child, &base_obj, type); } unlink_base_data(&base_obj); display_progress(progress, nr_resolved_deltas); } free(sorted_by_pos); } static void final(const char *final_pack_name, const char *curr_pack_name, const char *final_index_name, const char *curr_index_name, const char *keep_name, const char *keep_msg, unsigned char *sha1) { const char *report = "pack"; char name[PATH_MAX]; int err; if (!from_stdin) { close(input_fd); } else { fsync_or_die(output_fd, curr_pack_name); err = close(output_fd); if (err) die("error while closing pack file: %s", strerror(errno)); chmod(curr_pack_name, 0444); } if (keep_msg) { int keep_fd, keep_msg_len = strlen(keep_msg); if (!keep_name) { snprintf(name, sizeof(name), "%s/pack/pack-%s.keep", get_object_directory(), sha1_to_hex(sha1)); keep_name = name; } keep_fd = open(keep_name, O_RDWR|O_CREAT|O_EXCL, 0600); if (keep_fd < 0) { if (errno != EEXIST) die("cannot write keep file"); } else { if (keep_msg_len > 0) { write_or_die(keep_fd, keep_msg, keep_msg_len); write_or_die(keep_fd, "\n", 1); } if (close(keep_fd) != 0) die("cannot write keep file"); report = "keep"; } } if (final_pack_name != curr_pack_name) { if (!final_pack_name) { snprintf(name, sizeof(name), "%s/pack/pack-%s.pack", get_object_directory(), sha1_to_hex(sha1)); final_pack_name = name; } if (move_temp_to_file(curr_pack_name, final_pack_name)) die("cannot store pack file"); } chmod(curr_index_name, 0444); if (final_index_name != curr_index_name) { if (!final_index_name) { snprintf(name, sizeof(name), "%s/pack/pack-%s.idx", get_object_directory(), sha1_to_hex(sha1)); final_index_name = name; } if (move_temp_to_file(curr_index_name, final_index_name)) die("cannot store index file"); } if (!from_stdin) { printf("%s\n", sha1_to_hex(sha1)); } else { char buf[48]; int len = snprintf(buf, sizeof(buf), "%s\t%s\n", report, sha1_to_hex(sha1)); write_or_die(1, buf, len); /* * Let's just mimic git-unpack-objects here and write * the last part of the input buffer to stdout. */ while (input_len) { err = xwrite(1, input_buffer + input_offset, input_len); if (err <= 0) break; input_len -= err; input_offset += err; } } } static int git_index_pack_config(const char *k, const char *v, void *cb) { if (!strcmp(k, "pack.indexversion")) { pack_idx_default_version = git_config_int(k, v); if (pack_idx_default_version > 2) die("bad pack.indexversion=%"PRIu32, pack_idx_default_version); return 0; } return git_default_config(k, v, cb); } int main(int argc, char **argv) { int i, fix_thin_pack = 0; char *curr_pack, *pack_name = NULL; char *curr_index, *index_name = NULL; const char *keep_name = NULL, *keep_msg = NULL; char *index_name_buf = NULL, *keep_name_buf = NULL; struct pack_idx_entry **idx_objects; unsigned char sha1[20]; git_config(git_index_pack_config, NULL); for (i = 1; i < argc; i++) { char *arg = argv[i]; if (*arg == '-') { if (!strcmp(arg, "--stdin")) { from_stdin = 1; } else if (!strcmp(arg, "--fix-thin")) { fix_thin_pack = 1; } else if (!strcmp(arg, "--strict")) { strict = 1; } else if (!strcmp(arg, "--keep")) { keep_msg = ""; } else if (!prefixcmp(arg, "--keep=")) { keep_msg = arg + 7; } else if (!prefixcmp(arg, "--pack_header=")) { struct pack_header *hdr; char *c; hdr = (struct pack_header *)input_buffer; hdr->hdr_signature = htonl(PACK_SIGNATURE); hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10)); if (*c != ',') die("bad %s", arg); hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10)); if (*c) die("bad %s", arg); input_len = sizeof(*hdr); } else if (!strcmp(arg, "-v")) { verbose = 1; } else if (!strcmp(arg, "-o")) { if (index_name || (i+1) >= argc) usage(index_pack_usage); index_name = argv[++i]; } else if (!prefixcmp(arg, "--index-version=")) { char *c; pack_idx_default_version = strtoul(arg + 16, &c, 10); if (pack_idx_default_version > 2) die("bad %s", arg); if (*c == ',') pack_idx_off32_limit = strtoul(c+1, &c, 0); if (*c || pack_idx_off32_limit & 0x80000000) die("bad %s", arg); } else usage(index_pack_usage); continue; } if (pack_name) usage(index_pack_usage); pack_name = arg; } if (!pack_name && !from_stdin) usage(index_pack_usage); if (fix_thin_pack && !from_stdin) die("--fix-thin cannot be used without --stdin"); if (!index_name && pack_name) { int len = strlen(pack_name); if (!has_extension(pack_name, ".pack")) die("packfile name '%s' does not end with '.pack'", pack_name); index_name_buf = xmalloc(len); memcpy(index_name_buf, pack_name, len - 5); strcpy(index_name_buf + len - 5, ".idx"); index_name = index_name_buf; } if (keep_msg && !keep_name && pack_name) { int len = strlen(pack_name); if (!has_extension(pack_name, ".pack")) die("packfile name '%s' does not end with '.pack'", pack_name); keep_name_buf = xmalloc(len); memcpy(keep_name_buf, pack_name, len - 5); strcpy(keep_name_buf + len - 5, ".keep"); keep_name = keep_name_buf; } curr_pack = open_pack_file(pack_name); parse_pack_header(); objects = xmalloc((nr_objects + 1) * sizeof(struct object_entry)); deltas = xmalloc(nr_objects * sizeof(struct delta_entry)); parse_pack_objects(sha1); if (nr_deltas == nr_resolved_deltas) { stop_progress(&progress); /* Flush remaining pack final 20-byte SHA1. */ flush(); } else { if (fix_thin_pack) { char msg[48]; int nr_unresolved = nr_deltas - nr_resolved_deltas; int nr_objects_initial = nr_objects; if (nr_unresolved <= 0) die("confusion beyond insanity"); objects = xrealloc(objects, (nr_objects + nr_unresolved + 1) * sizeof(*objects)); fix_unresolved_deltas(nr_unresolved); sprintf(msg, "completed with %d local objects", nr_objects - nr_objects_initial); stop_progress_msg(&progress, msg); fixup_pack_header_footer(output_fd, sha1, curr_pack, nr_objects); } if (nr_deltas != nr_resolved_deltas) die("pack has %d unresolved deltas", nr_deltas - nr_resolved_deltas); } free(deltas); if (strict) check_objects(); idx_objects = xmalloc((nr_objects) * sizeof(struct pack_idx_entry *)); for (i = 0; i < nr_objects; i++) idx_objects[i] = &objects[i].idx; curr_index = write_idx_file(index_name, idx_objects, nr_objects, sha1); free(idx_objects); final(pack_name, curr_pack, index_name, curr_index, keep_name, keep_msg, sha1); free(objects); free(index_name_buf); free(keep_name_buf); if (pack_name == NULL) free(curr_pack); if (index_name == NULL) free(curr_index); return 0; } [-- Attachment #1.3: trace.3429 --] [-- Type: text/plain, Size: 8992 bytes --] ==3429== Memcheck, a memory error detector. ==3429== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==3429== Using LibVEX rev 1854, a library for dynamic binary translation. ==3429== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==3429== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation framework. ==3429== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==3429== For more details, rerun with: -v ==3429== ==3429== My PID = 3429, parent PID = 3421. Prog and args are: ==3429== /home/madcoder/dev/scm/git/git-index-pack2 ==3429== --stdin ==3429== -v ==3429== --fix-thin ==3429== --keep=fetch-pack 3421 on artemis ==3429== --pack_header=2,263 ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x5068AF9: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x5068B26: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x5068B86: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x5068B97: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x5068BD9: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Use of uninitialised value of size 8 ==3429== at 0x5068C2A: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x5068C8F: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x5068C98: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Use of uninitialised value of size 8 ==3429== at 0x5068E21: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Use of uninitialised value of size 8 ==3429== at 0x5068E31: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x50689AC: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x5066933: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x5068E57: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x5068E64: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x5068E76: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x506B361: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x5068EAC: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Use of uninitialised value of size 8 ==3429== at 0x5069CDB: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506B7B0: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x5068EAC: (within /usr/lib/libz.so.1.2.3.3) ==3429== by 0x506728C: deflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x404BD9: main (index-pack.c:674) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x4035EE: get_base_data (index-pack.c:485) ==3429== by 0x403687: get_base_data (index-pack.c:486) ==3429== by 0x403711: resolve_delta (index-pack.c:516) ==3429== by 0x4038A8: resolve_delta (index-pack.c:543) ==3429== by 0x404CF5: main (index-pack.c:762) ==3429== ==3429== Syscall param pread64(count) contains uninitialised byte(s) ==3429== at 0x5621353: __pread_nocancel (in /usr/lib/debug/libpthread-2.7.so) ==3429== by 0x4034C9: get_data_from_pack (index-pack.c:368) ==3429== by 0x4035FB: get_base_data (index-pack.c:496) ==3429== by 0x403687: get_base_data (index-pack.c:486) ==3429== by 0x403711: resolve_delta (index-pack.c:516) ==3429== by 0x4038A8: resolve_delta (index-pack.c:543) ==3429== by 0x404CF5: main (index-pack.c:762) ==3429== ==3429== Syscall param pread64(offset) contains uninitialised byte(s) ==3429== at 0x5621353: __pread_nocancel (in /usr/lib/debug/libpthread-2.7.so) ==3429== by 0x4034C9: get_data_from_pack (index-pack.c:368) ==3429== by 0x4035FB: get_base_data (index-pack.c:496) ==3429== by 0x403687: get_base_data (index-pack.c:486) ==3429== by 0x403711: resolve_delta (index-pack.c:516) ==3429== by 0x4038A8: resolve_delta (index-pack.c:543) ==3429== by 0x404CF5: main (index-pack.c:762) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x4034D9: get_data_from_pack (index-pack.c:372) ==3429== by 0x4035FB: get_base_data (index-pack.c:496) ==3429== by 0x403687: get_base_data (index-pack.c:486) ==3429== by 0x403711: resolve_delta (index-pack.c:516) ==3429== by 0x4038A8: resolve_delta (index-pack.c:543) ==3429== by 0x404CF5: main (index-pack.c:762) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x506D058: inflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x40352C: get_data_from_pack (index-pack.c:380) ==3429== by 0x4035FB: get_base_data (index-pack.c:496) ==3429== by 0x403687: get_base_data (index-pack.c:486) ==3429== by 0x403711: resolve_delta (index-pack.c:516) ==3429== by 0x4038A8: resolve_delta (index-pack.c:543) ==3429== by 0x404CF5: main (index-pack.c:762) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x506C597: inflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x40352C: get_data_from_pack (index-pack.c:380) ==3429== by 0x4035FB: get_base_data (index-pack.c:496) ==3429== by 0x403687: get_base_data (index-pack.c:486) ==3429== by 0x403711: resolve_delta (index-pack.c:516) ==3429== by 0x4038A8: resolve_delta (index-pack.c:543) ==3429== by 0x404CF5: main (index-pack.c:762) ==3429== ==3429== Conditional jump or move depends on uninitialised value(s) ==3429== at 0x506C5E9: inflate (in /usr/lib/libz.so.1.2.3.3) ==3429== by 0x40352C: get_data_from_pack (index-pack.c:380) ==3429== by 0x4035FB: get_base_data (index-pack.c:496) ==3429== by 0x403687: get_base_data (index-pack.c:486) ==3429== by 0x403711: resolve_delta (index-pack.c:516) ==3429== by 0x4038A8: resolve_delta (index-pack.c:543) ==3429== by 0x404CF5: main (index-pack.c:762) ==3429== ==3429== ERROR SUMMARY: 146 errors from 23 contexts (suppressed: 8 from 1) ==3429== malloc/free: in use at exit: 50,109 bytes in 17 blocks. ==3429== malloc/free: 1,223 allocs, 1,206 frees, 18,574,785 bytes allocated. ==3429== For counts of detected errors, rerun with: -v ==3429== searching for pointers to 17 not-freed blocks. ==3429== checked 618,664 bytes. ==3429== ==3429== LEAK SUMMARY: ==3429== definitely lost: 0 bytes in 0 blocks. ==3429== possibly lost: 8,100 bytes in 1 blocks. ==3429== still reachable: 42,009 bytes in 16 blocks. ==3429== suppressed: 0 bytes in 0 blocks. ==3429== Rerun with --leak-check=full to see details of leaked memory. [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-23 10:14 ` Björn Steinbrink 2008-07-23 10:22 ` Pierre Habouzit 2008-07-23 10:38 ` Pierre Habouzit @ 2008-07-23 10:49 ` Johannes Schindelin 2008-07-23 10:56 ` Björn Steinbrink 2008-07-23 11:19 ` Pierre Habouzit 2 siblings, 2 replies; 24+ messages in thread From: Johannes Schindelin @ 2008-07-23 10:49 UTC (permalink / raw) To: Björn Steinbrink; +Cc: Pierre Habouzit, spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: TEXT/PLAIN, Size: 2463 bytes --] Hi, On Wed, 23 Jul 2008, Björn Steinbrink wrote: > On 2008.07.23 01:17:45 +0200, Pierre Habouzit wrote: > > Hi, here is a manual painful down-secting (opposed to a bisect ;P) I > > did, since git in next cannot fetch on a regular basis for me. The > > culprit seems to be commit 92392b4: > > > > ┌─(1:11)──<~/dev/scm/git 92392b4...>── > > └[artemis] git fetch > > remote: Counting objects: 461, done. > > remote: Compressing objects: 100% (141/141), done. > > remote: Total 263 (delta 227), reused 155 (delta 121) > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > fatal: Out of memory, malloc failed > > fatal: index-pack failed > > [2] 16674 abort (core dumped) git fetch > > > > ┌─(1:12)──<~/dev/scm/git 92392b4...>── > > └[artemis] git checkout -m HEAD~1; make git-index-pack > > Previous HEAD position was 92392b4... index-pack: Honor core.deltaBaseCacheLimit when resolving deltas > > HEAD is now at 03993e1... index-pack: Track the object_entry that creates each base_data > > GIT_VERSION = 1.5.6.3.3.g03993 > > CC index-pack.o > > LINK git-index-pack > > > > ┌─(1:12)──<~/dev/scm/git 03993e1...>── > > └[artemis] git fetch > > remote: Counting objects: 461, done. > > remote: Compressing objects: 100% (141/141), done. > > remote: Total 263 (delta 227), reused 155 (delta 121) > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > Resolving deltas: 100% (227/227), completed with 153 local objects. > > From git://git.kernel.org/pub/scm/git/git > > 5ba2c22..0868a30 html -> origin/html > > 2857e17..abeeabe man -> origin/man > > 93310a4..95f8ebb master -> origin/master > > 559998f..e8bf351 next -> origin/next > > > > You can see the commit sha's in the prompt. 03993e1 is fine, 92392b4 is > > broken, I've absolutely no clue about what happens. > > > > All I can say is that at some point in get_data_from_pack, obj[1].idx > > points to something that is *not* a sha so it's probably corrupted. > > (from index-pack.c). > > Here's how to reproduce: Funny. That does not reproduce the bug here at all. But then, it is unsurprising, since both Pierre and me did something similar yesterday, fetching _just_ the pre-fetch refs into a freshly initted Git repository, and then fetching from kernel.org. Tested on x86_64. Ciao, Dscho ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-23 10:49 ` Johannes Schindelin @ 2008-07-23 10:56 ` Björn Steinbrink 2008-07-23 11:19 ` Pierre Habouzit 1 sibling, 0 replies; 24+ messages in thread From: Björn Steinbrink @ 2008-07-23 10:56 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Pierre Habouzit, spearce, Git ML, Junio C Hamano On 2008.07.23 12:49:04 +0200, Johannes Schindelin wrote: > Hi, > > On Wed, 23 Jul 2008, Björn Steinbrink wrote: > > > On 2008.07.23 01:17:45 +0200, Pierre Habouzit wrote: > > > Hi, here is a manual painful down-secting (opposed to a bisect ;P) I > > > did, since git in next cannot fetch on a regular basis for me. The > > > culprit seems to be commit 92392b4: > > > > > > ┌─(1:11)──<~/dev/scm/git 92392b4...>── > > > └[artemis] git fetch > > > remote: Counting objects: 461, done. > > > remote: Compressing objects: 100% (141/141), done. > > > remote: Total 263 (delta 227), reused 155 (delta 121) > > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > > fatal: Out of memory, malloc failed > > > fatal: index-pack failed > > > [2] 16674 abort (core dumped) git fetch > > > > > > ┌─(1:12)──<~/dev/scm/git 92392b4...>── > > > └[artemis] git checkout -m HEAD~1; make git-index-pack > > > Previous HEAD position was 92392b4... index-pack: Honor core.deltaBaseCacheLimit when resolving deltas > > > HEAD is now at 03993e1... index-pack: Track the object_entry that creates each base_data > > > GIT_VERSION = 1.5.6.3.3.g03993 > > > CC index-pack.o > > > LINK git-index-pack > > > > > > ┌─(1:12)──<~/dev/scm/git 03993e1...>── > > > └[artemis] git fetch > > > remote: Counting objects: 461, done. > > > remote: Compressing objects: 100% (141/141), done. > > > remote: Total 263 (delta 227), reused 155 (delta 121) > > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > > Resolving deltas: 100% (227/227), completed with 153 local objects. > > > From git://git.kernel.org/pub/scm/git/git > > > 5ba2c22..0868a30 html -> origin/html > > > 2857e17..abeeabe man -> origin/man > > > 93310a4..95f8ebb master -> origin/master > > > 559998f..e8bf351 next -> origin/next > > > > > > You can see the commit sha's in the prompt. 03993e1 is fine, 92392b4 is > > > broken, I've absolutely no clue about what happens. > > > > > > All I can say is that at some point in get_data_from_pack, obj[1].idx > > > points to something that is *not* a sha so it's probably corrupted. > > > (from index-pack.c). > > > > Here's how to reproduce: > > Funny. That does not reproduce the bug here at all. > > But then, it is unsurprising, since both Pierre and me did something > similar yesterday, fetching _just_ the pre-fetch refs into a freshly > initted Git repository, and then fetching from kernel.org. > > Tested on x86_64. Weird. Same arch here. And it's 100% reproducable so far (around 25 times now, I guess). Björn ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-23 10:49 ` Johannes Schindelin 2008-07-23 10:56 ` Björn Steinbrink @ 2008-07-23 11:19 ` Pierre Habouzit 2008-07-23 11:37 ` Johannes Schindelin 1 sibling, 1 reply; 24+ messages in thread From: Pierre Habouzit @ 2008-07-23 11:19 UTC (permalink / raw) To: Johannes Schindelin Cc: Björn Steinbrink, spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: text/plain, Size: 4057 bytes --] On Wed, Jul 23, 2008 at 10:49:04AM +0000, Johannes Schindelin wrote: > Hi, > > On Wed, 23 Jul 2008, Björn Steinbrink wrote: > > > On 2008.07.23 01:17:45 +0200, Pierre Habouzit wrote: > > > Hi, here is a manual painful down-secting (opposed to a bisect ;P) I > > > did, since git in next cannot fetch on a regular basis for me. The > > > culprit seems to be commit 92392b4: > > > > > > ┌─(1:11)──<~/dev/scm/git 92392b4....>── > > > └[artemis] git fetch > > > remote: Counting objects: 461, done. > > > remote: Compressing objects: 100% (141/141), done. > > > remote: Total 263 (delta 227), reused 155 (delta 121) > > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > > fatal: Out of memory, malloc failed > > > fatal: index-pack failed > > > [2] 16674 abort (core dumped) git fetch > > > > > > ┌─(1:12)──<~/dev/scm/git 92392b4....>── > > > └[artemis] git checkout -m HEAD~1; make git-index-pack > > > Previous HEAD position was 92392b4... index-pack: Honor core.deltaBaseCacheLimit when resolving deltas > > > HEAD is now at 03993e1... index-pack: Track the object_entry that creates each base_data > > > GIT_VERSION = 1.5.6.3.3.g03993 > > > CC index-pack.o > > > LINK git-index-pack > > > > > > ┌─(1:12)──<~/dev/scm/git 03993e1....>── > > > └[artemis] git fetch > > > remote: Counting objects: 461, done. > > > remote: Compressing objects: 100% (141/141), done. > > > remote: Total 263 (delta 227), reused 155 (delta 121) > > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > > Resolving deltas: 100% (227/227), completed with 153 local objects. > > > From git://git.kernel.org/pub/scm/git/git > > > 5ba2c22..0868a30 html -> origin/html > > > 2857e17..abeeabe man -> origin/man > > > 93310a4..95f8ebb master -> origin/master > > > 559998f..e8bf351 next -> origin/next > > > > > > You can see the commit sha's in the prompt. 03993e1 is fine, 92392b4 is > > > broken, I've absolutely no clue about what happens. > > > > > > All I can say is that at some point in get_data_from_pack, obj[1].idx > > > points to something that is *not* a sha so it's probably corrupted. > > > (from index-pack.c). > > > > Here's how to reproduce: > > Funny. That does not reproduce the bug here at all. > > But then, it is unsurprising, since both Pierre and me did something > similar yesterday, fetching _just_ the pre-fetch refs into a freshly > initted Git repository, and then fetching from kernel.org. > > Tested on x86_64. I can reproduce on x86_64 here. And I think I get the problem, and IMHO the pruning thing is flawed. We need more than *one* base to be kept at a time, pruning is too aggressive, and we still keep pointers to actually pruned data. This patch makes the issue non reproducible for me. The rationale is that get_base_data will already prune and is called as often, and in safer places. ================================= diff --git a/index-pack.c b/index-pack.c index ac20a46..5440e43 100644 --- a/index-pack.c +++ b/index-pack.c @@ -245,7 +245,6 @@ static void link_base_data(struct base_data *base, struct base_data *c) c->base = base; c->child = NULL; base_cache_used += c->size; - prune_base_data(c); } static void unlink_base_data(struct base_data *c) ================================= *But* I'm absolutely not sure it's enough. This should be written using reference counting instead of the "retain" hack, and prune should not free() anything that isn't with a 0 reference counter. The current code is brittle, it makes my head explode when I try to understand if the get_base_data() we temporarily keep pointers too may be harmed or not. -- ·O· Pierre Habouzit ··O madcoder@debian.org OOO http://www.madism.org [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-23 11:19 ` Pierre Habouzit @ 2008-07-23 11:37 ` Johannes Schindelin 2008-07-23 11:50 ` Pierre Habouzit 2008-07-23 12:00 ` Björn Steinbrink 0 siblings, 2 replies; 24+ messages in thread From: Johannes Schindelin @ 2008-07-23 11:37 UTC (permalink / raw) To: Pierre Habouzit; +Cc: Björn Steinbrink, spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: TEXT/PLAIN, Size: 3148 bytes --] Hi, On Wed, 23 Jul 2008, Pierre Habouzit wrote: > On Wed, Jul 23, 2008 at 10:49:04AM +0000, Johannes Schindelin wrote: > > > On Wed, 23 Jul 2008, Björn Steinbrink wrote: > > > > > On 2008.07.23 01:17:45 +0200, Pierre Habouzit wrote: > > > > Hi, here is a manual painful down-secting (opposed to a bisect ;P) I > > > > did, since git in next cannot fetch on a regular basis for me. The > > > > culprit seems to be commit 92392b4: > > > > > > > > ┌─(1:11)──<~/dev/scm/git 92392b4....>── > > > > └[artemis] git fetch > > > > remote: Counting objects: 461, done. > > > > remote: Compressing objects: 100% (141/141), done. > > > > remote: Total 263 (delta 227), reused 155 (delta 121) > > > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > > > fatal: Out of memory, malloc failed > > > > fatal: index-pack failed > > > > [2] 16674 abort (core dumped) git fetch > > > > > > > > ┌─(1:12)──<~/dev/scm/git 92392b4....>── > > > > └[artemis] git checkout -m HEAD~1; make git-index-pack > > > > Previous HEAD position was 92392b4... index-pack: Honor core.deltaBaseCacheLimit when resolving deltas > > > > HEAD is now at 03993e1... index-pack: Track the object_entry that creates each base_data > > > > GIT_VERSION = 1.5.6.3.3.g03993 > > > > CC index-pack.o > > > > LINK git-index-pack > > > > > > > > ┌─(1:12)──<~/dev/scm/git 03993e1....>── > > > > └[artemis] git fetch > > > > remote: Counting objects: 461, done. > > > > remote: Compressing objects: 100% (141/141), done. > > > > remote: Total 263 (delta 227), reused 155 (delta 121) > > > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > > > Resolving deltas: 100% (227/227), completed with 153 local objects. > > > > From git://git.kernel.org/pub/scm/git/git > > > > 5ba2c22..0868a30 html -> origin/html > > > > 2857e17..abeeabe man -> origin/man > > > > 93310a4..95f8ebb master -> origin/master > > > > 559998f..e8bf351 next -> origin/next > > > > > > > > You can see the commit sha's in the prompt. 03993e1 is fine, 92392b4 is > > > > broken, I've absolutely no clue about what happens. > > > > > > > > All I can say is that at some point in get_data_from_pack, obj[1].idx > > > > points to something that is *not* a sha so it's probably corrupted. > > > > (from index-pack.c). > > > > > > Here's how to reproduce: > > > > Funny. That does not reproduce the bug here at all. > > > > But then, it is unsurprising, since both Pierre and me did something > > similar yesterday, fetching _just_ the pre-fetch refs into a freshly > > initted Git repository, and then fetching from kernel.org. > > > > Tested on x86_64. > > I can reproduce on x86_64 here. Well, I cannot. However, I get some pread issue on i686. To be nice to kernel.org, I downloaded the pack in question: http://pacific.mpi-cbg.de/git/thin-pack.pack You should be able to reproduce the behavior by piping this into git-index-pack --stdin -v --fix-thin --keep=fetch-pack --pack_header=2,263 Hth, Dscho ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-23 11:37 ` Johannes Schindelin @ 2008-07-23 11:50 ` Pierre Habouzit 2008-07-23 12:00 ` Björn Steinbrink 1 sibling, 0 replies; 24+ messages in thread From: Pierre Habouzit @ 2008-07-23 11:50 UTC (permalink / raw) To: Johannes Schindelin Cc: Björn Steinbrink, spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: text/plain, Size: 1438 bytes --] On Wed, Jul 23, 2008 at 11:37:00AM +0000, Johannes Schindelin wrote: > Hi, > > On Wed, 23 Jul 2008, Pierre Habouzit wrote: > > > On Wed, Jul 23, 2008 at 10:49:04AM +0000, Johannes Schindelin wrote: > > > > > On Wed, 23 Jul 2008, Björn Steinbrink wrote: > > > Funny. That does not reproduce the bug here at all. > > > > > > But then, it is unsurprising, since both Pierre and me did something > > > similar yesterday, fetching _just_ the pre-fetch refs into a freshly > > > initted Git repository, and then fetching from kernel.org. > > > > > > Tested on x86_64. > > > > I can reproduce on x86_64 here. > > Well, I cannot. However, I get some pread issue on i686. To be nice to > kernel.org, I downloaded the pack in question: > > http://pacific.mpi-cbg.de/git/thin-pack.pack > > You should be able to reproduce the behavior by piping this into > > git-index-pack --stdin -v --fix-thin --keep=fetch-pack --pack_header=2,263 I can reproduce. Funily enough, I just happened to see that I have core.deltabasecachelimit = 0 in my git.git repository... which I probably used meaning -1 but oh well. The bottom line is that the pruning algorithm likely removes a pointer we still have a pointer to somewhere... -- ·O· Pierre Habouzit ··O madcoder@debian.org OOO http://www.madism.org [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: regression in 92392b4 2008-07-23 11:37 ` Johannes Schindelin 2008-07-23 11:50 ` Pierre Habouzit @ 2008-07-23 12:00 ` Björn Steinbrink 2008-07-23 12:11 ` [PATCH] index-pack: never prune base_cache Pierre Habouzit 1 sibling, 1 reply; 24+ messages in thread From: Björn Steinbrink @ 2008-07-23 12:00 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Pierre Habouzit, spearce, Git ML, Junio C Hamano On 2008.07.23 12:37:00 +0100, Johannes Schindelin wrote: > Hi, > > On Wed, 23 Jul 2008, Pierre Habouzit wrote: > > > On Wed, Jul 23, 2008 at 10:49:04AM +0000, Johannes Schindelin wrote: > > > > > On Wed, 23 Jul 2008, Björn Steinbrink wrote: > > > > > > > On 2008.07.23 01:17:45 +0200, Pierre Habouzit wrote: > > > > > Hi, here is a manual painful down-secting (opposed to a bisect ;P) I > > > > > did, since git in next cannot fetch on a regular basis for me. The > > > > > culprit seems to be commit 92392b4: > > > > > > > > > > ┌─(1:11)──<~/dev/scm/git 92392b4....>── > > > > > └[artemis] git fetch > > > > > remote: Counting objects: 461, done. > > > > > remote: Compressing objects: 100% (141/141), done. > > > > > remote: Total 263 (delta 227), reused 155 (delta 121) > > > > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > > > > fatal: Out of memory, malloc failed > > > > > fatal: index-pack failed > > > > > [2] 16674 abort (core dumped) git fetch > > > > > > > > > > ┌─(1:12)──<~/dev/scm/git 92392b4....>── > > > > > └[artemis] git checkout -m HEAD~1; make git-index-pack > > > > > Previous HEAD position was 92392b4... index-pack: Honor core.deltaBaseCacheLimit when resolving deltas > > > > > HEAD is now at 03993e1... index-pack: Track the object_entry that creates each base_data > > > > > GIT_VERSION = 1.5.6.3.3.g03993 > > > > > CC index-pack.o > > > > > LINK git-index-pack > > > > > > > > > > ┌─(1:12)──<~/dev/scm/git 03993e1....>── > > > > > └[artemis] git fetch > > > > > remote: Counting objects: 461, done. > > > > > remote: Compressing objects: 100% (141/141), done. > > > > > remote: Total 263 (delta 227), reused 155 (delta 121) > > > > > Receiving objects: 100% (263/263), 95.55 KiB, done. > > > > > Resolving deltas: 100% (227/227), completed with 153 local objects. > > > > > From git://git.kernel.org/pub/scm/git/git > > > > > 5ba2c22..0868a30 html -> origin/html > > > > > 2857e17..abeeabe man -> origin/man > > > > > 93310a4..95f8ebb master -> origin/master > > > > > 559998f..e8bf351 next -> origin/next > > > > > > > > > > You can see the commit sha's in the prompt. 03993e1 is fine, 92392b4 is > > > > > broken, I've absolutely no clue about what happens. > > > > > > > > > > All I can say is that at some point in get_data_from_pack, obj[1].idx > > > > > points to something that is *not* a sha so it's probably corrupted. > > > > > (from index-pack.c). > > > > > > > > Here's how to reproduce: > > > > > > Funny. That does not reproduce the bug here at all. > > > > > > But then, it is unsurprising, since both Pierre and me did something > > > similar yesterday, fetching _just_ the pre-fetch refs into a freshly > > > initted Git repository, and then fetching from kernel.org. > > > > > > Tested on x86_64. > > > > I can reproduce on x86_64 here. > > Well, I cannot. However, I get some pread issue on i686. To be nice to > kernel.org, I downloaded the pack in question: > > http://pacific.mpi-cbg.de/git/thin-pack.pack > > You should be able to reproduce the behavior by piping this into > > git-index-pack --stdin -v --fix-thin --keep=fetch-pack --pack_header=2,263 OK, that gave me a seemingly sane backtrace. What seems to happen (AFA my limited knowledge tells me): In fix_unresolved_deltas, we read base_obj from an existing pack, other than the one we're reading. We then link that object to the base cache. Then in resolve_delta, we create the "result" base_data object and link that one, too. Now this triggers the pruning, and because the cache is so small, we prune the object that we read from the existing pack! Fast forward a few function calls, we end up in get_base_data trying to re-read the data for that object, but this time from the pack that we got on stdin. And boom it goes. Does that make any sense to you? Björn ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] index-pack: never prune base_cache. 2008-07-23 12:00 ` Björn Steinbrink @ 2008-07-23 12:11 ` Pierre Habouzit 2008-07-23 12:52 ` Björn Steinbrink 0 siblings, 1 reply; 24+ messages in thread From: Pierre Habouzit @ 2008-07-23 12:11 UTC (permalink / raw) To: Björn Steinbrink Cc: Johannes Schindelin, spearce, Git ML, Junio C Hamano It may belong to something (stdin) that is consumed. Signed-off-by: Pierre Habouzit <madcoder@debian.org> --- On Wed, Jul 23, 2008 at 12:00:45PM +0000, Björn Steinbrink wrote: > On 2008.07.23 12:37:00 +0100, Johannes Schindelin wrote: > > Hi, > > > > Well, I cannot. However, I get some pread issue on i686. To be nice to > > kernel.org, I downloaded the pack in question: > > > > http://pacific.mpi-cbg.de/git/thin-pack.pack > > > > You should be able to reproduce the behavior by piping this into > > > > git-index-pack --stdin -v --fix-thin --keep=fetch-pack --pack_header=2,263 > > OK, that gave me a seemingly sane backtrace. What seems to happen (AFA > my limited knowledge tells me): > > In fix_unresolved_deltas, we read base_obj from an existing pack, other > than the one we're reading. We then link that object to the base cache. > > Then in resolve_delta, we create the "result" base_data object and link > that one, too. Now this triggers the pruning, and because the cache is > so small, we prune the object that we read from the existing pack! Fast > forward a few function calls, we end up in get_base_data trying to > re-read the data for that object, but this time from the pack that we > got on stdin. And boom it goes. > > Does that make any sense to you? Yes, that's obvious, the pack that we read from stdin is consumed, we should *NEVER* prune base_cache. And indeed that little patch works for me. index-pack.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/index-pack.c b/index-pack.c index ac20a46..eb81ed4 100644 --- a/index-pack.c +++ b/index-pack.c @@ -227,7 +227,7 @@ static void prune_base_data(struct base_data *retain) for (b = base_cache; base_cache_used > delta_base_cache_limit && b; b = b->child) { - if (b->data && b != retain) { + if (b != base_cache && b->data && b != retain) { free(b->data); b->data = NULL; base_cache_used -= b->size; -- 1.6.0.rc0.155.ga0442.dirty ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH] index-pack: never prune base_cache. 2008-07-23 12:11 ` [PATCH] index-pack: never prune base_cache Pierre Habouzit @ 2008-07-23 12:52 ` Björn Steinbrink 2008-07-23 13:09 ` Johannes Schindelin 0 siblings, 1 reply; 24+ messages in thread From: Björn Steinbrink @ 2008-07-23 12:52 UTC (permalink / raw) To: Pierre Habouzit, Johannes Schindelin, spearce, Git ML, Junio C Hamano On 2008.07.23 14:11:18 +0200, Pierre Habouzit wrote: > It may belong to something (stdin) that is consumed. Probably thanks to me, babbling about stdin without having a clue what I'm talking about, that rationale is wrong. We may not prune base_cache since that object might come from a different pack than the one that we are processing. In such a case, we would try to restore the data for that object from the pack we're processing and fail miserably. The patch itself should be fine. > > Signed-off-by: Pierre Habouzit <madcoder@debian.org> > --- > > On Wed, Jul 23, 2008 at 12:00:45PM +0000, Björn Steinbrink wrote: > > On 2008.07.23 12:37:00 +0100, Johannes Schindelin wrote: > > > Hi, > > > > > > Well, I cannot. However, I get some pread issue on i686. To be nice to > > > kernel.org, I downloaded the pack in question: > > > > > > http://pacific.mpi-cbg.de/git/thin-pack.pack > > > > > > You should be able to reproduce the behavior by piping this into > > > > > > git-index-pack --stdin -v --fix-thin --keep=fetch-pack --pack_header=2,263 > > > > OK, that gave me a seemingly sane backtrace. What seems to happen (AFA > > my limited knowledge tells me): > > > > In fix_unresolved_deltas, we read base_obj from an existing pack, other > > than the one we're reading. We then link that object to the base cache. > > > > Then in resolve_delta, we create the "result" base_data object and link > > that one, too. Now this triggers the pruning, and because the cache is > > so small, we prune the object that we read from the existing pack! Fast > > forward a few function calls, we end up in get_base_data trying to > > re-read the data for that object, but this time from the pack that we > > got on stdin. And boom it goes. > > > > Does that make any sense to you? > > Yes, that's obvious, the pack that we read from stdin is consumed, we > should *NEVER* prune base_cache. And indeed that little patch works for > me. > > index-pack.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/index-pack.c b/index-pack.c > index ac20a46..eb81ed4 100644 > --- a/index-pack.c > +++ b/index-pack.c > @@ -227,7 +227,7 @@ static void prune_base_data(struct base_data *retain) > for (b = base_cache; > base_cache_used > delta_base_cache_limit && b; > b = b->child) { > - if (b->data && b != retain) { > + if (b != base_cache && b->data && b != retain) { > free(b->data); > b->data = NULL; > base_cache_used -= b->size; ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] index-pack: never prune base_cache. 2008-07-23 12:52 ` Björn Steinbrink @ 2008-07-23 13:09 ` Johannes Schindelin 2008-07-23 13:20 ` Pierre Habouzit 2008-07-23 13:44 ` Björn Steinbrink 0 siblings, 2 replies; 24+ messages in thread From: Johannes Schindelin @ 2008-07-23 13:09 UTC (permalink / raw) To: Björn Steinbrink; +Cc: Pierre Habouzit, spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: TEXT/PLAIN, Size: 1097 bytes --] Hi, On Wed, 23 Jul 2008, Björn Steinbrink wrote: > On 2008.07.23 14:11:18 +0200, Pierre Habouzit wrote: > > It may belong to something (stdin) that is consumed. > > Probably thanks to me, babbling about stdin without having a clue what > I'm talking about, that rationale is wrong. > > We may not prune base_cache since that object might come from a > different pack than the one that we are processing. In such a case, we > would try to restore the data for that object from the pack we're > processing and fail miserably. Then the proper fix would be to load the object from that pack again. > The patch itself should be fine. No, since it opens the whole issue of memory explosion again, the same issue Shawn's original patch tried to fix. Ciao, Dscho P.S.: Could you please, please, please cull the part you are not responding to? This mailing list is read by more than 50 people. If you sum up the time it takes them to realize that that quoted part was irrelevant, I am sure you will end up with a larger number of minutes than it would take you to just delete it. Thanks. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] index-pack: never prune base_cache. 2008-07-23 13:09 ` Johannes Schindelin @ 2008-07-23 13:20 ` Pierre Habouzit 2008-07-23 13:46 ` Johannes Schindelin 2008-07-23 13:44 ` Björn Steinbrink 1 sibling, 1 reply; 24+ messages in thread From: Pierre Habouzit @ 2008-07-23 13:20 UTC (permalink / raw) To: Johannes Schindelin Cc: Björn Steinbrink, spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: text/plain, Size: 1077 bytes --] On Wed, Jul 23, 2008 at 01:09:40PM +0000, Johannes Schindelin wrote: > On Wed, 23 Jul 2008, Björn Steinbrink wrote: > > The patch itself should be fine. > > No, since it opens the whole issue of memory explosion again, the same > issue Shawn's original patch tried to fix. No it won't. Indeed the issue is with fix_unresolved_deltas that sometimes put at the root of the chain (in base_cache) something that comes from our store, not the pack we are writing. Then starts a delta chain resolution. It won't explode in memory at all, we just keep the first data of a delta chain in memory, that's all. It indeed consumes more memory, but we talk about *one* single object per delta chain because we're too lazy to memorize where it comes from. It's probably not much of an explosion. We also waste that object even when it's from our own pack. Well, I'd say "too bad". -- ·O· Pierre Habouzit ··O madcoder@debian.org OOO http://www.madism.org [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] index-pack: never prune base_cache. 2008-07-23 13:20 ` Pierre Habouzit @ 2008-07-23 13:46 ` Johannes Schindelin 0 siblings, 0 replies; 24+ messages in thread From: Johannes Schindelin @ 2008-07-23 13:46 UTC (permalink / raw) To: Pierre Habouzit; +Cc: Björn Steinbrink, spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: TEXT/PLAIN, Size: 1220 bytes --] Hi, On Wed, 23 Jul 2008, Pierre Habouzit wrote: > On Wed, Jul 23, 2008 at 01:09:40PM +0000, Johannes Schindelin wrote: > > On Wed, 23 Jul 2008, Björn Steinbrink wrote: > > > The patch itself should be fine. > > > > No, since it opens the whole issue of memory explosion again, the same > > issue Shawn's original patch tried to fix. > > No it won't. Indeed the issue is with fix_unresolved_deltas that > sometimes put at the root of the chain (in base_cache) something that > comes from our store, not the pack we are writing. Then starts a delta > chain resolution. If it comes from our store, we should have _no_ problem reconstructing the object. > It won't explode in memory at all, we just keep the first data of a > delta chain in memory, that's all. It indeed consumes more memory, but > we talk about *one* single object per delta chain because we're too lazy > to memorize where it comes from. It's probably not much of an explosion. "Probably". > We also waste that object even when it's from our own pack. Well, I'd > say "too bad". And I say it's dirty, and since the pack code traditionally is one of the cleanest parts of Git, coming from Nico, let's not change that, okay? Ciao, Dscho ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] index-pack: never prune base_cache. 2008-07-23 13:09 ` Johannes Schindelin 2008-07-23 13:20 ` Pierre Habouzit @ 2008-07-23 13:44 ` Björn Steinbrink 2008-07-23 14:41 ` Johannes Schindelin 1 sibling, 1 reply; 24+ messages in thread From: Björn Steinbrink @ 2008-07-23 13:44 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Pierre Habouzit, spearce, Git ML, Junio C Hamano On 2008.07.23 14:09:40 +0100, Johannes Schindelin wrote: > Hi, > > On Wed, 23 Jul 2008, Björn Steinbrink wrote: > > > On 2008.07.23 14:11:18 +0200, Pierre Habouzit wrote: > > > It may belong to something (stdin) that is consumed. > > > > Probably thanks to me, babbling about stdin without having a clue what > > I'm talking about, that rationale is wrong. > > > > We may not prune base_cache since that object might come from a > > different pack than the one that we are processing. In such a case, we > > would try to restore the data for that object from the pack we're > > processing and fail miserably. > > Then the proper fix would be to load the object from that pack again. Actually, my analysis was total bullshit. Right after reading the object from the foreign pack, we also call append_obj_to_pack, so we are actually able to reread that object just fine. The real issue seems to be that we just forget to initialize some fields. This patch fixes the issue for me, but I guess it's not quite the right way to do it, pure guesswork. Björn --- diff --git a/index-pack.c b/index-pack.c index ac20a46..33ba8ef 100644 --- a/index-pack.c +++ b/index-pack.c @@ -699,6 +699,9 @@ static struct object_entry *append_obj_to_pack( write_or_die(output_fd, header, n); obj[0].idx.crc32 = crc32(0, Z_NULL, 0); obj[0].idx.crc32 = crc32(obj[0].idx.crc32, header, n); + obj[0].hdr_size = n; + obj[0].type = type; + obj[0].size = size; obj[1].idx.offset = obj[0].idx.offset + n; obj[1].idx.offset += write_compressed(output_fd, buf, size, &obj[0].idx.crc32); hashcpy(obj->idx.sha1, sha1); ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH] index-pack: never prune base_cache. 2008-07-23 13:44 ` Björn Steinbrink @ 2008-07-23 14:41 ` Johannes Schindelin 2008-07-23 15:30 ` Pierre Habouzit 0 siblings, 1 reply; 24+ messages in thread From: Johannes Schindelin @ 2008-07-23 14:41 UTC (permalink / raw) To: Björn Steinbrink; +Cc: Pierre Habouzit, spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: TEXT/PLAIN, Size: 1070 bytes --] Hi, On Wed, 23 Jul 2008, Björn Steinbrink wrote: > diff --git a/index-pack.c b/index-pack.c > index ac20a46..33ba8ef 100644 > --- a/index-pack.c > +++ b/index-pack.c > @@ -699,6 +699,9 @@ static struct object_entry *append_obj_to_pack( > write_or_die(output_fd, header, n); > obj[0].idx.crc32 = crc32(0, Z_NULL, 0); > obj[0].idx.crc32 = crc32(obj[0].idx.crc32, header, n); > + obj[0].hdr_size = n; > + obj[0].type = type; > + obj[0].size = size; > obj[1].idx.offset = obj[0].idx.offset + n; > obj[1].idx.offset += write_compressed(output_fd, buf, size, &obj[0].idx.crc32); > hashcpy(obj->idx.sha1, sha1); I confirm that the issues I saw went away with this patch, and it looks obviously like the correct approach. The only things valgrind is still complaining about (apart from libz, which I will not bother commenting about) are uninitialized parts of the data being written to disk, and a crc over them. Judging from the addresses, those are probably the bytes that are padded for 4- or 8-byte alignment, so they are probably fine. Thanks, Dscho ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] index-pack: never prune base_cache. 2008-07-23 14:41 ` Johannes Schindelin @ 2008-07-23 15:30 ` Pierre Habouzit 0 siblings, 0 replies; 24+ messages in thread From: Pierre Habouzit @ 2008-07-23 15:30 UTC (permalink / raw) To: Johannes Schindelin Cc: Björn Steinbrink, spearce, Git ML, Junio C Hamano [-- Attachment #1: Type: text/plain, Size: 1310 bytes --] On Wed, Jul 23, 2008 at 02:41:14PM +0000, Johannes Schindelin wrote: > Hi, > > On Wed, 23 Jul 2008, Björn Steinbrink wrote: > > > diff --git a/index-pack.c b/index-pack.c > > index ac20a46..33ba8ef 100644 > > --- a/index-pack.c > > +++ b/index-pack.c > > @@ -699,6 +699,9 @@ static struct object_entry *append_obj_to_pack( > > write_or_die(output_fd, header, n); > > obj[0].idx.crc32 = crc32(0, Z_NULL, 0); > > obj[0].idx.crc32 = crc32(obj[0].idx.crc32, header, n); > > + obj[0].hdr_size = n; > > + obj[0].type = type; > > + obj[0].size = size; > > obj[1].idx.offset = obj[0].idx.offset + n; > > obj[1].idx.offset += write_compressed(output_fd, buf, size, &obj[0]..idx.crc32); > > hashcpy(obj->idx.sha1, sha1); > > I confirm that the issues I saw went away with this patch, and it looks > obviously like the correct approach. > > The only things valgrind is still complaining about (apart from libz, > which I will not bother commenting about) are uninitialized parts of the > data being written to disk, and a crc over them. > > Judging from the addresses, those are probably the bytes that are padded > for 4- or 8-byte alignment, so they are probably fine. I confirm this analysis having done the same independently and reached the same conclusions. [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2008-07-23 15:31 UTC | newest] Thread overview: 24+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-07-22 23:17 regression in 92392b4 Pierre Habouzit 2008-07-22 23:34 ` Johannes Schindelin 2008-07-23 0:41 ` Shawn O. Pearce 2008-07-23 0:58 ` Johannes Schindelin 2008-07-23 1:09 ` Pierre Habouzit 2008-07-23 1:20 ` Johannes Schindelin 2008-07-22 23:37 ` Pierre Habouzit 2008-07-23 10:14 ` Björn Steinbrink 2008-07-23 10:22 ` Pierre Habouzit 2008-07-23 10:38 ` Pierre Habouzit 2008-07-23 10:49 ` Johannes Schindelin 2008-07-23 10:56 ` Björn Steinbrink 2008-07-23 11:19 ` Pierre Habouzit 2008-07-23 11:37 ` Johannes Schindelin 2008-07-23 11:50 ` Pierre Habouzit 2008-07-23 12:00 ` Björn Steinbrink 2008-07-23 12:11 ` [PATCH] index-pack: never prune base_cache Pierre Habouzit 2008-07-23 12:52 ` Björn Steinbrink 2008-07-23 13:09 ` Johannes Schindelin 2008-07-23 13:20 ` Pierre Habouzit 2008-07-23 13:46 ` Johannes Schindelin 2008-07-23 13:44 ` Björn Steinbrink 2008-07-23 14:41 ` Johannes Schindelin 2008-07-23 15:30 ` Pierre Habouzit
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox