WinCE下应用程序错误的解决之道

 


       这个对话框,大家应该都不陌生。程序员做开发时经常会见到,用户肯定也曾被它骚扰过。很显然,这是软件的BUG所致。软件中存在的BUG肯定是会出现的,只是时间的问题,或早或晚,有些很幸运在测试时就会被发现,那些不幸的就成了客户抱怨的缘由。所以,我们不能抱有侥幸心理,而应该想办法来解决这类问题。

       对于软件的BUG来说,扼杀于摇篮当然是最根本的解决办法。尽量编写没有BUG的代码,必要时主动在代码中添加一些异常处理,让程序决断如何处理。很多语言都提供了异常处理的机制,但BUG似乎只能减少,而不可消灭。在嵌入式系统中,由于硬件及工作状态的差异,有些貌似万无一失的代码也常常出现BUG。所以,编写一个完全没有BUG的软件,是我们的理想与追求,但同时也需要我们做最坏的准备。也许某个三更半夜,就会被一个莫名的BUG折腾得焦头烂额。

       产品发布之前,会有很系统的测试,包括硬件和软件。对一个产品来说,测试的重要性不言而喻。尽可能在测试阶段发现所有的问题,而不要将这些问题留给客户。前两天听开发组的同事惊呼“这个BUG也被你们发现了,你们的测试功夫实在了得”。原来是他调用一函数时用错了一个参数,测试组的同事愣是把它揪了出来。另外一个关于汉字排序出错的BUG,也被测试组发现了。但要不要改,开发组的几个人争得面红耳赤。最后老邓都有些火了,他的意思是即使BUG再不易重现,客户也许从不会碰到,但只要确实有问题,就得Fix掉。另外的人觉得Fix这个BUG,太繁琐,不值得花太多时间。最后估计还是得听老邓的,发现了的BUG一定彻底解决!但测试也只能是解决一部分问题,毕竟还有可能存在暂时没有发现的BUG。这些BUG最终会在客户手上爆发。

       产品发布之后,平静了一段时间,终于有一天,客户抱怨来了,软件有BUG,出现系统崩溃的情况。询问再三,却没有更多的有利于Debug的信息。这不是客户的责任,毕竟他们不是专业的测试人员。要重现这个BUG也非常很困难。不过,幸运的是针对这种情况,WinCE提供了类似于桌面Windows的一套错误报告系统。通过它,我们能把一些软件BUG出现时的情况记录下来,有利于分析BUG的诱因,从而解决BUG。我发现M8似乎就采用了类似的机制,在Disk目录下,会看到一些LOG文件和edb_err.txt文件。

       综上,解决软件BUG的问题,有三道关口,第一关,编写代码时,止于源头,第二关, 系统测试时,斩立决,第三关,用户发现后,须立等可取。这三点说起来简单,实际上都有很大的学问,即所谓道,是需要花大量时间,研习许多资料才能了解的。

       以上说的是正道,下面再说点旁门左道,也是我目前碰到的问题。产品发布了,有少数用户报告有BUG,甚至发来如上所示的图。系统本身是有有看门狗的,但等看门狗复位系统的时间太长,需要几分钟。由于种种原因,现在也不可能到代码中去找错,有些部分甚至是没有源码的。目前的处理机制是,出现如上所示的对话框后,点击“OK”按钮,程序会关闭,然后另外的程序会再运行该出错关闭的程序。所以,我需要做的事情就是如何跳过这个提示对话框,让出错程序直接关闭。简单分析之后,有两个想法,一个是修改WinCE内核,修改异常处理部分的代码,出现此类异常时,直接关闭对应的进程。另一个是写个应用程序,模拟用户点击“OK”按钮的操作。第一种方法似乎可行,在Windows XP中可禁用错误报告,也可禁用通知,但在WinCE下没找到该开关。所以需要修改内核代码,并重新编译,这感觉有点不妥。第二种方法,直截了当,担心的问题是系统额外的消耗。很显然这个程序得一直运行着,并检测出错窗口,一旦出错,马上将其关掉。如果这个程序的系统消耗很小,那也不失为一个缓兵之计。当然,要从根本上解决问题,还得走正道。

       简单写了个Savior.exe,在模拟器上测试了一下,系统消耗基本可以忽略,下图为证,包括了异常出现前后的两个时间段,可以看到,都在0.5%以下。如果能暂时缓解一下问题,这点消耗是完全可以接受的。 


       在模拟器中,配合Crash.exe测试了一下,基本实现了左道的功能。Savior.exe的源代码如下:

 

Code
#include<windows.h>

//定义出错类型,列举所有出错提示框的信息
const TCHAR *szErrorInfo[] = 
{
    _T("致命的应用程序错误"),
    _T("应用程序错误"),
    _T("Fatal Application Error"),
    _T("Application Error"),
    NULL,
};

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPTSTR    lpCmdLine,
                   int       nCmdShow)
{
    HANDLE hMutex = CreateMutex(NULL,FALSE,_T("SAVIOR"));
    if (hMutex)
    {
        if(ERROR_ALREADY_EXISTS == GetLastError())
        {
            return FALSE;
        }
    }

    TCHAR szPath[256];
    while (1)
    {
        HWND hWnd = NULL;        
        for (int i = 0;szErrorInfo[i];i++)
        {
            if (szErrorInfo[i])
            {
                hWnd = FindWindow(NULL,szErrorInfo[i]);
                if (hWnd)
                {
                    //查找到出错提示对话框
                    DWORD dwProcessID;
                    
                    //获取出错进程ID
                    GetWindowThreadProcessId(hWnd,&dwProcessID);
                    
                    //获取出错进程句柄
                    HMODULE hProc = (HMODULE)OpenProcess(0,FALSE,dwProcessID);
                    if (hProc)
                    {
                        //获取出错进程对应的EXE
                        GetModuleFileName(hProc,szPath,255);
                    }
                    
                    //关闭出错提示对话框
                    SendMessage(hWnd,WM_CLOSE, 0, 0);
                    Sleep(3000);

                    //重新启动出错应用程序
                    PROCESS_INFORMATION pi;    
                    if (CreateProcess(szPath,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&pi))
                    {
                        CloseHandle(pi.hProcess);
                    }
                }
            }
            Sleep(100);
        }        
        Sleep(1500);
    }
    return TRUE;
}

      由于Crash.exe是一启动就出错的程序,所以,两个程序一起测试时,会陷入一个循环,出错重启,还出错还重启。在实际的项目中应该避免该情况,可以增加一个黑名单的功能,如果重启次数超过5次,就将该程序列入黑名单,关闭后不再重启。另外,针对出错信息形形色色,可以将其写入到文件或注册表中,便于后续增加错误信息的定义。左道的实际效果如何,还需拿到真机上测试。在某些无头设备中,用户没有办法点击弹出的出错提示框时,左道也能发挥作用,似乎还有些不可替代。

       WinCE下应用程序错误的解决之道,漫漫,可正,可邪,须上下求索。

时间: 2024-10-07 11:07:54

WinCE下应用程序错误的解决之道的相关文章

xp系统svchost.exe应用程序错误怎么解决

  xp系统svchost.exe应用程序错误怎么解决        为什么会出现svchost.exe应用程序错误的提示?让我们一起通过文章来看看吧. svchost.exe是Windows操作系统中的一个系统程序,它对系统的正常运行起到了重要的作用. svchost.exe文件存在于X:Windows/system32目录下,是Windows 系统中核心的重要进程 ,它可用来运行动态链接库DLL文件,从而启动对应的服务. 如果遇到了svchost.exe应用程序错误的问题有可能是病毒所引起的

win7旗舰版系统安装补丁提示“安装程序错误”如何解决

  win7旗舰版系统安装补丁提示"安装程序错误如何"解决?微软每隔一段时间就会发布新的补丁,win7旗舰版系统用户在安装补丁时提示"安装程序错误,您没有许可来更新"的问题,导致win7系统无法顺利安装补丁,为什么会出现这样情况呢?其实这种现象主要是本地安全设置问题,大家阅读下文,根据具体设置找到解决方法. 具体方法如下 1.按"Win+R"打开"运行"窗口,输入"gpedit.msc"命令后按回车,打开组

svchost.exe应用程序错误的解决方法

svchost.exe应用程序错误的解决方法: svchost.exe是微软Windows操作系统中的一个系统程序,其微软官方对它的解释是:svchost.exe是从动态链接库(DLL)中运行的服务的通用主机进程名称.该程序对系统的正常运行起到了重中之重的作用,而且是不能被结束的. Svchost.exe在哪里? Svchost.exe文件存在于"%system root%system32"(如C:Windowssystem32)目录下,可以说是Windows 系统中核心的重要进程 ,

ps打开图片显示无法完成请求,因为程序错误的解决方法

  最近使用Photoshop CS5文字工具时出现"无法完成请求,因为程序错误";或者"不能完成请求,因为某种原因阻止文本引擎进行初始化"的错误提示,如果遇到这个问题要怎么操作.下面小编就为大家详细介绍一下ps打开图片显示无法完成请求,因为程序错误的解决方法,一同来看看吧! ps打开图片显示无法完成请求,因为程序错误的解决方法 1.这里就以没有发表的经验中的图片为例来说一下,在经验预览图片中,我们在图片上点击右键,然后在列表中选择另存为. 2.接着在它弹出另存为的

xp系统ravmond.exe应用程序错误怎么解决

  xp系统ravmond.exe应用程序错误怎么解决 ravmond.exe应用程序错误的原因: 引发ravmond.exe应用程序错误的原因可能是因为电脑里安装了太多的安全软件,比如图片中出错的Ravmond进程就是瑞星安全软件的进程. ravmond.exe应用程序错误的解决方法: 其实解决这个问题的方法很简单,在电脑里只需要一套安全软件就可以了,如果安装多套软件反而会出现错误冲突导致系统缓慢.关于应用程序错误,内存不能为read提示的问题,有些是在安装某些程序之后出现的,可以找到出现问题

win7安装Adobe Photoshop CS5时出现adobe photoshop程序错误如何解决

  产生错误的原因: Adobe的系列软件会将注册信息存储在一些Sqlite3数据库文件中,随着反复安装.卸载Adobe组件,如Photoshop.Premiere .Dreamweaver.After Effects.Illustrator等等,会残留很多的残留信息,尤其是绿色版的Adobe软件,新安装的版本未能完全清楚之前写入数据库的信息,从而导致无法重新安装软件,这时必须清理数据库文件,方可继续安装. 准备工作及软件: 1.备份需要的数据,如自定义插件.配置等;尝试从控制面板卸载;关闭所有

win8.1系统wuauclt.exe 应用程序错误的解决方法

最近有用户反映Win8.1系统开机后经常弹出wuauclt.exe 应用程序错误 并报错0x8000173c指令引用的0x58a10108内存.该内存不能读为read内存不能为read的错误提示,那么我们先看看wuauclt.exe程序是什么,Wuauclt.exe是Windows自动升级管理程序.该进程会不断在线检测更新. 通过资料发现,该进程为微软实时检测更新的程序,也有网友反映该程序也是win8.1系统卡慢的原因之一,那么要解决这个问题,我们只需要把该程序对应的服务关闭即可. 操作方法:

PHP(FastCGI)在Nginx的alias下出现404错误的解决方法_nginx

本文讲述了PHP(FastCGI)在Nginx的alias下出现404错误的解决方法.分享给大家供大家参考,具体如下: 在Nginx的官方wiki中如下描述 The alias directive cannot be used inside a regex-specified location. If you need to do this you must use a combination of rewrite and root. 在实际使用中alias下面的php返回404,而html确可

未在本地计算机上注册“Microsoft.Jet.OleDb.4.0”提供程序错误的解决方法_数据库其它

最近在做一个导入Excel数据到数据库的程序出现了如下错误: 计算机上注册Microsoft.Jet.OleDb.4.0提供程序错误的解决方法_数据库其它-microsoft.jet.oledb"> 运行环境 数据库:SqlServer2008 R2 OS:Windows Server 2008 R2 IIS:IIS7 解决方法 在应用程序对用的应用程序池的高级设置中设置"启用32位应用程序"为"True"