Dominique Pelle wrote:
> 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
Thanks for analyzing it this far. It's clear that
dpl->df_count[idx_new] is uninitialized when dpl != dp. So why was
there this "+ !notset"? Simply removing it will at least remove the
error for the value being uninitialized:
*** ../vim-7.1.139/src/diff.c Sat Sep 29 14:15:00 2007
--- src/diff.c Sun Oct 14 17:08:25 2007
***************
*** 1310,1316 ****
dp->df_count[idx_new] += -off;
off = 0;
}
! for (i = idx_orig; i < idx_new + !notset; ++i)
if (curtab->tp_diffbuf[i] != NULL)
dp->df_count[i] = dpl->df_lnum[i] + dpl->df_count[i]
- dp->df_lnum[i] + off;
--- 1310,1316 ----
dp->df_count[idx_new] += -off;
off = 0;
}
! for (i = idx_orig; i < idx_new; ++i)
if (curtab->tp_diffbuf[i] != NULL)
dp->df_count[i] = dpl->df_lnum[i] + dpl->df_count[i]
- dp->df_lnum[i] + off;
Now I wonder if something else will fail. Can you provide us with the
three files you were diffing? This is needed to reproduce the bug and
verify that the fix doesn't change what Vim shows. We only need to see
the diffs, thus if it's something that should not be public, you can
change it to all "x" characters, so long as the same differences appear.
--
How To Keep A Healthy Level Of Insanity:
10. Ask people what sex they are. Laugh hysterically after they answer.
/// Bram Moolenaar -- [EMAIL PROTECTED] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---