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. Glass Beads

    UVA719 将循环串SSS展开成两倍大小:S+SS+SS+S,这样线性处理就可以处理所有循环的情况了.对S+SS+SS+S建立一个后缀自动机,让后从初始状态开始走,每次选择字典序最小的道路,走NNN ...

  2. pycharm2019.3.1版本需要的JetBrains Runtime 11不支持windows 32位系统。

    提示信息显示安装pycharm2019.3.1版本需要的JetBrains Runtime 11不支持windows 32位系统. 2.更换pycharm社区版的安装版本 百度找到解决办法,参考文章& ...

  3. 多级路由,重定向之后,刷新页面报错问题:报错Unexpected token '<'

    使用脚手架:vue-cli3.0vue版本:vue3.0vue-router版本:vue-router4.0 配置多级路由,首次访问,到重定向页面没有问题,然后在当前页面刷新控制台报错:Unexpec ...

  4. 【原创】freetype android交叉编译

    项目中Opencv需要显示中文,由于本身并不支持,所以需要借助第三方的库freetype来实现.这个库虽然android本身也有使用,但并没有暴露接口给外部使用. freetype官网 方式1 脚本编 ...

  5. [C#] Func及Action的快速Demo

    参考代码1: using System;using System.Collections.Generic;using System.Linq;namespace FuncActionDemo{    ...

  6. 4.3Dsmax捕捉工具

    平面视图: Line 线 多用于平面视图(按住shift可创建水平或垂直的线) Cirde 圆 Arc 弧形 NGon 多边形 Text 文本 输入中文会出现方框,换一下字体即可 Egg 鹅卵形 re ...

  7. 01-什么是ElasticSearch

    1.什么是搜索? 百度:我们想要查找想要的一些信息比如在百度搜索一本书,一部电影这就是最常见的搜索 但是百度!=搜索 垂直搜索(站内搜索) 互联网的搜索:电商网站,新闻网站,招聘网站,等等 IT系统的 ...

  8. 全新TI AM62xx系列核心板上市,小小身板蕴藏巨大势能!

    2011年TI推出AM335x,成为了此后市场上最受欢迎的通用工业级ARM处理器,并广泛应用于工业HMI, 医疗电子,机器人,能源,汽车等领域.随着工业4.0的发展,HMI人机交互.工业工控.医疗等领 ...

  9. SQL中通过表字段名称查询对应表名称

    select * from sys.objects as a where a.object_id in(select [OBJECT_ID] from sys.all_columns where na ...

  10. Python库之os库和logging库的基本使用说明

    使用os库操作目录及文件 使用os.sep() 方法获取系统分隔符 print(os.sep) 使用os.name()方法获取操作系统的平台类型 print(os.name) 使用os.getcwd( ...