重复delete 对象指针后的 异常调用栈怪异 解析
Release版VC6 MFC程序 程序正常退出时得到一个如下异常调用栈:
0:000> kb
# ChildEBP RetAddr Args to Child
WARNING: Frame IP not in any known module. Following frames may be wrong.
00 0019eb94 76124f2f 00c3afc8 0019ebdc 0019ebb8 0x8c73d01
01 0019ebdc 0079451a 00c3afc8 73d82ec0 00000001 USER32!IsZoomed+0xaf
02 0019ebe4 73d82ec0 00000001 73d35d1c 00c3afc8 JXC_MED!CMainFrame::`scalar deleting destructor'+0x8
03 0019ebec 73d35d1c 00c3afc8 00000000 73d35c0f MFC42!CControlFrameWnd::PostNcDestroy+0xb
04 0019ec2c 73d31e1d 00c3afc8 00c3afc8 00cae670 MFC42!CWnd::OnNcDestroy+0x10d
05 0019eca4 73d31b07 00000082 00000000 73dca448 MFC42!CWnd::OnWndMsg+0x2f4
06 0019ecc4 73d31a78 00000082 00000000 00000000 MFC42!CWnd::WindowProc+0x22
07 0019ed24 73d319d0 00c3afc8 00000000 00000082 MFC42!AfxCallWndProc+0x91
08 0019ed44 73dbe00c 00031002 00000082 00000000 MFC42!AfxWndProc+0x34
09 0019ed70 76135cab 00031002 00000082 00000000 MFC42!AfxWndProcBase+0x39
0a 0019ed9c 761267bc 73dbdfd3 00031002 00000082 USER32!_InternalCallWinProc+0x2b
0b 0019ee80 7612635a 73dbdfd3 00000000 00000082 USER32!UserCallWinProcCheckWow+0x3ac
0c 0019eee4 76133f87 01225f90 00000000 00000082 USER32!DispatchClientMessage+0xea
0d 0019ef28 77e62add 0019ef44 00000020 0019efac USER32!__fnNCDESTROY+0x37
0e 0019ef60 73d364c5 00031002 009a034c 009a1f14 ntdll!KiUserCallbackDispatcher+0x4d
0f 0019ef74 00794760 009a8968 00000000 00c3afc8 MFC42!CWnd::DestroyWindow+0x31
10 0019efb8 73d38fb4 00c3afc8 00c3afc8 00794965 JXC_MED!CMainFrame::DestroyWindow+0x13c [F:\Yangl\兰州专版\02 JXC_MED_YX_WL\MainFrm.cpp @ 852]
11 0019efd0 02b056f3 00000000 00794a45 00c3afc8 MFC42!CFrameWnd::OnClose+0xf5
12 0019efec 007949a3 00000000 73dca64c 00000001 ToolLib!CTFrameWnd::OnClose+0x13
13 0019f044 73d31e1d 00c3afc8 00c3afc8 00cae670 JXC_MED!CMainFrame::OnClose+0x3e [F:\Yangl\兰州专版\02 JXC_MED_YX_WL\MainFrm.cpp @ 1133]
顶层两个函数调用帧都是错的,地址怪异 ,没有函数名子通过反汇编校验,根据帧返回地址是 0079451a 判断出具体函数源码位置, 不及格的程序员-八神
JXC_MED!CMainFrame::`scalar deleting destructor':
00794512 56 push esi
00794513 8bf1 mov esi, this (ecx)
00794515 e814000000 call JXC_MED!CMainFrame::~CMainFrame (79452e) //顶层栈实际上是在调用此析构函数中的代码
0079451a f644240801 test byte ptr [esp+8], 1
0079451f 7407 je JXC_MED!CMainFrame::`scalar deleting destructor'+0x16 (794528)
00794521 56 push esi
00794522 e8338c0000 call JXC_MED!operator delete (79d15a)
00794527 59 pop this (ecx)
00794528 8bc6 mov eax, esi
0079452a 5e pop esi
0079452b c20400 ret 4
JXC_MED!CMainFrame::~CMainFrame:
0079452e b806828200 mov eax, 828206h
00794533 e8489b0000 call JXC_MED!__EH_prolog (79e080)
00794538 51 push this (ecx)
00794539 51 push this (ecx)
0079453a 56 push esi
0079453b 8bf1 mov esi, this (ecx)
0079453d 57 push edi
0079453e 8975f0 mov dword ptr [ebp-10h], esi
00794541 c70668a98800 mov dword ptr [esi], 88A968h
00794547 8b8e58040000 mov this (ecx), dword ptr [esi+458h]
0079454d c745fc06000000 mov dword ptr [ebp-4], 6
00794554 85c9 test this (ecx), this (ecx)
00794556 7407 je JXC_MED!CMainFrame::~CMainFrame+0x31 (79455f)
00794558 8b01 mov eax, dword ptr [this(??) (ecx)] //通过指令飞越技术查出是这里出错,代码对应 delete loadWareWork;
0079455a 6a01 push 1
0079455c ff5004 call dword ptr [eax+4]
0079455f a150889a00 mov eax, dword ptr ds:[009A8850h]
00794564 83780400 cmp dword ptr [eax+4], 0
00794568 741f je JXC_MED!CMainFrame::~CMainFrame+0x5b (794589)00794623 c3 ret
CMainFrame::~CMainFrame()
{
if(loadWareWork) delete loadWareWork; //这个被重复删了 导至出错
if (gpDb->IsOpen())
{
WriteOpLog(gpDb, gstrOprCode, GSP_OPLOG_MODULEID, "2", "退出系统");
}
}
图1:指针飞越技术重现@eip内存地址 0x8c73d01
解决办法,将这段代码删掉,此处多余的代码,理由是此类型是CWnd子类。不及格的程序员-八神
创建时使用WS_CHILD类型创建,它会随着父窗体自动DESTORY, 并且子类重载函数 PostNcDestroy 并 delete this了,不需要这里再次delete。
重复delete 对象指针后的 异常调用栈怪异 解析的更多相关文章
- windows C++ 异常调用栈简析
楔子 以win11 + vs2022运行VC++ 编译观察的结果. 如果安装了Visual Studio 2022,比如安装在D盘,则路径: D:\Visual Studio\IDE\VC\Tools ...
- delete 类对象指针的注意事项]
http://blog.csdn.net/infoworld/article/details/45560219 场景:1. C++类有构造和析构函数,析构函数是在类对象被delete时(或局部变量自动 ...
- delete之后千万要记得将指针置空,即勿重复delete!!!
下面这段代码有什么问题吗?(Arduino上运行) class C{ public: C(){ ptr = ]; } ~C(){ if(ptr!=NULL)delete [] ptr; } void ...
- C++在delete指针后要赋值为NULL
C++标准规定:delete空指针是合法的,没有副作用. 所以我们在Delete指针后赋值为NULL或0是个好习惯.对一个非空指针delete后,若没有赋NULL,若再次delete的话 有可能出现问 ...
- linux C 刚初始化后的一个变量在调用一个静态库中函数后被异常修改为乱码
linux C 中声明并初始化一个变量const char a[512]="test";后,接着调用了一个静态库中的函数函数test(b);,a并没有传入test函数,但在调用这个 ...
- delete了,析构函数却没有调用
析构函数在对象的生命结束时,会自动调用,大家所熟知的智能指针就是根据析构函数的这种特性而实现的,包括Qt的内存管理机制,也都是利用了析构函数的这一机制来实现的.c++创始人Bjarne Stroust ...
- 异常处理与MiniDump详解(2) 智能指针与C++异常
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie 讨论新闻组及文件 一. 综述 <异常处理与MiniDump详解(1) C++异常>稍 ...
- 值为NULL的对象指针
相信大家对NULL不会很陌生,NULL 是一个标准规定的宏定义,用来表示空指针常量,当一个指针变量被赋值为NULL时,表示它不再指向任何有效地址,无法在访问任何数据.在VS2012库文件stdio.h ...
- 读书笔记 之《Thinking in Java》(对象、集合、异常)
一.前言 本来想看完书再整理下自己的笔记的,可是书才看了一半发现笔记有点多,有点乱,就先整理一份吧,顺便复习下前面的知识,之后的再补上. 真的感觉,看书是个好习惯啊,难怪人家说“书籍是人类进步的阶梯” ...
- 统一返回对象封装和统一异常捕获封装springboot starter
好久没有更新文章了,高龄开发没什么技术,去了外包公司后没怎么更新文章了.今天分享下统一处理starter,相信开发web系统的时候都是会涉及到前后端的交互,而后端返回数据的时候一般都会统一封装一个返回 ...
随机推荐
- CF1272 B DIV3 ---代码对比
这次DIV3有点可惜啊,题解是我的与学长的代码对比 学长的原博客https://www.cnblogs.com/xyq0220/p/12036109.html B.Snow Walking Robot ...
- 2020.3.9 ~ 2020.3.15 ACM训练周总结
一.本周ACM学习相关内容 学习了dfs和bfs -- 4小时 课上系统的学习了vector等stl函数的使用即注意事项-3小时 二.题数与耗时 师哥安排了12道题,做了五道(不包含比赛题):大概4个 ...
- JVM - 1.内存结构
1 内存结构 1.1 程序计数器 1.1.1 作用 在执行的过程中 , 记住下一条jvm指令的执行地址 物理上通过寄存器实现 1.1.2 特性 每个线程都有自己的程序计数器 - 线程私有 不会存在内存 ...
- Vue的Component name报错
问题描述: Component name "xxxxx" should always be multi-word.eslintvue 解决方案: 在项目目录中找到 .eslintr ...
- Matlab %肆
第四章:Graph Plot form 'Data' plot(x,y); plot(y); %x = [1-n], n = length(y) EG1: plot(cos(0:pi/20:2 ...
- 使用angular/cli新建一个angular项目
1.打开cmd,进入你代码保存的文件夹,你想把新建的项目保存在哪个文件夹,即进入哪个文件夹: 我把文件放到这里: 然后,使用下面的命令创建项目: // ng new 项目名称,如下示例:创建名为 he ...
- python调用java&反编译地址
反编译工具地址: https://github.com/java-decompiler/jd-gui/releases 你想知道的JPype全在这里∞ 先总结自己趟的坑 1. python进程是6 ...
- springBoot的全局异常处理
GlobalException.java package com.bank.util; import com.bank.exception.ContentEmpyException; import c ...
- 智汇成城 ,创赢未来 | AI+产业峰会智慧城市专场在深成功举办!
11月4日下午,由福田区人才工作局指导,广州英码信息科技有限公司和共达地创新技术(深圳)有限公司联合主办,深圳市人工智能行业协会承办的AI+产业峰会之智慧城市专场活动在深圳市南山区成功举办. &quo ...
- Win32窗口设置为透明
可以使用以下方法将Win32窗口设置为透明: 定义窗口类时,在WNDCLASSEX结构体中设置hbrBackground成员为NULL. 在窗口创建时,使用WS_EX_LAYERED风格和SetLay ...