Closed htk719809837 closed 2 years ago
请问您的代码基线?是 rel-5-0 分支的最新版本还是 master 分支的最新版本?
我的代码是今年7月13日在minigui官网下载的,因为网络问题并没有通过git拉取,但是按照rel-5-0 分支的2e8eba7dd0a0d3c15f9ed58e7a3b5282e47fa8ca和f76c9187a8f3edb9d64b97826506538a1c324b8b两个提交记录修改以后并没有解开这个死锁
按照#83修改以后似乎并没有被修复
请贴一段用于重现该缺陷的代码,可编译为可执行程序的,以方便调试。谢谢!
并告知 MiniGUI 的运行模式。
使用的是线程模式,我准备切换到rel-5-0分支去尝试是否解开死锁,但是好像编译方式不太一样,./autogen.sh,也会有报错,看到新增了cmakelist,是不是修改了编译方式呢
MiniGUI 5.0 的构建仍然使用的是 autotools,跟 MiniGUI 3.0 没有本质区别,但某些配置选项发生了变化。
您可以参考如下仓库中的构建脚本:
确认了一下,死锁问题是在五月底解决的,是 5.0.9 版本发布之后,代码在 rel-5-0 分支上,尚未合并到 master 分支。
如果习惯使用软件包,可以切换到 rel-5-0 分支,在 PC 上进行配置,然后运行 make dist 命令打包成 5.0.10 的 tar.gz 包然后再放到你自己的项目中构建。
用了最新版本 rel-5-0,死锁并没有解决,能麻烦问一下当时死锁的原因是什么吗,从提交历史只看到了unlock zi for change (zi);移动了位置,还有一处定义改变了,但是并没有解决这个问题,在3.0中不存在这个死锁,如果有时间我会提供一个demo,不过还是想了解一下死锁产生的原因,谢谢!
属于缺陷。要快速解决您遇到的问题,还是要给出可以重现缺陷的代码,这样才能帮我们快速定位问题、解决问题。
static LRESULT pwdlogin_ime_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
printf("message in : %d \n", message);
switch (message)
{
case MSG_CREATE:
{
hWnd = CreateWindowEx(CTRL_BUTTON,
"333333333",
WS_CHILD | WS_VISIBLE ,
WS_EX_NONE,
103,
50, 100, 105, 40, hWnd, 0);
break;
}
case MSG_COMMAND:
{
break;
}
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
static LRESULT pwdlogin_window_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
printf("message in : %d \n", message);
switch (message)
{
case MSG_CREATE:
{
hWnd = CreateWindowEx(CTRL_BUTTON,
"222222",
WS_CHILD | WS_VISIBLE ,
WS_EX_NONE,
101,
50, 100, 105, 40, hWnd, 0);
break;
}
case MSG_COMMAND:
{
if(101 == wParam)
{
MoveWindow(hWnd,0,-100,200,200,TRUE);
DLGTEMPLATE stDlg;
memset(&stDlg, 0, sizeof(stDlg));
stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
stDlg.dwExStyle = WS_EX_NONE;
stDlg.x = 0;
stDlg.y = 0;
stDlg.w = 200;
stDlg.h = 200;
stDlg.caption = "1111";
CreateMainWindowIndirectParam(&stDlg, hWnd, pwdlogin_ime_proc, 0);
}
break;
}
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
} static LRESULT HelloWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case MSG_CREATE:
hWnd = CreateWindowEx(CTRL_BUTTON,
"11111111111",
WS_CHILD | WS_VISIBLE ,
WS_EX_TRANSPARENT,
100,
50, 50, 105, 40, hWnd, 0);
break;
case MSG_COMMAND:
if(100 == wParam)
{
DLGTEMPLATE stDlg;
memset(&stDlg, 0, sizeof(stDlg));
stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
stDlg.dwExStyle = WS_EX_NONE;
stDlg.x = 0;
stDlg.y = 0;
stDlg.w = 200;
stDlg.h = 200;
stDlg.caption = "";
CreateMainWindowIndirectParam(&stDlg, hWnd, pwdlogin_window_proc, 0);
}
break;
case MSG_CLOSE:
DestroyMainWindow (hWnd);
PostQuitMessage (hWnd);
break;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
int MiniGUIMain (int argc, const char* argv[]) { MSG Msg; HWND hMainWnd; MAINWINCREATE CreateInfo;
JoinLayer(NAME_DEF_LAYER , "helloworld" , 0 , 0);
CreateInfo.dwStyle = WS_VISIBLE | WS_CAPTION;
CreateInfo.dwExStyle = WS_EX_NONE;
CreateInfo.spCaption = "Hello";
CreateInfo.hMenu = 0;
CreateInfo.hCursor = GetSystemCursor(0);
CreateInfo.hIcon = 0;
CreateInfo.MainWindowProc = HelloWinProc;
CreateInfo.lx = 0;
CreateInfo.ty = 0;
CreateInfo.rx = 480;
CreateInfo.by = 272;
CreateInfo.iBkColor = COLOR_lightwhite;
CreateInfo.dwAddData = 0;
CreateInfo.hHosting = HWND_DESKTOP;
hMainWnd = CreateMainWindow (&CreateInfo);
if (hMainWnd == HWND_INVALID)
return -1;
ShowWindow(hMainWnd, SW_SHOWNORMAL);
while (GetMessage(&Msg, hMainWnd)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
MainWindowThreadCleanup (hMainWnd);
return 0;
}
由于网络问题无法上传文件,代码在上面,死锁的图片就不提供了,麻烦看一下啦,用的线程模式
这个仿照出现死锁情况的业务代码逻辑写的一个demo
ok, thanks!
请确认修复并反馈。修复在 rel-5-0 分支中。若无问题,将合并到 master 分支,并发布 5.0.10 版本。
谢谢!
目前看来已经修复,我这边业务逻辑也没有出现死锁了,谢谢!期待5.0.10发布!
好的!
前提:在创建对话框以后,对齐进行整个移动,MoveWindow()的操作(这里我们是输入框向上移动) 操作:然后通过CreateMainWindowIndirectParam()创建一个新的对话框(这里我们是基于对话框创建创建键盘),这个ui卡住,但是不崩溃 问题排查: 通过CreateMainWindowIndirectParam()创建基于对话框的键盘会默认 走到dialog.c中 hMainWin = CreateMainWindowEx (&CreateInfo, werdr_name, we_attrs, window_name, layer_name); 如上的创建函数里面。 进一步跟到:window.c中 if (SendMessage (HWND_DESKTOP, MSG_ADDNEWMAINWIN, (WPARAM) pWin, 0) < 0) goto err; 进一步跟到:desktop-comm.c中 case MSG_ADDNEWMAINWIN:
ifdef _MGHAVE_MENU
endif
再跟到:desktop.c中 dskMoveWindow AllocZOrderNodeEx()函数: 到这个函数走不下去了,发现卡在lock_zi_for_change(zi)走不下去了,发现该值为负值溢出为正,导致进行一次unlock后没有归零,无法进行写操作。 然后分析前后因果关系发现是由MoveWindow()导致的,所以去检查MoveWindow(); 跟到:desktop.c中的 dskMoveWindow()函数中:发现在 update_client_window_rgn (nodes [idx_znode].cli, nodes [idx_znode].hwnd); 这句下面有一句 / unlock zi for change ... / unlock_zi_for_change (zi); 解锁函数,这里与minigui3不同样,minigui3将这句话放在了稍微前面一点的EmptyClipRgn (&sg_UpdateRgn);之后;
看到提交记录里面有对其进行一个修改,但是修改并不生效。
***归结起来分析出来就是在desktop.c中的dskMoveWindow()函数中,有一句unlock_zi_for_change (zi);被移动了位置,导致进行一次unlock后没有归零,无法进行写操作,但是我尝试按照3.0的思路移动到前面,却不起任何作用,打算跟一步跟进的时候发现内部实现过于复杂了,所以想问一下是不是有解决方法