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. 转发 关于Windows安装解压版MySQL出现服务正在启动-服务无法启动的问题

    部分转自 :https://blog.csdn.net/u013901768/article/details/80707307 我是从服务器上复制了mysql的整个目录,到本地,然后怎么也不好用,看了 ...

  2. VS中多字节字符集和UNICODE字符集的使用说明

    两者的核心区别: 1.在制作多国语言软件时,使用Unicode(UTF-16,16bits,两个字节).无特殊要求时,还是使用多字节字符集比较好. 2.如果要兼容C编程,只能使用多字节字符集.这里的兼 ...

  3. C语言和C++的区别与联系(详细)

    文章转自:https://blog.csdn.net/cherrydreamsover/article/details/81835976 在学习了C语言和C++之后,这两者之间的区别我们需要仔细的捋一 ...

  4. gdb调试数组访问越界记录

    综述 问题来源于力扣的一道域名访问统计题目,我本想以建立首字母索引的方式去统计,但是在申请子域名buffer的地方发现使用malloc(sizeof(char)4)申请出来的buffer每次+1只能增 ...

  5. Vue解决后台传过来的时间展示时带T

    用空格替换: {{scope.row.ctime.toLocaleString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '')}} 参考作者:https: ...

  6. celery介绍安装以及基本使用步骤

    目录 一.关于celery 二.celery架构的构成 1 任务中间件 Broker, 2 任务执行单元 worker 3 结果存储 backend 三.celery的应用场景 1. 异步执行:解决耗 ...

  7. Android笔记--视图显示

    视图显示 视图的宽高设置 方式一:在.xml文件中设置视图的宽和高 通过调用android:layout_width设置视图的宽 通过调用android:layout_height设置视图的高 宽和高 ...

  8. Activiti7开发(五)-我的审批历史

    查看本人审批过的历史 public AjaxResult historyFromData(@RequestParam(value = "businessKey",required ...

  9. mybatis-plus update的三种方式

    参考博客:https://blog.csdn.net/weixin_44162337/article/details/107828366 1.最常见:根据id更新,xxxService.updateB ...

  10. 基于Sekiro的jsRPC的使用和安装

    什么是jsRPC 说实话在介绍 JSRPC 我向大家推荐一个库 Selenium-wire 感觉和JSrpc的原理很像 RPC指远程过程调用,APP里面的RPC大家比较熟悉了. 那什么是jsRPC,顾 ...