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 对象指针后的 异常调用栈怪异 解析的更多相关文章

  1. windows C++ 异常调用栈简析

    楔子 以win11 + vs2022运行VC++ 编译观察的结果. 如果安装了Visual Studio 2022,比如安装在D盘,则路径: D:\Visual Studio\IDE\VC\Tools ...

  2. delete 类对象指针的注意事项]

    http://blog.csdn.net/infoworld/article/details/45560219 场景:1. C++类有构造和析构函数,析构函数是在类对象被delete时(或局部变量自动 ...

  3. delete之后千万要记得将指针置空,即勿重复delete!!!

    下面这段代码有什么问题吗?(Arduino上运行) class C{ public: C(){ ptr = ]; } ~C(){ if(ptr!=NULL)delete [] ptr; } void ...

  4. C++在delete指针后要赋值为NULL

    C++标准规定:delete空指针是合法的,没有副作用. 所以我们在Delete指针后赋值为NULL或0是个好习惯.对一个非空指针delete后,若没有赋NULL,若再次delete的话 有可能出现问 ...

  5. linux C 刚初始化后的一个变量在调用一个静态库中函数后被异常修改为乱码

    linux C 中声明并初始化一个变量const char a[512]="test";后,接着调用了一个静态库中的函数函数test(b);,a并没有传入test函数,但在调用这个 ...

  6. delete了,析构函数却没有调用

    析构函数在对象的生命结束时,会自动调用,大家所熟知的智能指针就是根据析构函数的这种特性而实现的,包括Qt的内存管理机制,也都是利用了析构函数的这一机制来实现的.c++创始人Bjarne Stroust ...

  7. 异常处理与MiniDump详解(2) 智能指针与C++异常

    write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie 讨论新闻组及文件 一.   综述 <异常处理与MiniDump详解(1) C++异常>稍 ...

  8. 值为NULL的对象指针

    相信大家对NULL不会很陌生,NULL 是一个标准规定的宏定义,用来表示空指针常量,当一个指针变量被赋值为NULL时,表示它不再指向任何有效地址,无法在访问任何数据.在VS2012库文件stdio.h ...

  9. 读书笔记 之《Thinking in Java》(对象、集合、异常)

    一.前言 本来想看完书再整理下自己的笔记的,可是书才看了一半发现笔记有点多,有点乱,就先整理一份吧,顺便复习下前面的知识,之后的再补上. 真的感觉,看书是个好习惯啊,难怪人家说“书籍是人类进步的阶梯” ...

  10. 统一返回对象封装和统一异常捕获封装springboot starter

    好久没有更新文章了,高龄开发没什么技术,去了外包公司后没怎么更新文章了.今天分享下统一处理starter,相信开发web系统的时候都是会涉及到前后端的交互,而后端返回数据的时候一般都会统一封装一个返回 ...

随机推荐

  1. heimaJava-网络编程

    Java 网络编程 概念 网络编程可以让程序与网络上的其他设备中的程序进行数据交互 网络通信基本模式 常见的通信模式有如下两种形式,Client-Server(CS),Browser/Server(B ...

  2. Node.js+Vue.js开发王者荣耀手机端官网

    一.项目初始 1.工具安装和环境搭建 node.js.npm.mongodb 编辑器:VScode 2.项目初始化 项目分为三个部分,分别是移动端界面.后台管理界面和node.js开发的整体的服务端 ...

  3. 助教工作总结(高级语言程序设计C语言)

    * { font-family: 宋体 } zw { font-size: 20px; line-height: 2em } 一.助教工作的具体职责和任务   在本学期担任陈欣老师的计科专业21级c语 ...

  4. STM32使用DMA接收不定长数据

    开启串口,是能串口全局中断 配置DMA并勾选Memory选项 继续配置工程并且生成代码 添加一些串口通讯使用的全局变量 #define BUFFER_SIZE 128 uint8_t Tx_Buf[5 ...

  5. python之自动化连连看脚本-第一关不动-小记

    (如想转载,请联系博主或贴上本博地址) 仅供学习python之用,勿用做商业用途.运行环境为1920*1080屏幕,python3.7,win7,谷歌浏览器版本 75.0.3770.100. 参考ht ...

  6. maven插件汇总

    编译Java源码,一般只需设置编译的jdk版本 <plugin> <groupId>org.apache.maven.plugins</groupId> <a ...

  7. 【攻防世界】web练习区write up

    目录: view_source robots backup cookie disabled button weak auth simple php xff referer webshell get p ...

  8. vue 缓存后台获取的token

    代码 localStorage.setItem("token",res.data.data);// 用localStorage缓存token值

  9. 如何获取obs视频帧的二进制数据

    前面几篇文章梳理了obs的录屏和推流流程,几条纵线整理下来,算是基本理清了obs的工作流程. 现在回到第一个目标:捕捉桌面的帧数据,用rendertarget显示并输出到UE5材质. 那么,帧数据到底 ...

  10. Python——基础知识(一)

    1. 那么多编程语言,为什么学python 易于学习,是所有编程语言当中最容易学习的 没有最好的语言,只有最合适的语言 2. 反复执行的用例如何提升效率 测试流程回归(回顾) 很多测试用例在不同的测试 ...