CDHtmlDialog::DisconnectDHtmlElementEvents的怪异问题导致内存访问错误
工程中有2个类使用到,其中A类是正常的,而B类100%出现这个问题。
debug下报错位置:
void CDHtmlDialog::DisconnectDHtmlElementEvents()
{
const DHtmlEventMapEntry* pEventMap = GetDHtmlEventMap(); //此处报错,内存访问冲突
if (!pEventMap)
return;
int i;
// disconnect from element events
for (i=0; i<m_SinkedElements.GetSize(); i++)
{
CDHtmlElementEventSink *pSink = m_SinkedElements[i];
AtlUnadvise(pSink->m_spunkElem, __uuidof(IDispatch), pSink->m_dwCookie);
delete pSink;
}
m_SinkedElements.RemoveAll();
// disconnect from control events
for (i=0; i<m_ControlSinks.GetSize(); i++)
{
DisconnectFromConnectionPoint(m_ControlSinks[i]->m_spunkObj,
m_ControlSinks[i]->m_iid, m_ControlSinks[i]->m_dwCookie);
delete m_ControlSinks[i];
}
m_ControlSinks.RemoveAll();
return;
}查看this指针,发现此时this已经被删了!~~~oxfreefeee之类的,hwnd都是0x00000005什么的了。
因CDHtmlDialog是COM,所以调用堆栈前部分都不可见,且是消息触发,跟玩完。
查看调用堆栈:
1、CDHtmlDialog::_OnBeforeNavigate2()
2、CDHtmlDialog::OnBeforeNavigate()
3、CDHtmlDialog::DisconnectDHtmlEvents()
4、CDHtmlEventSink::DisconnectFromConnectionPoint()
5、CDHtmlDialog::DisconnectDHtmlElementEvents()
在CDHtmlDialog::_OnBeforeNavigate2()加断点,证明了A类、B类进入次数、数据的格式是一样的(格式一样,其实是废话,内存地址、Navigate的url当然不一样)
此处贴出CDHtmlDialog::DisconnectDHtmlEvents()
void CDHtmlDialog::DisconnectDHtmlEvents()
{
CComPtr<IHTMLDocument2> sphtmlDoc;
GetDHtmlDocument(&sphtmlDoc);
if (sphtmlDoc == NULL)
return;
//先调用DisconnectFromConnectionPoint
DisconnectFromConnectionPoint(sphtmlDoc, __uuidof(HTMLDocumentEvents), m_dwDHtmlEventSinkCookie);
//再调用DisconnectDHtmlElementEvents
DisconnectDHtmlElementEvents();
}跟踪到DisconnectFromConnectionPoint,执行前,查看this指针数据正常,执行后this指针被删除了!想必元凶在此,跟进去。
void CDHtmlEventSink::DisconnectFromConnectionPoint(IUnknown *punkObj, REFIID riid, DWORD& dwCookie)
{
AtlUnadvise(punkObj, riid, dwCookie);
}
//再跟进去
ATLINLINE ATLAPI AtlUnadvise(
_Inout_ IUnknown* pUnkCP,
_In_ const IID& iid,
_In_ DWORD dw)
{
if(pUnkCP == NULL)
return E_INVALIDARG;
CComPtr<IConnectionPointContainer> pCPC;
CComPtr<IConnectionPoint> pCP;
HRESULT hRes = pUnkCP->QueryInterface(__uuidof(IConnectionPointContainer), (void**)&pCPC);
if (SUCCEEDED(hRes))
hRes = pCPC->FindConnectionPoint(iid, &pCP);
if (SUCCEEDED(hRes))
hRes = pCP->Unadvise(dw);//到此为止了,vs进不去了
return hRes;
}
A类执行DisconnectFromConnectionPoint函数,返回S_OK,this指针未被修改。
B类执行DisconnectFromConnectionPoint函数,返回S_OK,this指针被修改,地址被删。导致在CDHtmlDialog::DisconnectDHtmlElementEvents()中调用GetDHtmlEventMap()报内存访问错误。
所以,问题出在Unadvise,确切的说是CComPtr<IHTMLDocument2>::Unadvise。
搜了下资料,Unadvise只是将源端、接收端连接断开
请问各位大大,Unadvise内部到底发生了什么事情导致this指针被更改了?
相关推荐
【高速电路设计】基于协议的板级布局指南:差分信号完整性与电源热管理协同优化方案
内容概要:本文档详细介绍了规格补充学习,并在实际项目中配合仿真工具与实测手段进行验证。
科技中介服务机构如何提升技术评估与价值分析的专业性与效率?.docx
科易网基于40亿+科创知识图谱数据库,深度探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。
产业园区运营负责人如何精准识别园区内企业技术需求?.docx
科易网基于40亿+科创知识图谱数据库,深度探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。
RG-EG系列出口网关RGOS配置手册
源码链接: https://pan.quark.cn/s/66d08a7ad775 本指南是锐捷网络为其RG-EG系列出口网关编写的配置指南,其中包含了从基础设置到高级操作的诸多内容。RG-EG系列出口网关是由锐捷网络开发的一款高性能网关设备,该产品专为出口网络场景设计,致力于实现高效且安全的网络数据流量监管与操控功能。以下为指南中所详述的几个核心知识点的阐释: 1. 命令行界面(CLI) 命令行界面是网关设备与使用者进行沟通的关键途径,使用者可通过在CLI中输入特定的文本指令来实施对网关设备的监控与设置。锐捷网络的CLI支持多种命令状态,每种状态所包含的可配置指令不尽相同,这样便于使用者依据不同的管理需求来选用合适的命令状态。 2. 基础管理 基础管理通常涵盖设备的基本设定,例如时间与日期的设定,以及系统软件的更新维护等。对于网关设备而言,基础管理具有至关重要的地位,因为它为网关设备的正常运作打下了坚实的基础。 3. 软件授权管理 软件授权管理涉及确保网关设备运行的是合法的软件版本,并对软件升级和授权进行管理。这有助于维护网络的安全性与设备的稳定性。 4. 系统日志管理 系统日志管理是监控网关设备运行状态的重要方法。通过记录和分析设备运行时的日志信息,网络管理员能够及时发现并处理设备中出现的故障。 5. 异常告警 异常告警功能使网关设备具备了主动识别并汇报潜在问题的能力。通过设定告警条件及接收告警的方式,管理员能够迅速应对设备异常,从而避免可能的网络中断或性能降低。 6. 网络管理 网络管理部分通常涉及对网关设备内各种网络功能的设定与优化,例如路由管理、行为管理等。这些功能对于维持网络的高性能与安全性具有不可替代的作用。 7. WLAN方面配置 对于集成无...
政府科技管理者如何实现科技成果转化项目的精准储备与动态跟踪?.docx
科易网基于40亿+科创知识图谱数据库,深度探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。


HTML/XML
