bug-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Partly solved: cvs 1.11.2 dies with "Assertion failed: ptr >= rcs buf_bu


From: Jost Martin
Subject: Partly solved: cvs 1.11.2 dies with "Assertion failed: ptr >= rcs buf_buffer && ptr < rcsbuf_buffer + rcsbuf_buffer_size, file rcs.c, line 1095"
Date: Wed, 27 Nov 2002 18:43:35 +0100

Hello,
[Sorry, it seems this stupid newsreader made a mess of my indentation.]

I'm using
Concurrent Versions System (CVS) 1.11.2 (client/server)
on HPUX 10.20; cvs has been compiled using the HP tools
I'm using cvs with pserver.

This worked for a long time without any problem but now...
I just have checked the newest version of some files in cvs. (and added a
few new files)

Now when I do a 'cvs update', cvs dies with an assertion error:

lasagne:/c/wgl2tab_> cvs update
? GPATH
[...]
? wgl2tab/cae_data/x.tab
cvs server: Updating .
cvs server: Updating common
Assertion failed: ptr >= rcsbuf_buffer && ptr < rcsbuf_buffer +
rcsbuf_buffer_size, file rcs.c, line 1095
cvs [server aborted]: received abort signal

It seems, that 1.11.2 is the newest version.
I tried to use cvs locally (instead of pserver): same problem
cvs happily checks out a fresh copy of the offending directory, but trying
to 'cvs update' this dir blows up cvs as described above.

I think I almost tracked down the problem, but I'm not sure about the fix.

Here is what I found:

I added some debug-code to rcs.c (containing the assertion)
This is the diff from the original rcs.c.:
===========================================================================

diff -c -r1.2 rcs.c
*** rcs.c 2002/11/27 16:42:01 1.2
--- rcs.c 2002/11/27 16:53:59
***************
*** 1091,1096 ****
--- 1091,1099 ----
ptr = rcsbuf->ptr;
ptrend = rcsbuf->ptrend;
+ printf("\nFile=%s\npos= %u\nptr
=0x%X\nrcsbuf_buffer=0x%X\nrcsbuf_buffer_size=%u\n",
+ rcsbuf -> filename, rcsbuf -> pos, ptr, rcsbuf_buffer,
rcsbuf_buffer_size);
+
/* Sanity check. */
assert (ptr >= rcsbuf_buffer && ptr < rcsbuf_buffer + rcsbuf_buffer_size);
***************
*** 1129,1135 ****
ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
if (ptr == NULL)
#endif
! return 0;
#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
--- 1132,1141 ----
ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
if (ptr == NULL)
#endif
! {
! puts("EOF!\n");
! return 0;
! }
#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
***************
*** 1182,1187 ****
--- 1188,1194 ----
{
*valp = NULL;
rcsbuf->ptr = ptr;
+ printf("keyp=%s\tvalp=%s\n", *keyp, (*valp == NULL ? "NULL" : *valp));
return 1;
}
***************
*** 1207,1212 ****
--- 1214,1220 ----
{
*valp = NULL;
rcsbuf->ptr = ptr + 1;
+ printf("keyp=%s\tvalp=%s\n", *keyp, (*valp == NULL ? "NULL" : *valp));
return 1;
}
if (! my_whitespace (c))
***************
*** 1313,1318 ****
--- 1321,1327 ----
if (c != '@')
*valp = NULL;
rcsbuf->ptr = ptr;
+ printf("keyp=%s\tvalp=%s\n", *keyp, (*valp == NULL ? "NULL" : *valp));
return 1;
}
}
***************
*** 1342,1348 ****
{
/* We're done. We already set everything up for this
case above. */
! rcsbuf->ptr = ptr + 1;
return 1;
}
if (! my_whitespace (n))
--- 1351,1358 ----
{
/* We're done. We already set everything up for this
case above. */
! rcsbuf->ptr = ptr + 1;
! printf("keyp=%s\tvalp=%s\n", *keyp, (*valp == NULL ? "NULL" : *valp));
return 1;
}
if (! my_whitespace (n))
***************
*** 1412,1417 ****
--- 1422,1428 ----
*valp = NULL;
rcsbuf->vlen = vlen;
+ printf("keyp=%s\tvalp=%s\n", *keyp, (*valp == NULL ? "NULL" : *valp));
return 1;
}
===========================================================================

I added code to spit out the relevant addresses and sizes and the keywords
and values.

I could track the problem down to one file. This is the end of what I got
from my debug-output for this file
(Please ask me, to have the offending file and/or the complete trace mailed)

File=/home/jost/cvs/common/makefile,v
pos= 0
ptr =0x400328AE
rcsbuf_buffer=0x400308B8
rcsbuf_buffer_size=8192
keyp=branches valp=NULL
File=/home/jost/cvs/common/makefile,v

pos= 0
ptr =0x400328B8
rcsbuf_buffer=0x400308B8
rcsbuf_buffer_size=8192 (== 0x2000)

So ptr == rcsbuf_buffer + rcsbuf_buffer_size => Boom

Why is this - and why seem I to be the first, to be bitten by this ? The
probability seems to be 1/8192, so this should happen fairly often....

IMPORTANT NOTE:
For one reason or another configure regarded mmap() on HPUX 10.20 not worthy
to be used !
So my cvs is compiled with HAVE_MMAP set to false !

I tracked down, where rcsbuf_getkey() is left at the last succeeding call.
This is here: (Line 1185 in the original file)

1171
1172 /* Here *KEYP points to the key in the buffer, C is the character
1173 we found at the of the key, and PTR points to the location in
1174 the buffer where we found C. We must set *PTR to \0 in order
1175 to terminate the key. If the key ended with ';', then there is
1176 no value. */
1177
1178 *ptr = '\0';
1179 ++ptr;
1180
1181 if (c == ';')
1182 {
1183 *valp = NULL;
1184 rcsbuf->ptr = ptr;
1185 return 1;
1186 }
1187
1188 /* C must be whitespace. Skip whitespace between the key and the
1189 value. If we find ';' now, there is no value. */
1190
1191 while (1)
1192 {
1193 if (ptr >= ptrend)
1194 #ifndef HAVE_MMAP
1195 {
1196 ptr = rcsbuf_fill (rcsbuf, ptr, keyp, (char **) NULL);
1197 if (ptr == NULL)
1198 #endif
1199 error (1, 0, "EOF while looking for value in RCS file %s",
1200 rcsbuf->filename);
1201 #ifndef HAVE_MMAP
1202 ptrend = rcsbuf->ptrend;
1203 }
1204 #endif
1205 c = *ptr;
1206 if (c == ';')
1207 {
1208 *valp = NULL;
1209 rcsbuf->ptr = ptr + 1;
1210 return 1;
1211 }
1212 if (! my_whitespace (c))
1213 break;
1214 ++ptr;
1215 }

The terminating ';' of a key/value-pair happened to just sit on the last
char of the buffer. (This - besides the fact, that mmap isn't used-
explains, why the problem happens so rarely)

If you look at the code, in line 1193 the next thing to happen would have
been to check the condition, which - at the next call - fires the assert().
Basically this violates a precondition - the one the assert() formulates.

There is a similar case in line 1210 I think. (I'm not quite sure about the
other return's; the "return 0" surely don't count)

It seems the way to fix this would be to add the check right at the start of
rcsbuf_getkey(), before the values from rcsbuf are read into ptr and ptrend:

if (rcsbuf- ptr >= rcsbuf->ptrend)
#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, rcsbuf->ptr, (char **) NULL, (char **) NULL);
if (ptr == NULL)
#endif
error (1, 0, "EOF while looking for value in RCS file %s",
rcsbuf->filename);
#ifndef HAVE_MMAP
}
#endif

But I'm not sure if this
- Fixes all the cases
- Doesn't have unpleasant side effects

Could someone please confirm this is the way to got (or suggest a better
one) ?

TIA

Martin







reply via email to

[Prev in Thread] Current Thread [Next in Thread]