I think get_varp_scope() is at fault.
/George
---------- Forwarded message ----------
From: George V. Reilly <geo...@reilly.org>
Date: 2008/7/9
Subject: Re: 64-bit support for Windows (Vista)
Note: ":helpgrep libintl" crashes for me when I build with VC9,
but not VC8. I have not had a chance to figure out why,
and it's too late here now for me to try it on Win32.
> An autocmd, selectbuf#BufNew, is calling set cpo&vim. Vim is freeing
> invalid memory for the old value from did_set_string_option. The
> previous value was (probably) set by vim72a\menu.vim.
>
> I think get_varp_scope() is at fault.
Hmm, could it be patch 7.2a.019? No, that only changed something for
non-string options.
--
Some of the well know MS-Windows errors:
ETIME Wrong time, wait a little while
ECRASH Try again...
EDETECT Unable to detect errors
EOVER You lost! Play another game?
ENOCLUE Eh, what did you want?
/// Bram Moolenaar -- Br...@Moolenaar.net -- 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're freeing empty_option, as returned by get_varp(). Look at how
many times 0x1`4035cffa recurs below.
Callstack from WinDbg:
0:000> kp
Child-SP RetAddr Call Site
00000000`0012ece0 00000001`40153e79 gvimd!free_string_option(unsigned
char * p = 0x00000001`4035cffa "")+0x1d [z:\vimsrc\vim7.2\src\option.c
@ 5171]
00000000`0012ed10 00000001`40069370
gvimd!set_string_option_direct(unsigned char * name =
0x00000001`4031e400 "buftype", int opt_idx = -1, unsigned char * val =
0x00000001`4031e3f4 "help", int opt_flags = 5, int set_sid = 0)+0x129
[z:\vimsrc\vim7.2\src\option.c @ 5312]
00000000`0012ed70 00000001`40170f62 gvimd!do_ecmd(int fnum = 2,
unsigned char * ffname = 0x00000000`00000000 "", unsigned char *
sfname = 0x00000000`00000000 "", struct exarg * eap =
0x00000000`00000000, long newlnum = 1, int flags = 3)+0x950
[z:\vimsrc\vim7.2\src\ex_cmds.c @ 3454]
00000000`0012ee80 00000001`40175b8d gvimd!qf_jump(struct qf_info_S *
qi = 0x00000001`4035ea30, int dir = 0, int errornr = 0, int forceit =
0)+0xc32 [z:\vimsrc\vim7.2\src\quickfix.c @ 1747]
00000000`0012efb0 00000001`4007ed20 gvimd!ex_helpgrep(struct exarg *
eap = 0x00000000`0012f1d0)+0x5ad [z:\vimsrc\vim7.2\src\quickfix.c @
3901]
00000000`0012f140 00000001`4007c074 gvimd!do_one_cmd(unsigned char **
cmdlinep = 0x00000000`0012f330, int sourcing = 0, struct condstack *
cstack = 0x00000000`0012f3e0, <function> * fgetline =
0x00000001`40003508, void * cookie = 0x00000000`00000000)+0x1c60
[z:\vimsrc\vim7.2\src\ex_docmd.c @ 2622]
00000000`0012f2d0 00000001`4013383a gvimd!do_cmdline(unsigned char *
cmdline = 0x00000000`00000000 "", <function> * getline =
0x00000001`40003508, void * cookie = 0x00000000`00000000, int flags =
0)+0x914 [z:\vimsrc\vim7.2\src\ex_docmd.c @ 1099]
00000000`0012f910 00000001`4012c076 gvimd!nv_colon(struct cmdarg_S *
cap = 0x00000000`0012f980)+0xda [z:\vimsrc\vim7.2\src\normal.c @ 5185]
00000000`0012f950 00000001`400d3ac7 gvimd!normal_cmd(struct oparg_S *
oap = 0x00000000`0012faa0, int toplevel = 1)+0x1106
[z:\vimsrc\vim7.2\src\normal.c @ 1160]
00000000`0012fa60 00000001`400d367a gvimd!main_loop(int cmdwin = 0,
int noexmode = 0)+0x407 [z:\vimsrc\vim7.2\src\main.c @ 1180]
00000000`0012fb40 00000001`4022cc2f gvimd!VimMain(void)+0x7ea
[z:\vimsrc\vim7.2\src\main.c @ 940]
00000000`0012fd00 00000001`4025e568 gvimd!WinMain(struct HINSTANCE__ *
hInstance = 0x00000001`40000000, struct HINSTANCE__ * hPrevInst =
0x00000000`00000000, char * lpszCmdLine = 0x00000000`01b56f1c "-u
NONE", int nCmdShow = 10)+0xcf [z:\vimsrc\vim7.2\src\os_w32exe.c @
131]
00000000`0012fe60 00000001`4025e41e
gvimd!__tmainCRTStartup(void)+0x138
[f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c @ 263]
00000000`0012ff30 00000000`7791cdcd gvimd!WinMainCRTStartup(void)+0xe
[f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c @ 182]
00000000`0012ff60 00000000`77b3c6e1 kernel32!BaseThreadInitThunk+0xd
00000000`0012ff90 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
0:000> dt empty_option
gvimd!empty_option
0x00000001`4035cffa ""
0:000> dt curbuf
gvimd!curbuf
0x00000000`053a9d00
+0x000 b_ml : memline
+0x060 b_next : 0x00000000`053da5c0 file_buffer
+0x068 b_prev : 0x00000000`04752d30 file_buffer
+0x070 b_nwindows : 1
+0x074 b_flags : 6
+0x078 b_ffname : 0x00000000`04fc0090
"c:\vimsrc\vim7.2\runtime\doc\mlang.txt"
+0x080 b_sfname : 0x00000000`04fcac20
"c:\vimsrc\vim7.2\runtime\doc\mlang.txt"
+0x088 b_fname : 0x00000000`04fcac20
"c:\vimsrc\vim7.2\runtime\doc\mlang.txt"
+0x1138 b_p_bh : 0x00000001`4035cffa ""
+0x1140 b_p_bt : 0x00000001`4035cffa ""
+0x11b0 b_p_ft : 0x00000001`4035cffa ""
+0x11d8 b_p_def : 0x00000001`4035cffa ""
+0x11e0 b_p_inc : 0x00000001`4035cffa ""
+0x1228 b_p_kp : 0x00000001`4035cffa ""
+0x1290 b_p_syn : 0x00000001`4035cffa ""
+0x12e0 b_p_gp : 0x00000001`4035cffa ""
+0x12e8 b_p_mp : 0x00000001`4035cffa ""
+0x12f0 b_p_efm : 0x00000001`4035cffa ""
+0x12f8 b_p_ep : 0x00000001`4035cffa ""
+0x1300 b_p_path : 0x00000001`4035cffa ""
+0x1310 b_p_tags : 0x00000001`4035cffa ""
+0x1318 b_p_dict : 0x00000001`4035cffa ""
+0x1320 b_p_tsr : 0x00000001`4035cffa ""
+0x14b0 b_p_bexpr : 0x00000001`4035cffa ""
--
/George V. Reilly geo...@reilly.org
http://www.georgevreilly.com/blog http://blogs.cozi.com/tech
> >> An autocmd, selectbuf#BufNew, is calling set cpo&vim. Vim is freeing
> >> invalid memory for the old value from did_set_string_option. The
> >> previous value was (probably) set by vim72a\menu.vim.
> >>
> >> I think get_varp_scope() is at fault.
> >
> > Hmm, could it be patch 7.2a.019? No, that only changed something for
> > non-string options.
>
> You're freeing empty_option, as returned by get_varp(). Look at how
> many times 0x1`4035cffa recurs below.
It's perfectly normal for many options to point to empty_option.
> Callstack from WinDbg:
> 0:000> kp
> Child-SP RetAddr Call Site
> 00000000`0012ece0 00000001`40153e79 gvimd!free_string_option(unsigned
> char * p = 0x00000001`4035cffa "")+0x1d [z:\vimsrc\vim7.2\src\option.c
The free_string_option() function explicitly checks for empty_option.
So where is it that an option value is freed without checking for
empty_option? Or is there a problem with 64-bit in here somewhere?
--
Get a life? What is the URL where it can be downloaded?
Yes, you're right.
I believe I have it this time. ex_helpgrep is setting p_cpo =
(char_u*)"", then that's being free'd as a side-effect of an autocmd
doing "set cpo&vim".
0:000> kp 40
Child-SP RetAddr Call Site
00000000`0012d540 00000001`40156656 gvimd!free_string_option(unsigned
char * p = 0x00000001`4035eba5 "")+0x2b [z:\vimsrc\vim7.2\src\option.c
@ 5173]
00000000`0012d570 00000001`40152bef gvimd!did_set_string_option(int
opt_idx = 53, unsigned char ** varp = 0x00000001`403646f8, int
new_value_alloced = 1, unsigned char * oldval = 0x00000001`4035eba5
"", unsigned char * errbuf = 0x00000000`0012d7b0 "", int opt_flags =
0)+0x25d6 [z:\vimsrc\vim7.2\src\option.c @ 6650]
00000000`0012d730 00000001`4008e4fc gvimd!do_set(unsigned char * arg =
0x00000000`0606764a "m", int opt_flags = 0)+0x1c5f
[z:\vimsrc\vim7.2\src\option.c @ 4647]
00000000`0012d8a0 00000001`4007ed20 gvimd!ex_set(struct exarg * eap =
0x00000000`0012d970)+0x6c [z:\vimsrc\vim7.2\src\ex_docmd.c @ 10880]
00000000`0012d8e0 00000001`4007c074 gvimd!do_one_cmd(unsigned char **
cmdlinep = 0x00000000`0012dad0, int sourcing = 1, struct condstack *
cstack = 0x00000000`0012db80, <function> * fgetline =
0x00000001`40001fdc, void * cookie = 0x00000000`0012e120)+0x1c60
[z:\vimsrc\vim7.2\src\ex_docmd.c @ 2622]
00000000`0012da70 00000001`400785ff gvimd!do_cmdline(unsigned char *
cmdline = 0x00000000`00000000 "", <function> * getline =
0x00000001`40001fdc, void * cookie = 0x00000000`0012e120, int flags =
7)+0x914 [z:\vimsrc\vim7.2\src\ex_docmd.c @ 1099]
00000000`0012e0b0 00000001`40077abd gvimd!do_source(unsigned char *
fname = 0x00000000`06073a60 "C:\gvr\vimfiles\autoload\selectbuf.vim",
int check_other = 0, int is_vimrc = 0)+0x65f
[z:\vimsrc\vim7.2\src\ex_cmds2.c @ 3117]
00000000`0012e190 00000001`40077ceb gvimd!source_callback(unsigned
char * fname = 0x00000000`06073a60
"C:\gvr\vimfiles\autoload\selectbuf.vim", void * cookie =
0x00000000`00000000)+0x1d [z:\vimsrc\vim7.2\src\ex_cmds2.c @ 2559]
00000000`0012e1c0 00000001`40077a95 gvimd!do_in_runtimepath(unsigned
char * name = 0x00000000`05f926f0 "autoload/selectbuf.vim", int all =
0, <function> * callback = 0x00000001`40077aa0, void * cookie =
0x00000000`00000000)+0x21b [z:\vimsrc\vim7.2\src\ex_cmds2.c @ 2653]
00000000`0012e250 00000001`40055df2 gvimd!source_runtime(unsigned char
* name = 0x00000000`05f926f0 "autoload/selectbuf.vim", int all =
0)+0x25 [z:\vimsrc\vim7.2\src\ex_cmds2.c @ 2573]
00000000`0012e280 00000001`4005141a gvimd!script_autoload(unsigned
char * name = 0x00000000`05f92636 "selectbuf#BufNew", int reload =
0)+0x122 [z:\vimsrc\vim7.2\src\eval.c @ 20757]
00000000`0012e2e0 00000001`40051281 gvimd!find_var_in_ht(struct
hashtable_S * ht = 0x00000001`4035a198, unsigned char * varname =
0x00000000`05f92636 "selectbuf#BufNew", int writing = 0)+0x18a
[z:\vimsrc\vim7.2\src\eval.c @ 18732]
00000000`0012e330 00000001`4003e330 gvimd!find_var(unsigned char *
name = 0x00000000`05f92636 "selectbuf#BufNew", struct hashtable_S **
htp = 0x00000000`00000000)+0x71 [z:\vimsrc\vim7.2\src\eval.c @ 18689]
00000000`0012e380 00000001`40054ed3 gvimd!deref_func_name(unsigned
char * name = 0x00000000`05f92636 "selectbuf#BufNew", int * lenp =
0x00000000`0012e450)+0x40 [z:\vimsrc\vim7.2\src\eval.c @ 7779]
00000000`0012e3c0 00000001`40036f74 gvimd!trans_function_name(unsigned
char ** pp = 0x00000000`0012e508, int skip = 0, int flags = 1, struct
funcdict_T * fdp = 0x00000000`0012e528)+0x403
[z:\vimsrc\vim7.2\src\eval.c @ 20314]
00000000`0012e4b0 00000001`4007ed20 gvimd!ex_call(struct exarg * eap =
0x00000000`0012e610)+0x44 [z:\vimsrc\vim7.2\src\eval.c @ 3251]
00000000`0012e580 00000001`4007c074 gvimd!do_one_cmd(unsigned char **
cmdlinep = 0x00000000`0012e770, int sourcing = 1, struct condstack *
cstack = 0x00000000`0012e820, <function> * fgetline =
0x00000001`400b4100, void * cookie = 0x00000000`0012ede0)+0x1c60
[z:\vimsrc\vim7.2\src\ex_docmd.c @ 2622]
00000000`0012e710 00000001`400b3b6a gvimd!do_cmdline(unsigned char *
cmdline = 0x00000000`00000000 "", <function> * getline =
0x00000001`400b4100, void * cookie = 0x00000000`0012ede0, int flags =
7)+0x914 [z:\vimsrc\vim7.2\src\ex_docmd.c @ 1099]
00000000`0012ed50 00000001`400b32ca
gvimd!apply_autocmds_group(auto_event event = EVENT_BUFNEW (1),
unsigned char * fname = 0x00000000`05f7b530
"c:/vimsrc/vim7.2/runtime/doc/mlang.txt", unsigned char * fname_io =
0x00000000`00000000 "", int force = 0, int group = -3, struct
file_buffer * buf = 0x00000000`07373f50, struct exarg * eap =
0x00000000`00000000)+0x66a [z:\vimsrc\vim7.2\src\fileio.c @ 8793]
00000000`0012ee50 00000001`400087dc gvimd!apply_autocmds(auto_event
event = EVENT_BUFNEW (1), unsigned char * fname = 0x00000000`00000000
"", unsigned char * fname_io = 0x00000000`00000000 "", int force = 0,
struct file_buffer * buf = 0x00000000`07373f50)+0x4a
[z:\vimsrc\vim7.2\src\fileio.c @ 8406]
00000000`0012eea0 00000001`4000a2c1 gvimd!buflist_new(unsigned char *
ffname = 0x00000000`0601c5d0 "c:\vimsrc\vim7.2\runtime\doc\mlang.txt",
unsigned char * sfname = 0x00000000`05d940c0
"c:\vimsrc\vim7.2\runtime\doc\mlang.txt", long lnum = 0, int flags =
0)+0x5ac [z:\vimsrc\vim7.2\src\buffer.c @ 1697]
00000000`0012eef0 00000001`4016ffeb gvimd!buflist_add(unsigned char *
fname = 0x00000000`05d940c0 "c:\vimsrc\vim7.2\runtime\doc\mlang.txt",
int flags = 0)+0x21 [z:\vimsrc\vim7.2\src\buffer.c @ 2766]
00000000`0012ef30 00000001`4016f82a gvimd!qf_get_fnum(unsigned char *
directory = 0x00000000`00000000 "", unsigned char * fname =
0x00000000`05d940c0 "c:\vimsrc\vim7.2\runtime\doc\mlang.txt")+0x10b
[z:\vimsrc\vim7.2\src\quickfix.c @ 1204]
00000000`0012ef70 00000001`40175b7c gvimd!qf_add_entry(struct
qf_info_S * qi = 0x00000001`4035ea30, struct qfline_S ** prevp =
0x00000000`0012f0f8, unsigned char * dir = 0x00000000`00000000 "",
unsigned char * fname = 0x00000000`05d940c0
"c:\vimsrc\vim7.2\runtime\doc\mlang.txt", int bufnum = 0, unsigned
char * mesg = 0x00000000`01cff7a0 "already. Otherwise get the
libintl.dll file if you don't have it yet:", long lnum = 95, int col =
29, int vis_col = 0, unsigned char * pattern = 0x00000000`00000000 "",
int nr = 0, int type = 1, int valid = 1)+0x5a
[z:\vimsrc\vim7.2\src\quickfix.c @ 965]
00000000`0012efb0 00000001`4007ed20 gvimd!ex_helpgrep(struct exarg *
eap = 0x00000000`0012f1d0)+0x4ac [z:\vimsrc\vim7.2\src\quickfix.c @
3871]
00000000`0012f140 00000001`4007c074 gvimd!do_one_cmd(unsigned char **
cmdlinep = 0x00000000`0012f330, int sourcing = 0, struct condstack *
cstack = 0x00000000`0012f3e0, <function> * fgetline =
0x00000001`40003508, void * cookie = 0x00000000`00000000)+0x1c60
[z:\vimsrc\vim7.2\src\ex_docmd.c @ 2622]
00000000`0012f2d0 00000001`4013383a gvimd!do_cmdline(unsigned char *
cmdline = 0x00000000`00000000 "", <function> * getline =
0x00000001`40003508, void * cookie = 0x00000000`00000000, int flags =
0)+0x914 [z:\vimsrc\vim7.2\src\ex_docmd.c @ 1099]
00000000`0012f910 00000001`4012c076 gvimd!nv_colon(struct cmdarg_S *
cap = 0x00000000`0012f980)+0xda [z:\vimsrc\vim7.2\src\normal.c @ 5185]
00000000`0012f950 00000001`400d3ac7 gvimd!normal_cmd(struct oparg_S *
oap = 0x00000000`0012faa0, int toplevel = 1)+0x1106
[z:\vimsrc\vim7.2\src\normal.c @ 1160]
00000000`0012fa60 00000001`400d367a gvimd!main_loop(int cmdwin = 0,
int noexmode = 0)+0x407 [z:\vimsrc\vim7.2\src\main.c @ 1180]
00000000`0012fb40 00000001`4022cd4f gvimd!VimMain(void)+0x7ea
[z:\vimsrc\vim7.2\src\main.c @ 940]
00000000`0012fd00 00000001`4025e688 gvimd!WinMain(struct HINSTANCE__ *
hInstance = 0x00000001`40000000, struct HINSTANCE__ * hPrevInst =
0x00000000`00000000, char * lpszCmdLine = 0x00000000`01ac6eb5 "", int
nCmdShow = 10)+0xcf [z:\vimsrc\vim7.2\src\os_w32exe.c @ 131]
00000000`0012fe60 00000001`4025e53e
gvimd!__tmainCRTStartup(void)+0x138
[f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c @ 263]
00000000`0012ff30 00000000`7791cdcd gvimd!WinMainCRTStartup(void)+0xe
[f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c @ 182]
00000000`0012ff60 00000000`77b3c6e1 kernel32!BaseThreadInitThunk+0xd
00000000`0012ff90 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
--
> >> >> An autocmd, selectbuf#BufNew, is calling set cpo&vim. Vim is freeing
> >> >> invalid memory for the old value from did_set_string_option. The
> >> >> previous value was (probably) set by vim72a\menu.vim.
> >> >>
> >> >> I think get_varp_scope() is at fault.
> >> >
> >> > Hmm, could it be patch 7.2a.019? No, that only changed something for
> >> > non-string options.
> >>
> >> You're freeing empty_option, as returned by get_varp(). Look at how
> >> many times 0x1`4035cffa recurs below.
> >
> > It's perfectly normal for many options to point to empty_option.
> >
> >> Callstack from WinDbg:
> >> 0:000> kp
> >> Child-SP RetAddr Call Site
> >> 00000000`0012ece0 00000001`40153e79 gvimd!free_string_option(unsigned
> >> char * p = 0x00000001`4035cffa "")+0x1d [z:\vimsrc\vim7.2\src\option.c
> >
> > The free_string_option() function explicitly checks for empty_option.
> > So where is it that an option value is freed without checking for
> > empty_option? Or is there a problem with 64-bit in here somewhere?
>
> Yes, you're right.
>
> I believe I have it this time. ex_helpgrep is setting p_cpo =
> (char_u*)"", then that's being free'd as a side-effect of an autocmd
> doing "set cpo&vim".
Good catch. String options should never be set to a static string,
unless we are 100% sure nobody can set the option.
I'll change it, also taking care of not restoring the value if it was
changed in the mean time.
I found a couple of other places with a similar problem. Unlikely to
happen, but you never know when someone does weird things.
--
hundred-and-one symptoms of being an internet addict:
232. You start conversations with, "Have you gotten an ISDN line?"
George V. Reilly wrote:Good catch. String options should never be set to a static string,
> I believe I have it this time. ex_helpgrep is setting p_cpo =
> (char_u*)"", then that's being free'd as a side-effect of an autocmd
> doing "set cpo&vim".
unless we are 100% sure nobody can set the option.
I'll change it, also taking care of not restoring the value if it was
changed in the mean time.
I found a couple of other places with a similar problem. Unlikely to
happen, but you never know when someone does weird things.