[Bug] segfault on closing tab

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[Bug] segfault on closing tab

ryo7000
Hi

gVim crashes when operating as follows.

  gvim -u NONE -U NONE --noplugin --nofork -c "set guifont=Sans\ 10" -
c vnew

  qa
  :tabnew
  :q
  q
  100@a

The cause of the crash is as follows.

* tab_close_othertab
  * win_free_mem
    (A) vim_free(frp)  <- Here, the memory area is freed.
    * win_free
      (B) gui_mch_destroy_scrollbar  <- After this function is called,
frame_minheight() is called from another context.
  (C) remove deleted tabpage from first_tabpage list.

The value might be written in memory area (tp->fr_win) freed in (A)
during the processing of (C) as (A), and frame_minheight() is called
after the function of (B), and it becomes the violation of the memory
by topfrp->fr_win->w_status_height and it crashes in that.

Crash doesn't do easily according to the font, but it seems to be easy
for crash to do comparatively in the Sans font.
It hardly crashes by correcting it as follows.

  vim_free(frp);
  win_free(win, tp);

to

  win_free(win, tp);
  vim_free(frp);

Please fix this bug.

Regards,
ryo7000

--
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Bug] segfault on closing tab

Dominique Pellé
ryo7000 skribis:

> Hi
>
> gVim crashes when operating as follows.
>
>  gvim -u NONE -U NONE --noplugin --nofork -c "set guifont=Sans\ 10" -
> c vnew
>
>  qa
>  :tabnew
>  :q
>  q
>  100@a
>
> The cause of the crash is as follows.
>
> * tab_close_othertab
>  * win_free_mem
>    (A) vim_free(frp)  <- Here, the memory area is freed.
>    * win_free
>      (B) gui_mch_destroy_scrollbar  <- After this function is called,
> frame_minheight() is called from another context.
>  (C) remove deleted tabpage from first_tabpage list.
>
> The value might be written in memory area (tp->fr_win) freed in (A)
> during the processing of (C) as (A), and frame_minheight() is called
> after the function of (B), and it becomes the violation of the memory
> by topfrp->fr_win->w_status_height and it crashes in that.
>
> Crash doesn't do easily according to the font, but it seems to be easy
> for crash to do comparatively in the Sans font.
> It hardly crashes by correcting it as follows.
>
>  vim_free(frp);
>  win_free(win, tp);
>
> to
>
>  win_free(win, tp);
>  vim_free(frp);
>
> Please fix this bug.
>
> Regards,
> ryo7000

Hi

I can reproduce the crash too, both with Vim-7.2.445 and
Vim-7.3a (2293:b9bc9c5df131) gui GTK2 (Linux x86).

When running with Valgrind, after a few minutes, I get the
following errors.  The stack is deep and I had to modify
Valgrind to display the full stack:

==3615== Invalid read of size 4
==3615==    at 0x81C7C9A: frame_minheight (window.c:3040)
==3615==    by 0x81CBDB6: min_rows (window.c:6139)
==3615==    by 0x81B6977: check_shellsize (term.c:3004)
==3615==    by 0x81BA3B5: ui_get_shellsize (ui.c:307)
==3615==    by 0x81B6AE0: set_shellsize (term.c:3099)
==3615==    by 0x81B6A3D: shell_resized (term.c:3043)
==3615==    by 0x81CDD89: gui_resize_shell (gui.c:1313)
==3615==    by 0x81DC02C: form_configure_event (gui_gtk_x11.c:3590)
==3615==    by 0x417A423: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x4746251: g_closure_invoke (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475A99C: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475BC32: g_signal_emit_valist (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x42A7635: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x4173F3B: gtk_main_do_event (in
/usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x81E12CB: gtk_form_send_configure (gui_gtk_f.c:820)
==3615==    by 0x81E07F7: gtk_form_size_allocate (gui_gtk_f.c:458)
==3615==    by 0x4753437: g_cclosure_marshal_VOID__BOXED (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x4746177: g_closure_invoke (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475A239: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475BDB3: g_signal_emit_valist (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x42AC503: gtk_widget_size_allocate (in
/usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x40B4FB5: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x4753437: g_cclosure_marshal_VOID__BOXED (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x4746177: g_closure_invoke (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475A239: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475BDB3: g_signal_emit_valist (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x42AC503: gtk_widget_size_allocate (in
/usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x42BF2ED: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x4753437: g_cclosure_marshal_VOID__BOXED (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x4746251: g_closure_invoke (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475A239: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475BDB3: g_signal_emit_valist (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x42AC503: gtk_widget_size_allocate (in
/usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x42BF767: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x4753DCB: g_cclosure_marshal_VOID__VOID (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x4746251: g_closure_invoke (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475A5E5: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475BDB3: g_signal_emit_valist (in
/usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
==3615==    by 0x40E9709: gtk_container_check_resize (in
/usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x40E975F: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x4429357: ??? (in /usr/lib/libgdk-x11-2.0.so.0.2000.1)
==3615==    by 0x47C8660: ??? (in /lib/libglib-2.0.so.0.2400.1)
==3615==    by 0x47CA5E4: g_main_context_dispatch (in
/lib/libglib-2.0.so.0.2400.1)
==3615==    by 0x47CE2D7: ??? (in /lib/libglib-2.0.so.0.2400.1)
==3615==    by 0x47CE4B7: g_main_context_iteration (in
/lib/libglib-2.0.so.0.2400.1)
==3615==    by 0x41741B2: gtk_main_iteration_do (in
/usr/lib/libgtk-x11-2.0.so.0.2000.1)
==3615==    by 0x81DE9C9: gui_mch_update (gui_gtk_x11.c:5411)
==3615==    by 0x81D448E: gui_mch_destroy_scrollbar (gui_gtk.c:774)
==3615==    by 0x81C96D6: win_free (window.c:4405)
==3615==    by 0x81C6EF3: win_free_mem (window.c:2368)
==3615==    by 0x81C6E20: win_close_othertab (window.c:2328)
==3615==    by 0x81C6A0E: win_close (window.c:2154)
==3615==    by 0x80AD76C: ex_quit (ex_docmd.c:6347)
==3615==    by 0x80A7A00: do_one_cmd (ex_docmd.c:2640)
==3615==    by 0x80A52D9: do_cmdline (ex_docmd.c:1109)
==3615==    by 0x812C680: nv_colon (normal.c:5234)
==3615==    by 0x8125EE3: normal_cmd (normal.c:1188)
==3615==    by 0x80E803C: main_loop (main.c:1252)
==3615==    by 0x80E7A93: main (main.c:960)
==3615==  Address 0x514b050 is 40 bytes inside a block of size 44 free'd
==3615==    at 0x4024B8A: free (vg_replace_malloc.c:366)
==3615==    by 0x8116F0A: vim_free (misc2.c:1702)
==3615==    by 0x81C6EE1: win_free_mem (window.c:2367)
==3615==    by 0x81C6E20: win_close_othertab (window.c:2328)
==3615==    by 0x81C6A0E: win_close (window.c:2154)
==3615==    by 0x80AD76C: ex_quit (ex_docmd.c:6347)
==3615==    by 0x80A7A00: do_one_cmd (ex_docmd.c:2640)
==3615==    by 0x80A52D9: do_cmdline (ex_docmd.c:1109)
==3615==    by 0x812C680: nv_colon (normal.c:5234)
==3615==    by 0x8125EE3: normal_cmd (normal.c:1188)
==3615==    by 0x80E803C: main_loop (main.c:1252)
==3615==    by 0x80E7A93: main (main.c:960)
(more errors afer that)


I came to the same conclusion as you: inverting the 2 lines
windows.c:2367 & window.c:2368 fixes it.

diff -r 2209060c340d src/window.c
--- a/src/window.c Sat Jul 10 17:51:46 2010 +0200
+++ b/src/window.c Sat Jul 10 22:27:30 2010 +0200
@@ -2364,8 +2364,8 @@
     /* Remove the window and its frame from the tree of frames. */
     frp = win->w_frame;
     wp = winframe_remove(win, dirp, tp);
+    win_free(win, tp);
     vim_free(frp);
-    win_free(win, tp);

     /* When deleting the current window of another tab page select a new
      * current window. */


Regards
-- Dominique

--
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Bug] segfault on closing tab

Bram Moolenaar

Dominique Pelle wrote:

> ryo7000 skribis:
>
> > Hi
> >
> > gVim crashes when operating as follows.
> >
> >  gvim -u NONE -U NONE --noplugin --nofork -c "set guifont=Sans\ 10" -
> > c vnew
> >
> >  qa
> >  :tabnew
> >  :q
> >  q
> >  100@a
> >
> > The cause of the crash is as follows.
> >
> > * tab_close_othertab
> >  * win_free_mem
> >    (A) vim_free(frp)  <- Here, the memory area is freed.
> >    * win_free
> >      (B) gui_mch_destroy_scrollbar  <- After this function is called,
> > frame_minheight() is called from another context.
> >  (C) remove deleted tabpage from first_tabpage list.
> >
> > The value might be written in memory area (tp->fr_win) freed in (A)
> > during the processing of (C) as (A), and frame_minheight() is called
> > after the function of (B), and it becomes the violation of the memory
> > by topfrp->fr_win->w_status_height and it crashes in that.
> >
> > Crash doesn't do easily according to the font, but it seems to be easy
> > for crash to do comparatively in the Sans font.
> > It hardly crashes by correcting it as follows.
> >
> >  vim_free(frp);
> >  win_free(win, tp);
> >
> > to
> >
> >  win_free(win, tp);
> >  vim_free(frp);
> >
> > Please fix this bug.
> >
> > Regards,
> > ryo7000
>
> Hi
>
> I can reproduce the crash too, both with Vim-7.2.445 and
> Vim-7.3a (2293:b9bc9c5df131) gui GTK2 (Linux x86).
>
> When running with Valgrind, after a few minutes, I get the
> following errors.  The stack is deep and I had to modify
> Valgrind to display the full stack:
>
> ==3615== Invalid read of size 4
> ==3615==    at 0x81C7C9A: frame_minheight (window.c:3040)
> ==3615==    by 0x81CBDB6: min_rows (window.c:6139)
> ==3615==    by 0x81B6977: check_shellsize (term.c:3004)
> ==3615==    by 0x81BA3B5: ui_get_shellsize (ui.c:307)
> ==3615==    by 0x81B6AE0: set_shellsize (term.c:3099)
> ==3615==    by 0x81B6A3D: shell_resized (term.c:3043)
> ==3615==    by 0x81CDD89: gui_resize_shell (gui.c:1313)
> ==3615==    by 0x81DC02C: form_configure_event (gui_gtk_x11.c:3590)
> ==3615==    by 0x417A423: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x4746251: g_closure_invoke (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475A99C: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475BC32: g_signal_emit_valist (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x42A7635: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x4173F3B: gtk_main_do_event (in
> /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x81E12CB: gtk_form_send_configure (gui_gtk_f.c:820)
> ==3615==    by 0x81E07F7: gtk_form_size_allocate (gui_gtk_f.c:458)
> ==3615==    by 0x4753437: g_cclosure_marshal_VOID__BOXED (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x4746177: g_closure_invoke (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475A239: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475BDB3: g_signal_emit_valist (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x42AC503: gtk_widget_size_allocate (in
> /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x40B4FB5: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x4753437: g_cclosure_marshal_VOID__BOXED (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x4746177: g_closure_invoke (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475A239: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475BDB3: g_signal_emit_valist (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x42AC503: gtk_widget_size_allocate (in
> /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x42BF2ED: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x4753437: g_cclosure_marshal_VOID__BOXED (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x4746251: g_closure_invoke (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475A239: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475BDB3: g_signal_emit_valist (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x42AC503: gtk_widget_size_allocate (in
> /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x42BF767: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x4753DCB: g_cclosure_marshal_VOID__VOID (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x4746251: g_closure_invoke (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475A5E5: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475BDB3: g_signal_emit_valist (in
> /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
> ==3615==    by 0x40E9709: gtk_container_check_resize (in
> /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x40E975F: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x4429357: ??? (in /usr/lib/libgdk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x47C8660: ??? (in /lib/libglib-2.0.so.0.2400.1)
> ==3615==    by 0x47CA5E4: g_main_context_dispatch (in
> /lib/libglib-2.0.so.0.2400.1)
> ==3615==    by 0x47CE2D7: ??? (in /lib/libglib-2.0.so.0.2400.1)
> ==3615==    by 0x47CE4B7: g_main_context_iteration (in
> /lib/libglib-2.0.so.0.2400.1)
> ==3615==    by 0x41741B2: gtk_main_iteration_do (in
> /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> ==3615==    by 0x81DE9C9: gui_mch_update (gui_gtk_x11.c:5411)
> ==3615==    by 0x81D448E: gui_mch_destroy_scrollbar (gui_gtk.c:774)
> ==3615==    by 0x81C96D6: win_free (window.c:4405)
> ==3615==    by 0x81C6EF3: win_free_mem (window.c:2368)
> ==3615==    by 0x81C6E20: win_close_othertab (window.c:2328)
> ==3615==    by 0x81C6A0E: win_close (window.c:2154)
> ==3615==    by 0x80AD76C: ex_quit (ex_docmd.c:6347)
> ==3615==    by 0x80A7A00: do_one_cmd (ex_docmd.c:2640)
> ==3615==    by 0x80A52D9: do_cmdline (ex_docmd.c:1109)
> ==3615==    by 0x812C680: nv_colon (normal.c:5234)
> ==3615==    by 0x8125EE3: normal_cmd (normal.c:1188)
> ==3615==    by 0x80E803C: main_loop (main.c:1252)
> ==3615==    by 0x80E7A93: main (main.c:960)
> ==3615==  Address 0x514b050 is 40 bytes inside a block of size 44 free'd
> ==3615==    at 0x4024B8A: free (vg_replace_malloc.c:366)
> ==3615==    by 0x8116F0A: vim_free (misc2.c:1702)
> ==3615==    by 0x81C6EE1: win_free_mem (window.c:2367)
> ==3615==    by 0x81C6E20: win_close_othertab (window.c:2328)
> ==3615==    by 0x81C6A0E: win_close (window.c:2154)
> ==3615==    by 0x80AD76C: ex_quit (ex_docmd.c:6347)
> ==3615==    by 0x80A7A00: do_one_cmd (ex_docmd.c:2640)
> ==3615==    by 0x80A52D9: do_cmdline (ex_docmd.c:1109)
> ==3615==    by 0x812C680: nv_colon (normal.c:5234)
> ==3615==    by 0x8125EE3: normal_cmd (normal.c:1188)
> ==3615==    by 0x80E803C: main_loop (main.c:1252)
> ==3615==    by 0x80E7A93: main (main.c:960)
> (more errors afer that)
>
>
> I came to the same conclusion as you: inverting the 2 lines
> windows.c:2367 & window.c:2368 fixes it.
>
> diff -r 2209060c340d src/window.c
> --- a/src/window.c Sat Jul 10 17:51:46 2010 +0200
> +++ b/src/window.c Sat Jul 10 22:27:30 2010 +0200
> @@ -2364,8 +2364,8 @@
>      /* Remove the window and its frame from the tree of frames. */
>      frp = win->w_frame;
>      wp = winframe_remove(win, dirp, tp);
> +    win_free(win, tp);
>      vim_free(frp);
> -    win_free(win, tp);
>
>      /* When deleting the current window of another tab page select a new
>       * current window. */

Tricky stuff.  The basic problem is that the GUI functions try to get
information from a tab page that is halfway being removed.  Swapping the
lines will fix the immediate problem, but something else may come up
later.

I think it's better to first remove the tab page from the structure, so
that it's no longer used by the GUI functions.  Then delete the stuff
involved.  It's hard to see if this doesn't cause a new problem.  Please
use this patch and try it out:


*** ../vim-7.2.445/src/window.c 2010-03-17 16:54:51.000000000 +0100
--- src/window.c 2010-07-11 13:18:31.000000000 +0200
***************
*** 2304,2309 ****
--- 2304,2310 ----
      win_T *wp;
      int dir;
      tabpage_T   *ptp = NULL;
+     int free_tp = FALSE;
 
      /* Close the link to the buffer. */
      close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
***************
*** 2321,2331 ****
      if (wp == NULL)
  return;
 
-     /* Free the memory used for the window. */
-     wp = win_free_mem(win, &dir, tp);
-
      /* When closing the last window in a tab page remove the tab page. */
!     if (wp == NULL)
      {
  if (tp == first_tabpage)
     first_tabpage = tp->tp_next;
--- 2322,2329 ----
      if (wp == NULL)
  return;
 
      /* When closing the last window in a tab page remove the tab page. */
!     if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
      {
  if (tp == first_tabpage)
     first_tabpage = tp->tp_next;
***************
*** 2341,2348 ****
     }
     ptp->tp_next = tp->tp_next;
  }
! free_tabpage(tp);
      }
  }
 
  /*
--- 2339,2352 ----
     }
     ptp->tp_next = tp->tp_next;
  }
! free_tp = TRUE;
      }
+
+     /* Free the memory used for the window. */
+     win_free_mem(win, &dir, tp);
+
+     if (free_tp)
+ free_tabpage(tp);
  }
 
  /*


--
"My particular problem is with registry entries, which seem to just
accumulate like plastic coffee cups..."           -- Paul Moore

 /// Bram Moolenaar -- [hidden email] -- 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.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: segfault on closing tab

ryo7000
Thank you for a more appropriate patch.

> Please use this patch and try it out:

I tried this patch, Segfault did not occur at all.

Regards,
ryo7000

On 7月11日, 午後9:16, Bram Moolenaar <[hidden email]> wrote:

> Dominique Pelle wrote:
> > ryo7000 skribis:
>
> > > Hi
>
> > > gVim crashes when operating as follows.
>
> > >  gvim -u NONE -U NONE --noplugin --nofork -c "set guifont=Sans\ 10" -
> > > c vnew
>
> > >  qa
> > >  :tabnew
> > >  :q
> > >  q
> > >  100@a
>
> > > The cause of the crash is as follows.
>
> > > * tab_close_othertab
> > >  * win_free_mem
> > >    (A) vim_free(frp)  <- Here, the memory area is freed.
> > >    * win_free
> > >      (B) gui_mch_destroy_scrollbar  <- After this function is called,
> > > frame_minheight() is called from another context.
> > >  (C) remove deleted tabpage from first_tabpage list.
>
> > > The value might be written in memory area (tp->fr_win) freed in (A)
> > > during the processing of (C) as (A), and frame_minheight() is called
> > > after the function of (B), and it becomes the violation of the memory
> > > by topfrp->fr_win->w_status_height and it crashes in that.
>
> > > Crash doesn't do easily according to the font, but it seems to be easy
> > > for crash to do comparatively in the Sans font.
> > > It hardly crashes by correcting it as follows.
>
> > >  vim_free(frp);
> > >  win_free(win, tp);
>
> > > to
>
> > >  win_free(win, tp);
> > >  vim_free(frp);
>
> > > Please fix this bug.
>
> > > Regards,
> > > ryo7000
>
> > Hi
>
> > I can reproduce the crash too, both with Vim-7.2.445 and
> > Vim-7.3a (2293:b9bc9c5df131) gui GTK2 (Linux x86).
>
> > When running with Valgrind, after a few minutes, I get the
> > following errors.  The stack is deep and I had to modify
> > Valgrind to display the full stack:
>
> > ==3615== Invalid read of size 4
> > ==3615==    at 0x81C7C9A: frame_minheight (window.c:3040)
> > ==3615==    by 0x81CBDB6: min_rows (window.c:6139)
> > ==3615==    by 0x81B6977: check_shellsize (term.c:3004)
> > ==3615==    by 0x81BA3B5: ui_get_shellsize (ui.c:307)
> > ==3615==    by 0x81B6AE0: set_shellsize (term.c:3099)
> > ==3615==    by 0x81B6A3D: shell_resized (term.c:3043)
> > ==3615==    by 0x81CDD89: gui_resize_shell (gui.c:1313)
> > ==3615==    by 0x81DC02C: form_configure_event (gui_gtk_x11.c:3590)
> > ==3615==    by 0x417A423: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x4746251: g_closure_invoke (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475A99C: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475BC32: g_signal_emit_valist (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x42A7635: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x4173F3B: gtk_main_do_event (in
> > /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x81E12CB: gtk_form_send_configure (gui_gtk_f.c:820)
> > ==3615==    by 0x81E07F7: gtk_form_size_allocate (gui_gtk_f.c:458)
> > ==3615==    by 0x4753437: g_cclosure_marshal_VOID__BOXED (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x4746177: g_closure_invoke (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475A239: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475BDB3: g_signal_emit_valist (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x42AC503: gtk_widget_size_allocate (in
> > /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x40B4FB5: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x4753437: g_cclosure_marshal_VOID__BOXED (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x4746177: g_closure_invoke (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475A239: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475BDB3: g_signal_emit_valist (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x42AC503: gtk_widget_size_allocate (in
> > /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x42BF2ED: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x4753437: g_cclosure_marshal_VOID__BOXED (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x4746251: g_closure_invoke (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475A239: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475BDB3: g_signal_emit_valist (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x42AC503: gtk_widget_size_allocate (in
> > /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x42BF767: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x4753DCB: g_cclosure_marshal_VOID__VOID (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x47448B8: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x4746251: g_closure_invoke (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475A5E5: ??? (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475BDB3: g_signal_emit_valist (in
> > /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x475C255: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2400.1)
> > ==3615==    by 0x40E9709: gtk_container_check_resize (in
> > /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x40E975F: ??? (in /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x4429357: ??? (in /usr/lib/libgdk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x47C8660: ??? (in /lib/libglib-2.0.so.0.2400.1)
> > ==3615==    by 0x47CA5E4: g_main_context_dispatch (in
> > /lib/libglib-2.0.so.0.2400.1)
> > ==3615==    by 0x47CE2D7: ??? (in /lib/libglib-2.0.so.0.2400.1)
> > ==3615==    by 0x47CE4B7: g_main_context_iteration (in
> > /lib/libglib-2.0.so.0.2400.1)
> > ==3615==    by 0x41741B2: gtk_main_iteration_do (in
> > /usr/lib/libgtk-x11-2.0.so.0.2000.1)
> > ==3615==    by 0x81DE9C9: gui_mch_update (gui_gtk_x11.c:5411)
> > ==3615==    by 0x81D448E: gui_mch_destroy_scrollbar (gui_gtk.c:774)
> > ==3615==    by 0x81C96D6: win_free (window.c:4405)
> > ==3615==    by 0x81C6EF3: win_free_mem (window.c:2368)
> > ==3615==    by 0x81C6E20: win_close_othertab (window.c:2328)
> > ==3615==    by 0x81C6A0E: win_close (window.c:2154)
> > ==3615==    by 0x80AD76C: ex_quit (ex_docmd.c:6347)
> > ==3615==    by 0x80A7A00: do_one_cmd (ex_docmd.c:2640)
> > ==3615==    by 0x80A52D9: do_cmdline (ex_docmd.c:1109)
> > ==3615==    by 0x812C680: nv_colon (normal.c:5234)
> > ==3615==    by 0x8125EE3: normal_cmd (normal.c:1188)
> > ==3615==    by 0x80E803C: main_loop (main.c:1252)
> > ==3615==    by 0x80E7A93: main (main.c:960)
> > ==3615==  Address 0x514b050 is 40 bytes inside a block of size 44 free'd
> > ==3615==    at 0x4024B8A: free (vg_replace_malloc.c:366)
> > ==3615==    by 0x8116F0A: vim_free (misc2.c:1702)
> > ==3615==    by 0x81C6EE1: win_free_mem (window.c:2367)
> > ==3615==    by 0x81C6E20: win_close_othertab (window.c:2328)
> > ==3615==    by 0x81C6A0E: win_close (window.c:2154)
> > ==3615==    by 0x80AD76C: ex_quit (ex_docmd.c:6347)
> > ==3615==    by 0x80A7A00: do_one_cmd (ex_docmd.c:2640)
> > ==3615==    by 0x80A52D9: do_cmdline (ex_docmd.c:1109)
> > ==3615==    by 0x812C680: nv_colon (normal.c:5234)
> > ==3615==    by 0x8125EE3: normal_cmd (normal.c:1188)
> > ==3615==    by 0x80E803C: main_loop (main.c:1252)
> > ==3615==    by 0x80E7A93: main (main.c:960)
> > (more errors afer that)
>
> > I came to the same conclusion as you: inverting the 2 lines
> > windows.c:2367 & window.c:2368 fixes it.
>
> > diff -r 2209060c340d src/window.c
> > --- a/src/window.c Sat Jul 10 17:51:46 2010 +0200
> > +++ b/src/window.c Sat Jul 10 22:27:30 2010 +0200
> > @@ -2364,8 +2364,8 @@
> >      /* Remove the window and its frame from the tree of frames. */
> >      frp = win->w_frame;
> >      wp = winframe_remove(win, dirp, tp);
> > +    win_free(win, tp);
> >      vim_free(frp);
> > -    win_free(win, tp);
>
> >      /* When deleting the current window of another tab page select a new
> >       * current window. */
>
> Tricky stuff.  The basic problem is that the GUI functions try to get
> information from a tab page that is halfway being removed.  Swapping the
> lines will fix the immediate problem, but something else may come up
> later.
>
> I think it's better to first remove the tab page from the structure, so
> that it's no longer used by the GUI functions.  Then delete the stuff
> involved.  It's hard to see if this doesn't cause a new problem.  Please
> use this patch and try it out:
>
> *** ../vim-7.2.445/src/window.c 2010-03-17 16:54:51.000000000 +0100
> --- src/window.c        2010-07-11 13:18:31.000000000 +0200
> ***************
> *** 2304,2309 ****
> --- 2304,2310 ----
>       win_T     *wp;
>       int               dir;
>       tabpage_T   *ptp = NULL;
> +     int               free_tp = FALSE;
>
>       /* Close the link to the buffer. */
>       close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
> ***************
> *** 2321,2331 ****
>       if (wp == NULL)
>         return;
>
> -     /* Free the memory used for the window. */
> -     wp = win_free_mem(win, &dir, tp);
> -
>       /* When closing the last window in a tab page remove the tab page. */
> !     if (wp == NULL)
>       {
>         if (tp == first_tabpage)
>             first_tabpage = tp->tp_next;
> --- 2322,2329 ----
>       if (wp == NULL)
>         return;
>
>       /* When closing the last window in a tab page remove the tab page. */
> !     if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
>       {
>         if (tp == first_tabpage)
>             first_tabpage = tp->tp_next;
> ***************
> *** 2341,2348 ****
>             }
>             ptp->tp_next = tp->tp_next;
>         }
> !       free_tabpage(tp);
>       }
>   }
>
>   /*
> --- 2339,2352 ----
>             }
>             ptp->tp_next = tp->tp_next;
>         }
> !       free_tp = TRUE;
>       }
> +
> +     /* Free the memory used for the window. */
> +     win_free_mem(win, &dir, tp);
> +
> +     if (free_tp)
> +       free_tabpage(tp);
>   }
>
>   /*
>
> --
> "My particular problem is with registry entries, which seem to just
> accumulate like plastic coffee cups..."           -- Paul Moore
>
>  /// Bram Moolenaar -- [hidden email] --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.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: segfault on closing tab

Dominique Pellé
ryo7000 wrote:

>> Please use this patch and try it out:
>
> I tried this patch, Segfault did not occur at all.

Patch also works for me: no more crash, no more valgrind error.

-- Dominique

--
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: segfault on closing tab

Bram Moolenaar

Dominique Pelle wrote:

> ryo7000 wrote:
>
> >> Please use this patch and try it out:
> >
> > I tried this patch, Segfault did not occur at all.
>
> Patch also works for me: no more crash, no more valgrind error.

Thanks for testing.  I'll send it out now.

--
PRINCE:    He's come to rescue me, father.
LAUNCELOT: (embarrassed) Well, let's not jump to conclusions ...
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [hidden email] -- 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.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Loading...