zoukankan      html  css  js  c++  java
  • DrGraph软件升级:处理BUG_退出程序出错

    简要说明

    1. 退出程序出错(解决1/2)

    提交人

    DrGraph 2013/04/22

    处理状态

    处理中

    同步状态

     

    现象

    退出程序,出现错误:

    详细信息:

    问题签名:

    问题事件名称:    APPCRASH

    应用程序名:    DrGraph.exe

    应用程序版本:    0.0.0.0

    应用程序时间戳:    00000000

    故障模块名称:    ntdll.dll

    故障模块版本:    6.1.7600.16385

    故障模块时间戳:    4a5bdadb

    异常代码:    80000003

    异常偏移:    0009f8d2

    OS 版本:    6.1.7600.2.0.0.256.1

    区域设置 ID:    2052

    其他信息 1:    d1ab

    其他信息 2:    d1ab624ec7d094c26a73530c245a3468

    其他信息 3:    d1ab

    其他信息 4:    d1ab624ec7d094c26a73530c245a3468

    定位及调试过程

    1. 经查,初步定为释放DLL对象时出错
    1. 加上日志输出

    __fastcall TqaDllBase::~TqaDllBase() {

        CBW_LOG(THelper::FormatString("准备:释放动态链接库 %s", FDllFileName.c_str()),

            qdtInterface);

        if (FDeleteDllModel && FDllModelObject) {

            try {

                FDeleteDllModel(FDllModelObject);

                CBW_LOG("成功:删除接口对象", qdtInterface);

            }

            catch(Exception & ex) {

                CBW_LOG(THelper::FormatString("失败:释放动态链接库 %s 时出错:%s", FDllFileName.c_str(),

                        ex.Message.c_str()), qdtInterface);

            }

        }

        if (hDll) {

            FDllCount[hDll] -= 1;

            if (FDllCount[hDll] == 0)

                try {

                FreeLibrary((HMODULE)hDll);

                CBW_LOG(THelper::FormatString("成功:释放动态链接库 %s", FDllFileName.c_str()),

                    qdtInterface);

                }

            catch(Exception & ex) {

                CBW_LOG(THelper::FormatString("失败:释放动态链接库 %s 出现异常 %s",

                        FDllFileName.c_str()), qdtInterface);

            }

        }

    }

    打开日志开关

    1. 查看程序退出时的日志输出

    <Info msg="准备:释放动态链接库 D:\ExenObj\Exe\2010Graph\dll\QaWord.dll" />

    <Info msg="成功:删除接口对象" />

    <Info msg="成功:释放动态链接库 D:\ExenObj\Exe\2010Graph\dll\QaWord.dll" />

    <Info msg="准备:释放动态链接库 D:\ExenObj\Exe\2010Graph\dll\CbwRegExp.dll" />

    <Info msg="成功:删除接口对象" />

    <Info msg="成功:释放动态链接库 D:\ExenObj\Exe\2010Graph\dll\CbwRegExp.dll" />

    <Info msg="准备:释放动态链接库 D:\ExenObj\Exe\2010Graph\dll\CbwImage.dll" />

    <Info msg="成功:删除接口对象" />

    <Info msg="成功:释放动态链接库 D:\ExenObj\Exe\2010Graph\dll\CbwImage.dll" />

    <Info msg="准备:释放动态链接库 D:\ExenObj\Exe\2010Graph\dll\QaVoice.dll" />

    <Info msg="成功:删除接口对象" />

    <Info msg="成功:释放动态链接库 D:\ExenObj\Exe\2010Graph\dll\QaVoice.dll" />

    <Info msg="准备:释放动态链接库 D:\ExenObj\Exe\2010Graph\dll\QaUtil.dll" />

    <Info msg="成功:删除接口对象" />

    <Info msg="成功:释放动态链接库 D:\ExenObj\Exe\2010Graph\dll\QaUtil.dll" />

    1. 说明这里没错,继续跟踪,发现是ClearCbwGraphForm的问题,更进一步,定位在SpecialDebugInfo

    UnicodeString __fastcall SpecialDebugInfo() {

        int size = AllCompilerObjects.size();

        UnicodeString result = THelper::FormatString("共有 %d 个分析对象:", size); // *

        std::map<int, TCbwCompilerObject*>aAllCompilerObjects;

        CBW_ITERATOR_MAP(TCbwCompilerObject*, int, AllCompilerObjects)

            aAllCompilerObjects[it->second] = it->first;

        CBW_ITERATOR_MAP(int, TCbwCompilerObject *, aAllCompilerObjects) {

            TCbwCompilerObject * object = it->second;

            UnicodeString refCount = "";

            TEquation_Variable * ev = dynamic_cast<TEquation_Variable*>(object);

            if (ev)

                refCount.sprintf(L", 引用次数: %d", ev->RefCount);

            try {

                result += THelper::FormatString("\n下标:%d, 地址:%x, 类型:%s, 信息:%s%s",

                    it->first, int(object), UnicodeString(object->ClassName()).c_str(),

                    object->Content.c_str(), refCount.c_str());

            }

            catch(Exception & ex) {

                result += EXCEPTION_INFO + THelper::FormatString

                        ("\n下标:%d(Exception: %s), 类型:%s", it->first, ex.Message.c_str(),

                    UnicodeString(object->ClassName()).c_str());

            }

        } // */

        return result;

    }

    最终原因在于:程序关闭退出时,AllCompilerObjects已被自动释放掉,而此时再调用时将会出错

    1. 修改:

    删除ClearCbwGraphForm()中的

        CBW_LOG(SpecialDebugInfo(), qdtProgram);

    不再输出该日志信息。

    1. 结果状态:此处通过,还是会出现该提示对话框

      检查日志记录到:

      <Info msg="退出工作: delete OperateNames" />

      <Info msg="退出工作: after delete OperateNames" />

      跟踪发现调用~TVariantT后出问题,其构造析构函数调用次数很多,下面跟一下

    构造

    析构

    :008DFCCC

     

    :0012FAC4 { "http://127.0.0.1" }

     

    :0012FA7C

     

    :0012FA6C

     

    :0012FA5C

     

    :0012FA8C

     
     

    :0012FA5C

     

    :0012FA6C

     

    :0012FA7C

     

    :0012FA8C

     

    :0012FAC4

    :0012FB28 { "D:\\ExenObj\\Exe\\2010Graph\\welcome\\index.html" }

     

    :0012FAE0

     

    :0012FAD0

     

    :0012FAC0

     

    :0012FAF0

     
     

    :0012FAC0

     

    :0012FAD0

     

    :0012FAE0

     

    :0012FAF0

     

    :0012FB28

    :0012FA20 { "D:\\ExenObj\\Exe\\2010Graph\\welcome\\index.html" }

     

    :0012F9D8

     

    :0012F9C8

     

    :0012F9B8

     

    :0012F9E8

     
     

    :0012F9B8

     

    :0012F9C8

     

    :0012F9D8

     

    :0012F9E8

     

    :0012FA20

     

    :008DFCCC

    完全匹配

    运行之后提示出错

    但不在IDE下运行是正常的

     
    1. 屏蔽掉退出宏#pragma exit

    #pragma exit GlobalExitWork 64

    #pragma exit DeleteMVCCriticalSection 64

    #pragma exit FreeAllDllObjects 64

    #pragma exit DeleteOperateItemNameList 64

    #pragma exit ClearCbwTreeObject 80

    #pragma exit DestroyGlobalXMLNode 70

    #pragma exit DestroyDefaultVclClasses 70

    #pragma exit ClearCbwGraphForm 80

    #pragma exit ClearCbwObject 80

    #pragma exit DestroyObjectTypeList 80

    #pragma exit DestoryExecuteXML 70

    #pragma exit DestoryUDPObject 80

    之后,程序退出正常

    逐个添加上:

    #pragma exit GlobalExitWork 64 à OK

    #pragma exit DeleteMVCCriticalSection 64 à OK

    #pragma exit FreeAllDllObjects 64 à Error

    #pragma exit DeleteOperateItemNameList 64 à OK

    #pragma exit ClearCbwTreeObject 80 à OK

    #pragma exit DestroyGlobalXMLNode 70 à OK

    #pragma exit DestroyDefaultVclClasses 70 à OK

    #pragma exit ClearCbwGraphForm 80 à OK

    #pragma exit ClearCbwObject 80 à OK

    #pragma exit DestroyObjectTypeList 80 à OK

    #pragma exit DestoryExecuteXML 70 à OK

    #pragma exit DestoryUDPObject 80 à OK

    问题定位为FreeAllDllObjects

    输出日志,发现共有5个DLL:

    D:\ExenObj\Exe\2010Graph\dll\QaWord.dll

    D:\ExenObj\Exe\2010Graph\dll\CbwRegExp.dll

    D:\ExenObj\Exe\2010Graph\dll\CbwImage.dll

    D:\ExenObj\Exe\2010Graph\dll\QaVoice.dll

    D:\ExenObj\Exe\2010Graph\dll\QaUtil.dll

    逐个屏蔽DLL

    __fastcall TqaDllBase::~TqaDllBase() {

        static int count = 0;

        if(++count == N)

            return;

    }

    经查,排列屏蔽,发现,任意一个DLL卸载均会导致最终抛出对话框。

    再进一步,发现屏蔽FreeLibrary即可。

    什么原因?

    之前声明hDll为HANDLE类型,中间会强制转换为HMODULE,不会是这个原因吧?

    改成HMODULE类型,运行还是出错。

    现在唯一的解释就是:DLL是用AnsiString实现的,宿主程序是用UnicodeString。但这明显是说不通的。

    另一个解释就是:DLL是用CB6实现的,宿主程序是用CB2010实现的。之前在CB6中不会出错。

    越解释越不通,暂且放下。屏蔽掉FreeLibrary

  • 相关阅读:
    20080619 SQL SERVER 输入 NULL 的快捷键
    20090406 Adobe的“此产品的许可已停止工作”错误的解决办法
    20080908 Office Powerpoint 2007 不能输入中文的解决办法
    20080831 ClearGertrude Blog Skin 's cnblogs_code class
    20080603 Facebook 平台正式开放
    20080519 安装 Microsoft SQL Server 2000 时提示 创建挂起的文件操作
    test
    Linux—fork函数学习笔记
    SOA的设计理念
    Why BCP connects to SQL Server instance which start with account of Network Service fail?
  • 原文地址:https://www.cnblogs.com/drgraph/p/3036782.html
Copyright © 2011-2022 走看看