Hi,

Valgrind memory checker finds use of uninitialized memory in
vim7/src/diff.c when diffing 3 files or more.  I don't see such
errors when diffing 2 files only.

I can reproduce the problem by diffing 3 vim source files for example:

$ cd vim7/src
$ valgrind ./vim -u NONE -U NONE -d syntax.c spell.c screen.c 2> vg.log

(admittedly it does not make much sense to diff those 3 files but
it shows the bug)

==24682== Conditional jump or move depends on uninitialised value(s)
==24682==    at 0x805964D: diff_infold (diff.c:1964)
==24682==    by 0x80C644A: foldlevelDiff (fold.c:2991)
==24682==    by 0x80C5100: foldUpdateIEMS (fold.c:2294)
==24682==    by 0x80C30C5: foldUpdate (fold.c:861)
==24682==    by 0x80C3838: checkupdate (fold.c:1226)
==24682==    by 0x80C220D: hasFoldingWin (fold.c:164)
==24682==    by 0x8058EB8: diff_set_topline (diff.c:1705)
==24682==    by 0x8115178: check_scrollbind (normal.c:3975)
==24682==    by 0x80D7939: main (main.c:903)
==24682==
==24682== Conditional jump or move depends on uninitialised value(s)
==24682==    at 0x805964D: diff_infold (diff.c:1964)
==24682==    by 0x80C644A: foldlevelDiff (fold.c:2991)
==24682==    by 0x80C59D7: foldUpdateIEMSRecurse (fold.c:2644)
==24682==    by 0x80C50CD: foldUpdateIEMS (fold.c:2284)
==24682==    by 0x80C30C5: foldUpdate (fold.c:861)
==24682==    by 0x80C3838: checkupdate (fold.c:1226)
==24682==    by 0x80C220D: hasFoldingWin (fold.c:164)
==24682==    by 0x8058EB8: diff_set_topline (diff.c:1705)
==24682==    by 0x8115178: check_scrollbind (normal.c:3975)
==24682==    by 0x80D7939: main (main.c:903)
(etc, more errors)

When pressing "Pg-down" to scroll down, valgrind reports
more errors in diff.c as well as in fold.c but they may possibly
all have the same root cause).

The first reported error is in src/diff.c at line 1964:

  1961         if (dp->df_lnum[idx] - diff_context > lnum)
  1962             break;
  1963         /* If this change ends before the line we have a match. */
!!1964         if (dp->df_lnum[idx] + dp->df_count[idx] + diff_context > lnum)
  1965             return FALSE;

As a result, I believe function diff_infold(...) may return
TRUE or FALSE at random.

Line 1964 uses several variables so any of them could be the
uninitialized one.  However, variables dp->df_lnum[idx],
diff_context and lnum have been used in a test at line 1961
without error.  So the only variable that must be
uninitialized at line 1964 has to be dp->df_count[idx].

So I've added some printf(...) to see whether df_count[...]
was initialized earlier with something uninitialized.  I
can see that dp->df_count[i] is set with something
uninitialized in diff.c at line 1315 (before valgrind
error is reported at line 1964):

1313   for (i = idx_orig; i < idx_new + !notset; ++i)
1314       if (curtab->tp_diffbuf[i] != NULL)
1315           dp->df_count[i] = dpl->df_lnum[i] + dpl->df_count[i]
1316                                         - dp->df_lnum[i] + off;

Adding printf() shows that variable dpl->df_count[i] (on the right)
is uninitialized at line 1315, so left term dp->df_count[i]
is also uninitialized as a result.

When that happens i == 2, idx_new == 2 and notset is 0 (so !notset is 1).

I have no patch, I could not find more than that yet. It's not clear
to me how this should be initialized.

I'm using vim-7.1.138 built on Linux with:
- configure --with-features=huge
- changed src/Makefile to compile without optimisation (-O0)
- changed src/Makefile to enable PROFILE_CFLAGS = -DEXITFREE

-- Dominique

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Raspunde prin e-mail lui