1、程序结构是主程序与插件(DLL模式)。主程序提供接口让DLL得到主程序某个类实例(用户数据)的指针,并且是只读模式。不允许删除此指针,所以发布给DLL的此类的头文件没有析构函数。如代码所示。

class IUserData
{
public:
    virtual CString GetName() = 0;
    virtual CString GetUserId() = 0;
    virtual CString GetPrivatePath() = 0;
    virtual CString GetDepartId() = 0;
    virtual const CMapStringToString& GetModuleMap() = 0;
};

问题是这样的,工程师在写程序过程中,在卸载某一接件dll时把从主框架中得到的用户数据指针给删除了。

a,由于暴露给DLL的接口没有提供析构函数,所以在插件中delete此指针时,不会调用析构函数。在析构函数里加断点,程序不会执行到,给程序排错制造了困难。

b,此实例已经被删除,但内存块未被重新分配前,所有的内容操作不会报错。当程序报错时,断点所示的地方很难联想到是用户数据实例被删除引起的。

c,解决过程是,通过调试观察内存发现,用户数据指针所指的区域在某个插件卸载后变为fe ee fe ee,根据经验,这是被delete的结果,之后就找到问题所在了。

 

2、主程序与收发线程。启动收发线程时将主程序建立的Session指针传给收发线程。注销后,Session重新建立,delete后重新new。收发线程也是重新建立,但用的Session指针还是原来被删除的指针,导致问题发生。

a,Session指针已经被删除,但内存块未被重新分配给其它指针前,所有的内存操作不会报错。当程序报错时,断点所示的地方很难联想到是指针被删除引起的。

b,通过调试发现,收发线程里Session的指针所指向的地址没变后,知道问题之所在。

Posted on 2013-04-26 14:27  我不是牛人  阅读(531)  评论(0编辑  收藏  举报