MFC不支持尝试执行的操作 Bug精准定位方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ClamReason/article/details/81348600

上图:程序运行时出现下面的弹出对话框:

问题截图
出问题时的截图

今天成功破获此bug,并给出了完美解决该问题的一般方法,保证准确定位到代码行!

网上一搜都说这是界面控件被删除,但是绑定的成员变量以及界面控件和原来成员变量的转换未被同步删除导致。这一点是毋容置疑的,基本上也的确是这个原因。

所以出问题的代码基本上都长这个样子:    DDX_Control(pDX, IDC_CHECK1, m_v);

对于简单的程序,比如你的程序就一个对话框,就那么几个变量,估计看一下

void CDialogDlg::DoDataExchange(CDataExchange* pDX)

函数的实现部分就能知道是谁的界面控件被删除了。搜一下资源符号IDC_CHECK1有没有在rc文件中出现即可。

但是对于复杂的程序,比如我遇到的,多文档程序,View就三四个,每个里面都有DoDataExchange,你一搜,资源都在,而且有的复杂界面搜资源在不在也很费时,但也算是个比较不错的办法,能有多少绑定变量呢,一个个搜呗。

但我们的程序并不是这样,我们的程序很少出现界面控件被删除成员不被删除的情况,因为都是比较熟练的程序员。我们的程序是多文档,而且出问题的地方在最外层,一开始你肯定想不到是成员绑定导致的。

现在就给出最一般的定位该类问题的方法:

首先,我们只能借助于日志,而且日志必须是实时的,也就是说我希望弹出这个对话框的时候,我就不再操作我的程序了,让程序“卡在这里”。从而我就可以到日志中看到底执行到哪一行代码才导致的这个问题。

为了让日志能够实时刷新,我们需要借助于下面的一个定位标记函数(自己写的,够用了):

std::ofstream fout("C:/yourLog.log")

void print(const std::string& _yourLogTagForLocationTheProblem)

{

    fout<<_yourLogTagForLocationTheProblem<<std::endl;

    fout.flush();//这个会让上面的输出直接刷到文件里,从而让你的程序可以准确定位到问题行。

}

            接下来就是万事俱备,只剩下断点了。下断点很简单 了,找到入口函数,在入口函数里觉得可能的地方调用上面的全局函数写日志,你肯定会在日志中发现:

Log1

Log2

开始弹出报错对话框

Log3(此时未被写入文件)

那么问题就很明显了,出问题的代码就在Log2和Log3之间,如果Log2和Log3之间调用了函数,就在函数内继续此方法进一步定位;如果调用了框架函数,比如OnPaint,OpenDocumentFile(NULL)等,那这时候就要了解MFC的框架机制,看看自己的代码在哪里重载了框架的函数,并在里面设断点。

我定位的情况是:程序调用OpenDocumentFile(NULL)的时候出了问题,根据分析MFC框架机制,最后得出我们的程序创建了三个字窗口View,每个View里面都有调用自己的DoDataExchange,进一步用上面的定位方法得出在第三个View的DoDataExchange中有个绑定变量失败。这个不是界面控件被删除,而是这个控件是一个ocx控件,经过现场测试发现是ocx在安装的时候没能成功注册导致。

至此,问题已经找到,剩下的就是解决为何注册不成功的问题了。锅就不是我的了,呵呵

猜你喜欢

转载自blog.csdn.net/ClamReason/article/details/81348600