VincentWei / MiniGUI

A modern and mature cross-platform window system for embedded systems and smart IoT devices.
http://www.minigui.com
GNU General Public License v3.0
694 stars 157 forks source link

关于一个死锁问题 #87

Closed htk719809837 closed 2 years ago

htk719809837 commented 2 years ago

前提:在创建对话框以后,对齐进行整个移动,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

    if (sg_ptmi)
        dskForceCloseMenu ();

endif

    return dskAddNewMainWindow(pWin);

再跟到: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的思路移动到前面,却不起任何作用,打算跟一步跟进的时候发现内部实现过于复杂了,所以想问一下是不是有解决方法

VincentWei commented 2 years ago

请问您的代码基线?是 rel-5-0 分支的最新版本还是 master 分支的最新版本?

htk719809837 commented 2 years ago

我的代码是今年7月13日在minigui官网下载的,因为网络问题并没有通过git拉取,但是按照rel-5-0 分支的2e8eba7dd0a0d3c15f9ed58e7a3b5282e47fa8ca和f76c9187a8f3edb9d64b97826506538a1c324b8b两个提交记录修改以后并没有解开这个死锁

htk719809837 commented 2 years ago

按照#83修改以后似乎并没有被修复

VincentWei commented 2 years ago

请贴一段用于重现该缺陷的代码,可编译为可执行程序的,以方便调试。谢谢!

VincentWei commented 2 years ago

并告知 MiniGUI 的运行模式。

htk719809837 commented 2 years ago

使用的是线程模式,我准备切换到rel-5-0分支去尝试是否解开死锁,但是好像编译方式不太一样,./autogen.sh,也会有报错,看到新增了cmakelist,是不是修改了编译方式呢

VincentWei commented 2 years ago

MiniGUI 5.0 的构建仍然使用的是 autotools,跟 MiniGUI 3.0 没有本质区别,但某些配置选项发生了变化。

您可以参考如下仓库中的构建脚本:

https://github.com/VincentWei/build-minigui-5.0

VincentWei commented 2 years ago

确认了一下,死锁问题是在五月底解决的,是 5.0.9 版本发布之后,代码在 rel-5-0 分支上,尚未合并到 master 分支。

如果习惯使用软件包,可以切换到 rel-5-0 分支,在 PC 上进行配置,然后运行 make dist 命令打包成 5.0.10 的 tar.gz 包然后再放到你自己的项目中构建。

htk719809837 commented 2 years ago

用了最新版本 rel-5-0,死锁并没有解决,能麻烦问一下当时死锁的原因是什么吗,从提交历史只看到了unlock zi for change (zi);移动了位置,还有一处定义改变了,但是并没有解决这个问题,在3.0中不存在这个死锁,如果有时间我会提供一个demo,不过还是想了解一下死锁产生的原因,谢谢!

VincentWei commented 2 years ago

属于缺陷。要快速解决您遇到的问题,还是要给出可以重现缺陷的代码,这样才能帮我们快速定位问题、解决问题。

htk719809837 commented 2 years ago

include <minigui/common.h>

include <minigui/minigui.h>

include <minigui/gdi.h>

include <minigui/window.h>

include <minigui/control.h>

include

include

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;

ifdef _MGRM_PROCESSES

JoinLayer(NAME_DEF_LAYER , "helloworld" , 0 , 0);

endif

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;

}

ifdef _MGRM_THREADS

include <minigui/dti.c>

endif

由于网络问题无法上传文件,代码在上面,死锁的图片就不提供了,麻烦看一下啦,用的线程模式

htk719809837 commented 2 years ago

这个仿照出现死锁情况的业务代码逻辑写的一个demo

VincentWei commented 2 years ago

ok, thanks!

VincentWei commented 2 years ago

请确认修复并反馈。修复在 rel-5-0 分支中。若无问题,将合并到 master 分支,并发布 5.0.10 版本。

谢谢!

htk719809837 commented 2 years ago

目前看来已经修复,我这边业务逻辑也没有出现死锁了,谢谢!期待5.0.10发布!

VincentWei commented 2 years ago

好的!