vs2019 - 使用IDA定位已经被捕获的异常

2023-12-28 18:37:04

vs2019 - 使用IDA定位已经被捕获的异常

概述

正在测试程序的功能, 用VS2019开着调试版跑起来. 发现程序关闭后, 在VS2019的输出窗口发现了C++异常的信息, 还不是一条.
在这里插入图片描述
虽然不影响程序的运行, 但是心里膈应.
这种异常发生了, 但是没被VS2019断下来, 说明这4个C++异常是在工程中被try-catch住的.
我现在这个程序, 主动使用try-catch的地方不多. 如果在每个try-catch住的地方下断点倒是可以.
但是为了普遍性, 还是要找出一种不依赖断点无脑排错的调试方法.

笔记

将debug版编译好, 用IDA带着跑起来.
用IDA载入EXE时, 因为是载入的Debug版程序, 连同PDB一起载入.
选择本地调试器
在这里插入图片描述
跑起来.
进行一样的操作, 发现IDA断住异常了:)
在这里插入图片描述
按确定后, 让程序自然暂停住.
打开栈调用链窗口
在这里插入图片描述
在这里插入图片描述
因为出了异常, 栈调用链不是很准.
但是能看到最上层的函数是COrderOperation::static_thread_dispatch().
那现在就可以有的放矢了, 关掉IDA.
只在COrderOperation::static_thread_dispatch()上下断点.
然后重新用VS2019跑程序, 到了发现报错的疑似顶层函数, 步入, 然后步过, 看看执行过那步, 会在VS2019输出窗口显示被捕获的异常信息.
如此这般, 就会很快缩小排查范围. 最后定位并修复问题.

我这里发下的问题是, 删除文件的函数做了try-catch, 如果删除了不存在的文件, 就会抛异常, 并被函数内的catch捕获住. 修正如下:

bool CFileOperation::Delete(CString sPathName)
{
	try {
		// 如果文件存在, 才删除, 防止出异常.
		// 虽然这里被catch住了, 总的来说不好
		if (!this->IsFileExist(sPathName))
		{
			return true;
		}

		DoDelete(sPathName);

	} catch (CFExeption* e) {
		m_sError = e->GetErrorText();
		m_dwError = e->GetErrorCode();
		delete e;

		if (m_dwError == 0) {
			return true;
		}

		return false;
	}

	return true;
}

备注

虽然被try-catch住的异常, 不会引起程序的功能出问题. 但是也说明可能哪里出了问题, 如果能在逻辑上将异常搞定, 让他不出异常, 感觉更好一点.

修正完后, 又跑了一次, 程序退出后, 在VS2019的输出窗口没有任何发生c++异常的提示信息了:P

补充

又想了一下, 既然是自己try-catch, 那么自然知道是哪里catch的, 为何不在catch中, 用框架提供的功能, 整点动静出来, 这样, 也不用第三方调试器辅助调试了.
在这里插入图片描述
在VS2019Debug版程序退出后, 如果在输出窗口看到自己catch住的打印信息的输出, 双击就可以定位到catch住异常的地方了.
这属于自己编码不规范引起的问题.

当然, 发现异常后, 如果有可能修复, 还是要修复.

备注

这种用IDA来辅助定位问题的方法, 对于自己的工程可能有点脱裤子放屁的感觉.
但是对于自己接手维护的不规范工程(e.g. 不是自己写的工程(刚接手, 还没深入理解), 开源工程(代码行数大, 看不过来, 刚接触的工程, 逻辑理解的有点懵懂), 遗留的烂工程(可能就是自己以前写的工程)), 还是管点用.

END

文章来源:https://blog.csdn.net/LostSpeed/article/details/135273928
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。