调用 XtDestroyWidget 时主题应用程序崩溃
我们有一个 32 位 Motif Gui 应用程序。现在我们将应用程序从Solaris移植到Linux上,系统经常崩溃。根据我们的分析,我们可以发现这个问题是在我们关闭应用程序中的表单时发生的。当表单关闭时,我们将删除表单并调用函数 XtDestroyWidget() 来删除小部件。我们对应用程序进行了净化,我们发现关闭表单时会发生堆栈数组边界读取(SBR)。
我从互联网上下载了一个示例主题程序,该程序使用 XtDestroyWidget() 来销毁该对象。当我也为这个示例程序运行 purify 时,我可以找到相同的 SBR。
SBR:堆栈数组边界读取(54 次): * 这种情况发生在: XtDispatchEvent [libXt.so.4] 删除AllPMgr [libXm.so.3] XtCallCallbackList [libXt.so.4] XtPhase2Destroy [libXt.so.4] _XtDoPhase2Destroy [libXt.so.4] XtDispatchEvent [libXt.so.4] XtAppMainLoop [libXt.so.4] 主要[popup.cc:49] _start [crt1.o] * 从 0xffbfe4f0 读取 4 个字节。 * 帧指针0xffbfe4d0 * 地址 0xffbfe4f0 位于函数 XtCallCallbackList 中堆栈指针上方 32 个字节。
此 SBR 发生在 XtAppMainLoop() 中。根据这些事实,我认为该 SBR 是一种常见的 SBR,并且与主题相关,而不是与我们的应用相关。
您能否对以下问题补充一些想法? 1)为什么当我们使用XtDestroyWidget()时会发生SBR。这个SBR是不是很严重?
2)我删除了 XtDestroyWidget 并使用了 XtUnrealizeWidget()。这将帮助我删除 SBR,因此不会发生崩溃。所有正常形式也将被正常删除。但我在这种方法中面临的问题是 POP_UP 表单在这种方法中没有被删除。除了 HIDE 选项之外,任何人都可以建议一种删除 POP_UP 表单的解决方法吗?
如果有人能回答或添加一些关于这个问题的想法,这对我将非常有帮助。
提前致谢, Sanush Chacko
-----添加示例程序.. 你好 请从我获得 SBR 的地方找到示例程序。
包括 X11/StringDefs.h 包括 Xm/Xm.h 包括 Xm/PushB.h
Widget 顶层;
void close_window(Widget w, XtPointer client_data, XtPointer event_data) { 弹出小部件 = (Widget)client_data; XtDestroyWidget(弹出窗口); }
void pop(Widget w, XtPointer client_data, XtPointer event_data) { 小部件a、按钮、弹出窗口;
popup = XtVaCreatePopupShell("Popup", transientShellWidgetClass, toplevel, NULL);
button = XtVaCreateManagedWidget("Close", xmPushButtonWidgetClass, popup,
NULL);
XtAddCallback(button, XmNactivateCallback, close_window, (XtPointer)popup);
XtPopup(popup, XtGrabNone);
}
main(int argc, char *argv[]) { 小部件按钮; XtAppContext 应用程序; XmString标签;
toplevel = XtVaAppInitialize(&app, "Popup", NULL, 0,
&argc, argv, NULL, NULL);
label = XmStringCreateSimple("Make popup");
button = XtVaCreateManagedWidget("pushme", xmPushButtonWidgetClass, toplevel,
XmNlabelString, label,
NULL);
XmStringFree(label);
XtAddCallback(button, XmNactivateCallback, pop, NULL);
XtRealizeWidget(toplevel);
XtAppMainLoop(app);
}
We have a 32bit Motif Gui application. Now we ported the application from Solaris to Linux and the system is crashing very frequently. On our analysis we could find that this issue happened when we are closing the forms in our application. When the forms are closed we will delete the forms and will call the function XtDestroyWidget() to remove the widgets. We ran a purify for the application and we could found that the Stack Array Bounds Read (SBR) is happening when we close the form.
I had downloaded a sample motif program from the internet which is using XtDestroyWidget() to destroy the object. When i ran purify for this sample program also, i could found the same SBR.
SBR: Stack array bounds read (54 times):
* This is occurring while in:
XtDispatchEvent [libXt.so.4]
RemoveAllPMgr [libXm.so.3]
XtCallCallbackList [libXt.so.4]
XtPhase2Destroy [libXt.so.4]
_XtDoPhase2Destroy [libXt.so.4]
XtDispatchEvent [libXt.so.4]
XtAppMainLoop [libXt.so.4]
main [popup.cc:49]
_start [crt1.o]
* Reading 4 bytes from 0xffbfe4f0.
* Frame pointer 0xffbfe4d0
* Address 0xffbfe4f0 is 32 bytes above stack pointer in function XtCallCallbackList.
This SBR is happening in the XtAppMainLoop(). From these facts i assume that this SBR is a common one and related to motif rather than to our application.
Can you please add some thoughts to the following questions.
1) Why SBR is happening when we use XtDestroyWidget(). Is this SBR a severe one.
2) I had removed the XtDestroyWidget and used XtUnrealizeWidget(). This will help me to remove the SBR and hence crash is not happening. Also all normal forms will be removed normally. But the problem i am facing in this approach is the POP_UP forms are NOT removed in this method. Can any one please suggest a work around for removing POP_UP forms also other than the HIDE option.
It will be very helpful for me if anyone can answer or add some thoughts for this issue.
Thanks in advance,
Sanush Chacko
-----Adding Sample Program..
Hi
Please find the sample program from where i got the SBR.
include X11/StringDefs.h
include Xm/Xm.h
include Xm/PushB.h
Widget toplevel;
void close_window(Widget w, XtPointer client_data, XtPointer event_data)
{
Widget popup = (Widget)client_data;
XtDestroyWidget(popup);
}
void pop(Widget w, XtPointer client_data, XtPointer event_data)
{
Widget a, button, popup;
popup = XtVaCreatePopupShell("Popup", transientShellWidgetClass, toplevel, NULL);
button = XtVaCreateManagedWidget("Close", xmPushButtonWidgetClass, popup,
NULL);
XtAddCallback(button, XmNactivateCallback, close_window, (XtPointer)popup);
XtPopup(popup, XtGrabNone);
}
main(int argc, char *argv[])
{
Widget button;
XtAppContext app;
XmString label;
toplevel = XtVaAppInitialize(&app, "Popup", NULL, 0,
&argc, argv, NULL, NULL);
label = XmStringCreateSimple("Make popup");
button = XtVaCreateManagedWidget("pushme", xmPushButtonWidgetClass, toplevel,
XmNlabelString, label,
NULL);
XmStringFree(label);
XtAddCallback(button, XmNactivateCallback, pop, NULL);
XtRealizeWidget(toplevel);
XtAppMainLoop(app);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不应该在小部件调用的回调中销毁该小部件。
不要每次单击按钮时都创建一个新的弹出窗口,而是在创建按钮时在程序开始时创建一个弹出窗口,根据需要显示和隐藏弹出窗口,然后在 XtAppMainLoop() 返回后销毁它。
这在性能方面更有效(但在内存方面效率稍低)。
我有点生疏,但我相信您还可以管理/取消管理小部件,而不仅仅是隐藏/显示它。
You should not destroy the widget within a callback called by the widget.
Instead of creating a new popup every time you click a button, create a popup at the start of the program when you create the button, show and hide the popup as required, and then destroy it after XtAppMainLoop() returns.
This is more efficient in terms of performance (but slightly less efficient in terms of memory).
I'm a bit rusty, but I believe you can also manage/unmanage the widget rather than just hide/show it.