记一次修复MiniGUI相关Bug的过程
这个Bug连着困扰了我六七个小时,而且表现神秘不定,我觉得很有必要把它详细地记录下来。
事情源于我正在编写的一个GUI库,底层基于MiniGUI,主要用在嵌入式Linux下显示图形界面。最开始的表现是,我在本机编译完成后跑得好好的程序,在交叉编译后放到arm板子上一启动就崩溃,而且诡异的是,崩溃的几率和我类的参数有关,最开始我在类的destructor前加上了virtual之后,崩溃消失了,然后我又在类里加了些变量,程序又崩溃了。而且本机上一点崩溃的迹象也没有。所以我一度认为这是交叉编译器的Bug,无奈。
之后事情终于有了转机,本机上编译的程序终于也崩溃了!可见,很多时候程序员们是多么渴望程序崩溃啊!
于是马上调出gdb,崩溃处的代码如下:
dskOnNewCtrlInstance (hWnd=1075427776, message=361, wParam=134576144, lParam=134575776) at desktop-comm.c:2683 2683 pNode->hWnd = (HWND)pNewCtrl;
p pNode 发现pNode是0x00,找到你了!难道是MiniGUI的Bug?
再仔细观察代码:
if (pNewCtrl->dwExStyle & WS_EX_CTRLASMAINWIN) { PZORDERNODE pNode = pNewCtrl->pZOrderNode;
不对!代码理应不会跳到这一段,我的dwExStyle并没有包含WS_EX_CTRLASMAINWIN,我设置的应该是WS_EX_NONE,最后前往注册窗口类的代码处,终于发现了Bug所在:
/* Register the common WINDOW_CLASS_NAME */ WNDCLASS WindowClass; WindowClass.spClassName = (char*) WINDOW_CLASS_NAME; WindowClass.dwStyle = WS_EX_NONE; WindowClass.hCursor = GetSystemCursor(IDC_ARROW); WindowClass.iBkColor = COLOR_lightwhite; WindowClass.WinProc = BasicWindow::dispatch; RegisterWindowClass(&WindowClass);
原来我没有设置dwExStyle,于是dwExStyle被填充入了垃圾数据,运气好時不会启动这个Bug,运气不好時就会崩溃,归根到底问题还是出在我自己身上……
最后虽然MiniGUI没有错,但也许一句 assert (NULL != pNode); 就能省下我许许多多的时间,也算是今后自己写代码的一个教训吧。