This patch fixes a bug where the block number and the block index would get out
of sync. Inside putsource() there was code that boiled down to this:
do { if(...) { Change = YES; cp = blockp; } putline(output); } while (blockp != NULL && getrefchar() != '\n'); if (Change == YES) blockp = cp;
It was possible for putline() to read in a new block. The last line could then
reset blockp WITHOUT reloading the old block. This effectively skipped a block's
worth of data resulting in a cscope report with some extra bogus data and some
missing valid data.
This is a very wide-ranging issue, and I'm certain that everybody who uses cscope regularly has hit it at least once. It's a bit of a corner case since a block boundary has to lie in just the right place, so it's not something people would see all the time. Ideally we'd move away from buffers entirely to something like mmap(), but that involves more upheaval that is worthwhile, probably...
Ticket moved from /p/cscope/bugs/286/
I couldn't send a test case earlier because the code in question wasn't mine to
share. But now that I know what to look for, I have a test case from the cscope
codebase itself. This test case revealed a problem with the attached patch. I
will fix this, and send out a new patch. In the meatime, here's the test case:
I checked out the latest cscope sources from CVS on 2013-07-27. (Is there a
repo-wide 'cvs status' command instead of just per-file?) I then made a tiny
change:
Then I built a new cscope index:
Then I ran a cscope query to find all functions called by invmake()
Note that the abcdef() call is missing. Also note that the reported calls
immediately after where the abcdef() call should have been are no longer in the
invmake() function. For instance the fread() call on line 638 is in invopen()
not invmake().
As I said earlier, the patch appears to be flawed. After I apply the patch in
this report, cscope goes into an infinite loop. This patch did work for my
earlier test case, but it's clearly insufficient, and I'll send a new one out
shortly.
OK. Fixed it.
It turned out that my previous fix tickled another bug lurking in
that area of the code.
I was sloppy in the exact codebase I was applying cscope to, and
I can no longer obtain the buggy behavior with the directions
above. Thus I'm doing this again, using the unmodified cscope
15.8a tarball from sourceforge as the source repository to apply
cscope to. To build the index I ran
I'm attaching this index file as well. With this index file and
this source I see the following 3 behaviors:
stock cscope 15.8a
dima@shorty:~/cscope$ cscope -d -L2 loadmenu
src/mouse.c mousereinit 174 mousereinit();
src/mouse.c printf 175 (void ) printf("\033V1");
cscope 15.8a with just the patch above
infinite loop
cscope 15.8a with the two patches in this message
dima@shorty:~/cscope$ cscope -d -L2 loadmenu
src/mouse.c mousereinit 174 mousereinit();
src/mouse.c printf 175 (void ) printf("\033V1");
src/mouse.c printf 176 (void ) printf("\033M0@%s@%s@", menu[0].text, menu[0].value);
src/mouse.c printf 178 (void ) printf("\033M@%s@%s@", menu[i].text, menu[i].value);
src/mouse.c mousecleanup 184 mousecleanup();
src/mouse.c printf 185 (void ) printf("\033[6;1X\033[9;1X");
src/mouse.c strlen 187 len = strlen(menu[i].text);
src/mouse.c printf 188 (void ) printf("\033[%d;%dx%s%s", len,
src/mouse.c strlen 189 (int ) (len + strlen(menu[i].value)),
src/mouse.c fflush 194 (void ) fflush(stdout);
You can confirm that #3 is correct. The bug fixed in the second
patch is described in its commit log (at the top of the patch
file). It's nothing particularly interesting.
dima
Patches