Bug #886
closedReproducible segmentation fault: dynamic submenus
0%
Description
When I dynamically add a submenu with a menuitem, click on it, remove it, re-add it, reclick it, I get a crash. When the menu is not rendered as a list and doesn't make use of internal paths, I don't get the crash.
FYI: I'm using the git version.
Steps to reproduce:
- click the 'middle menu' option
- click the 'Add submenu' button
- click the 'probleemitem' option
- click the 'middle menu' option
- click the 'Remove submenu' option
- click the 'Add submenu option'
- click the 'probleemitem' option -> segmentation fault
void HelloApplication::create()
{
contentsStack_ = new WStackedWidget();
// top menu
WMenu *topmenu = new WMenu(contentsStack_, Vertical);
topmenu->setRenderAsList(true);
topmenu->setStyleClass("menu");
topmenu->setInternalPathEnabled();
topmenu->setInternalBasePath("/");
// menu middle
WMenu *middle_menu = new WMenu(contentsStack_, Vertical);
middle_menu->setRenderAsList(true);
middle_menu->setStyleClass("menu");
middle_menu->setInternalPathEnabled();
middle_menu->setInternalBasePath("/level1");
WPushButton *add_submenu_button = new WPushButton();
add_submenu_button->clicked().connect(bind(&HelloApplication::add_option, this));
add_submenu_button->setText("Add submenu");
WPushButton *remove_submenu_button = new WPushButton();
remove_submenu_button->clicked().connect(bind(&HelloApplication::remove_option, this));
remove_submenu_button->setText("Remove submenu");
WContainerWidget *middle_container = new WContainerWidget();
middle_container->addWidget(add_submenu_button);
middle_container->addWidget(remove_submenu_button);
WSubMenuItem *middle_menuItem = new WSubMenuItem("middle menu", middle_container);
middle_menuItem->setSubMenu(middle_menu);
topmenu->addItem(middle_menuItem);
// assign so we can use this in our add_option() method
menu_ = middle_menu;
WHBoxLayout *layout = new WHBoxLayout();
layout*->addWidget(topmenu*);
layout->addWidget(contentsStack_);
root()->setLayout(layout, AlignTop);
}
void HelloApplication::add_option()
{
WMenu *submenu = new WMenu(contentsStack_, Vertical);
submenu->setRenderAsList(true);
submenu->setStyleClass("menu submenu");
WSubMenuItem *submenuItem = new WSubMenuItem("submenu", new WText("submenu contents"));
submenu->setInternalPathEnabled();
submenu~~setInternalBasePath("/" + submenuItem~~>pathComponent());
WMenuItem *probleemitem = new WMenuItem("probleemitem", new WText("probleem item"));
submenu->addItem(probleemitem);
submenuItem->setSubMenu(submenu);
menu_->addItem(submenuItem);
menu_item_ = submenuItem;
}
void HelloApplication::remove_option()
{
menu*->removeItem(menu_item*);
}
stacktrace:
Thread [6] 21711 (Suspended : Signal : SIGSEGV:Segmentation fault)
Wt::WMenu::selectVisual() at WMenu.C:314 0xb7c8cf0b
Wt::WMenu::select() at WMenu.C:292 0xb7c8d3f4
Wt::WMenu::select() at WMenu.C:287 0xb7c8dc5c
Wt::WSubMenuItem::subItemSelected() at WSubMenuItem.C:30 0xb7cf6f3d
boost::_mfi::mf0<void, Wt::WSubMenuItem>::operator() at mem_fn_template.hpp:49 0xb7cf722d
operator() at bind.hpp:253 0xb7cf722d
operator() at bind_template.hpp:203 0xb7cf722d
boost::detail::function::void_function_obj_invoker6<boost::_bi::bind_t<void, boost::_mfi::mf0<void, Wt::WSubMenuItem>, boost::_bi::list1<boost::_bi::value<Wt::WSubMenuItem*> > >, void, Wt::WMenuItem*, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass>::invoke() at function_template.hpp:153 0xb7cf722d
boost::signal6<void, Wt::WMenuItem*, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass, boost::last_value, int, std::less, boost::function6<void, Wt::WMenuItem*, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass> >::operator() at 0xb7c90958
Wt::Signal<Wt::WMenuItem*, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass>::emit() at 0xb7c90fad
Wt::WMenu::select() at WMenu.C:301 0xb7c8d591
Wt::WMenuItem::setFromInternalPath() at WMenuItem.C:375 0xb7c91b85
Wt::WMenu::internalPathChanged() at WMenu.C:458 0xb7c8da1e
boost::_mfi::mf1<void, Wt::WMenu, std::string const&>::operator() at mem_fn_template.hpp:165 0xb7c8e66f
operator() at bind.hpp:313 0xb7c8e66f
operator() at bind_template.hpp:203 0xb7c8e66f
boost::detail::function::void_function_obj_invoker6<boost::_bi::bind_t<void, boost::_mfi::mf1<void, Wt::WMenu, std::string const&>, boost::_bi::list2<boost::_bi::value<Wt::WMenu*>, boost::arg<1> > >, void, std::string, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass>::invoke() at function_template.hpp:153 0xb7c8e66f
boost::signal6<void, std::string, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass, boost::last_value, int, std::less, boost::function6<void, std::string, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass> >::operator() at 0xb7bcaaef
Wt::Signal<std::string, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass, Wt::NoClass>::emit() at 0xb7bcb18f
Wt::WMenu::select() at WMenu.C:306 0xb7c8d632
<...more frames...>
Files
Updated by Rob Van Dyck over 13 years ago
- File 877_wt.png 877_wt.png added
Besides the above issue you can still see Bug #877 in action on step 4 of the above steps. You can see the text 'probleem item' under the 2 push buttons, while it should not be visible anymore because you clicked the 'middle menu' option, which only contains the push buttons. Therefor #877 is wrongly marked as resolved imho. See attached screenshot.
Updated by Rob Van Dyck over 13 years ago
Repost of code with proper formatting
@
void HelloApplication::create()
{
contentsStack_ = new WStackedWidget();
// top menu
WMenu *topmenu = new WMenu(contentsStack_, Vertical);
topmenu->setRenderAsList(true);
topmenu->setStyleClass("menu");
topmenu->setInternalPathEnabled();
topmenu->setInternalBasePath("/");
// menu middle
WMenu *middle_menu = new WMenu(contentsStack_, Vertical);
middle_menu->setRenderAsList(true);
middle_menu->setStyleClass("menu");
middle_menu->setInternalPathEnabled();
middle_menu->setInternalBasePath("/level1");
WPushButton *add_submenu_button = new WPushButton();
add_submenu_button->clicked().connect(bind(&HelloApplication::add_option, this));
add_submenu_button->setText("Add submenu");
WPushButton *remove_submenu_button = new WPushButton();
remove_submenu_button->clicked().connect(bind(&HelloApplication::remove_option, this));
remove_submenu_button->setText("Remove submenu");
WContainerWidget *middle_container = new WContainerWidget();
middle_container->addWidget(add_submenu_button);
middle_container->addWidget(remove_submenu_button);
WSubMenuItem *middle_menuItem = new WSubMenuItem("middle menu", middle_container);
middle_menuItem->setSubMenu(middle_menu);
topmenu->addItem(middle_menuItem);
// assign so we can use this in our add_option() method
menu_ = middle_menu;
WHBoxLayout *layout = new WHBoxLayout();
layout*->addWidget(topmenu*);
layout->addWidget(contentsStack_);
root()->setLayout(layout, AlignTop);
}
void HelloApplication::add_option()
{
WMenu *submenu = new WMenu(contentsStack_, Vertical);
submenu->setRenderAsList(true);
submenu->setStyleClass("menu submenu");
WSubMenuItem *submenuItem = new WSubMenuItem("submenu", new WText("submenu contents"));
submenu->setInternalPathEnabled();
submenu~~setInternalBasePath("/" + submenuItem~~>pathComponent());
WMenuItem *probleemitem = new WMenuItem("probleemitem", new WText("probleem item"));
submenu->addItem(probleemitem);
submenuItem->setSubMenu(submenu);
menu_->addItem(submenuItem);
menu_item_ = submenuItem;
}
void HelloApplication::remove_option()
{
menu*->removeItem(menu_item*);
}
@
Updated by Koen Deforche over 13 years ago
- Status changed from New to Resolved
- Assignee set to Koen Deforche
Hey Rob,
Thanks for being persistent on this. Fixed this, together with #877, in git.
Btw., your test case will leak the menu_item_ after you've removed it, and deleting the menu_item_ would mask/workaround the problem you observe.
Regards,
koen
Updated by Rob Van Dyck over 13 years ago
Koen Deforche wrote:
Hey Rob,
Thanks for being persistent on this. Fixed this, together with #877, in git.
Btw., your test case will leak the menu_item_ after you've removed it, and deleting the menu_item_ would mask/workaround the problem you observe.
Regards,
koen
Hey Koen,
Thanx for fixing the bug!
Regards,
Rob.
Updated by Koen Deforche over 13 years ago
- Status changed from Resolved to Closed