emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

crash in xmenu.c


From: Richard Stallman
Subject: crash in xmenu.c
Date: Sun, 16 Apr 2006 20:56:51 -0400

I think I have fixed the crash in xmenu.c.  It was not, I believe,
related to the problem #18 that was found by coverity--that was a
coincidence.

With this fix, the debugger comes up ok
after (setq debug-on-error t) C-x 5 f emacs.c RET.
However, another bug remains:  if you type q at the debugger,
Emacs crashes.  I don't have time to debug that.

*** xmenu.c     22 Feb 2006 13:56:52 -0500      1.300
--- xmenu.c     16 Apr 2006 16:55:59 -0400      
***************
*** 266,279 ****
  static void
  init_menu_items ()
  {
    if (NILP (menu_items))
      {
        menu_items_allocated = 60;
        menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
      }
  
-   if (!NILP (menu_items_inuse))
-     error ("Trying to use a menu from within a menu-entry");
    menu_items_inuse = Qt;
    menu_items_used = 0;
    menu_items_n_panes = 0;
--- 266,280 ----
  static void
  init_menu_items ()
  {
+   if (!NILP (menu_items_inuse))
+     error ("Trying to use a menu from within a menu-entry");
+ 
    if (NILP (menu_items))
      {
        menu_items_allocated = 60;
        menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
      }
  
    menu_items_inuse = Qt;
    menu_items_used = 0;
    menu_items_n_panes = 0;
***************
*** 310,315 ****
--- 311,349 ----
    xassert (NILP (menu_items_inuse));
  }
  
+ /* This undoes save_menu_items, and it is called by the specpdl unwind
+    mechanism.  */
+ 
+ static Lisp_Object
+ restore_menu_items (saved)
+      Lisp_Object saved;
+ {
+   menu_items = XCAR (saved);
+   menu_items_inuse = (! NILP (menu_items) ? Qt : Qnil);
+   menu_items_allocated = (VECTORP (menu_items) ? ASIZE (menu_items) : 0);
+   saved = XCDR (saved);
+   menu_items_used = XINT (XCAR (saved));
+   saved = XCDR (saved);
+   menu_items_n_panes = XINT (XCAR (saved));
+   saved = XCDR (saved);  
+   menu_items_submenu_depth = XINT (XCAR (saved));
+ }
+ 
+ /* Push the whole state of menu_items processing onto the specpdl.
+    It will be restored when the specpdl is unwound.  */
+ 
+ static void
+ save_menu_items ()
+ {
+   Lisp_Object saved = list4 (!NILP (menu_items_inuse) ? menu_items : Qnil,
+                            make_number (menu_items_used),
+                            make_number (menu_items_n_panes),
+                            make_number (menu_items_submenu_depth));
+   record_unwind_protect (restore_menu_items, saved);
+   menu_items_inuse = Qnil;
+   menu_items = Qnil;
+ }
+ 
  /* Make the menu_items vector twice as large.  */
  
  static void
***************
*** 320,325 ****
--- 354,360 ----
    old = menu_items;
  
    menu_items_allocated *= 2;
+ 
    menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
    bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents,
         old_size * sizeof (Lisp_Object));
***************
*** 1728,1733 ****
--- 1763,1769 ----
    int i;
    int submenu_depth = 0;
    widget_value **submenu_stack;
+   int panes_seen = 0;
  
    submenu_stack
      = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
***************
*** 1774,1779 ****
--- 1810,1817 ----
          Lisp_Object pane_name, prefix;
          char *pane_string;
  
+         panes_seen++;
+ 
          pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
          prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
  
***************
*** 1821,1826 ****
--- 1859,1868 ----
          Lisp_Object item_name, enable, descrip, def, type, selected;
          Lisp_Object help;
  
+         /* All items should be contained in panes.  */
+         if (panes_seen == 0)
+           abort ();
+ 
          item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
          enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
          descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
***************
*** 2046,2052 ****
        specbind (Qdebug_on_next_call, Qnil);
  
        record_unwind_save_match_data ();
-       record_unwind_protect (unuse_menu_items, Qnil);
        if (NILP (Voverriding_local_map_menu_flag))
        {
          specbind (Qoverriding_terminal_local_map, Qnil);
--- 2088,2093 ----
***************
*** 2074,2079 ****
--- 2115,2122 ----
  
        /* Fill in menu_items with the current menu bar contents.
         This can evaluate Lisp code.  */
+       save_menu_items ();
+ 
        menu_items = f->menu_bar_vector;
        menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
        submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
***************
*** 2133,2139 ****
        }
  
        set_buffer_internal_1 (prev);
-       unbind_to (specpdl_count, Qnil);
  
        /* If there has been no change in the Lisp-level contents
         of the menu bar, skip redisplaying it.  Just exit.  */
--- 2176,2181 ----
***************
*** 2146,2155 ****
        {
          free_menubar_widget_value_tree (first_wv);
          discard_menu_items ();
! 
          return;
        }
  
        /* Now GC cannot happen during the lifetime of the widget_value,
         so it's safe to store data from a Lisp_String.  */
        wv = first_wv->contents;
--- 2188,2202 ----
        {
          free_menubar_widget_value_tree (first_wv);
          discard_menu_items ();
!         unbind_to (specpdl_count, Qnil);
          return;
        }
  
+       f->menu_bar_vector = menu_items;
+       f->menu_bar_items_used = menu_items_used;
+ 
+       unbind_to (specpdl_count, Qnil);
+ 
        /* Now GC cannot happen during the lifetime of the widget_value,
         so it's safe to store data from a Lisp_String.  */
        wv = first_wv->contents;
***************
*** 2164,2172 ****
            wv = wv->next;
        }
  
-       f->menu_bar_vector = menu_items;
-       f->menu_bar_items_used = menu_items_used;
-       discard_menu_items ();
      }
    else
      {
--- 2211,2216 ----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]