On Thursday, August 13, 2015 at 5:16:54 PM UTC-4, Dominique Pelle wrote:
> Christian Brabandt wrote:
> 
> > Hi Travis!
> >
> > On Mi, 12 Aug 2015, Travis Lebsock wrote:
> >
> >> I can reproduce the error without any plugins now.
> >>
> >> 1. I run the following command in cmd.
> >>
> >> gvim -u NONE -N -c:"set beval bexpr='foo'"
> >>
> >> 2. Insert some text then hit esc.
> >> 3. Hover mouse over the text.
> >> 4. Once foo bubble shows up I click
> >> 5. Then it crashes
> >
> > Hm, I don't know much about Windows Programming. Debugger shows, an
> > exception is thrown on a WM_LBUTTONDOWN message at gui_win48.c:1951
> > after the call to DispatchMessage()
> >
> > ,----
> > |   1948     if (vk != VK_F10 || check_map(k10, State, FALSE, TRUE, FALSE,
> > |   1949                                                           NULL, 
> > NULL) == NULL)
> > |   1950 #endif
> > |   1951         pDispatchMessage(&msg);
> > |   1952 }
> > `----
> >
> > I don't remember Windows Programming much, so I can't say, what the
> > proper fix would need to be.
> >
> > Perhaps someone more knowledgeable than I can analyze this further.
> 
> 
> I don't have Windows and I'm also not knowledgeable about Windows.
> Maybe someone could build Vim for Windows with those tools
> to chase memory errors:
> 
> http://www.drmemory.org/
> https://code.google.com/p/address-sanitizer/wiki/WindowsPort
> 
> It may help for this issues and other Windows specific issues.
> 
> Regards
> Dominique

I had some time so I took a look at it and I think I have a solution.

The stack trace was pretty scary, as the actual crash was crashing in 
comctl32.dll code:

        comctl32.dll!CToolTipsMgr::GetToolAtPoint()     Unknown
        comctl32.dll!CToolTipsMgr::ToolAtMessagePos(void)       Unknown
        comctl32.dll!CToolTipsMgr::ShowVirtualBubble(void)      Unknown
        comctl32.dll!CToolTipsMgr::HandleRelayedMessage()       Unknown
        comctl32.dll!CToolTipsMgr::ToolTipsWndProc(struct HWND__ *,unsigned 
int,unsigned __int64,__int64)       Unknown
        comctl32.dll!CToolTipsMgr::s_ToolTipsWndProc()  Unknown
        user32.dll!UserCallWinProcCheckWow()    Unknown
        user32.dll!SendMessageWorker()  Unknown
        user32.dll!SendMessageW()       Unknown
        comctl32.dll!CallNextSubclassProc ()    Unknown
        comctl32.dll!MasterSubclassProc()       Unknown
        user32.dll!UserCallWinProcCheckWow()    Unknown
        user32.dll!DispatchMessageWorker()      Unknown
>       gvimd.exe!process_message() Line 1949   C
        gvimd.exe!gui_mch_wait_for_chars(int wtime) Line 2032   C
        gvimd.exe!gui_wait_for_chars(long wtime) Line 2906      C
        gvimd.exe!ui_inchar(unsigned char * buf, int maxlen, long wtime, int 
tb_change_cnt) Line 190    C
        gvimd.exe!inchar(unsigned char * buf, int maxlen, long wait_time, int 
tb_change_cnt) Line 3099  C
        gvimd.exe!vgetorpeek(int advance) Line 2874     C
        gvimd.exe!vgetc(...) Line 1638  C
        gvimd.exe!safe_vgetc(...) Line 1843     C
        gvimd.exe!normal_cmd(oparg_S * oap, int toplevel) Line 641      C
        gvimd.exe!main_loop(int cmdwin, int noexmode) Line 1352 C
        gvimd.exe!VimMain(...) Line 1052        C
        gvimd.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInst, 
char * lpszCmdLine, int nCmdShow) Line 131  C

My assumption from looking at this is that isn't a C error, but a logical error 
of window resource use after free. I assumed that the click caused the crash 
because the internal comctl32.dll code was using it after a user callback 
(Handle_WM_Notify in gui_w32.c) had deleted it (via delete_tooltip). To test 
this assumption, I commented out, the DestroyWindow() call in delete_tooltip. 
This successfully avoids the crash, but now we have a resource leak of windows. 
I can confirm this by hovering and unhovering around 20 times, and you start to 
see a lot of shadowing and lag caused by the stacking windows.

So, looking at the documentation for DestroyWindow() is equivalent to 
SendMessage of WM_DESTROY and WM_NCDESTROY. Since SendMessage is synchronous, 
like DestroyWindow() this probably caused the crash. So, I thought of deferring 
via PostMessage, which adds the window destroy commands to the bottom of the 
message queue, which hopefully will be processed after whatever magic 
comctl32.dll code has ran.

I tried it, and luckily it worked. After hovering around 20 times, I did not 
notice shadowing indicating a resource leak of windows, and could no longer get 
it crash.

Here is the patch:

diff -r 3efc03b7f01b src/gui_w32.c
--- a/src/gui_w32.c     Mon Aug 10 01:38:00 2015 -0400
+++ b/src/gui_w32.c     Thu Aug 13 18:28:14 2015 -0400
@@ -4837,7 +4837,8 @@
 delete_tooltip(beval)
     BalloonEval        *beval;
 {
-    DestroyWindow(beval->balloon);
+    PostMessage(beval->balloon, WM_DESTROY, 0, 0);
+    PostMessage(beval->balloon, WM_NCDESTROY, 0, 0);
 }

 /*ARGSUSED*/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui