捕获Windows上的访问违规
Catching access violations on Windows
我试图捕获应用程序中所有未处理的异常,以便在它们发生时保存日志文件。这是一个64位的Windows应用程序,使用Visual Studio 2013编译,用c++编写。为了测试,我使用的是VS.生成的默认c++ Win32项目。
我通过使用SetUnhandledExceptionFilter注册处理程序来捕获所有异常。这适用于大多数情况,但不是全部。所有throw()-n异常都会被捕获,大多数硬件异常(如浮点数或访问违规)也会被捕获。不触发处理程序的代码是:
std::vector<int> foo(5, 0);
for (auto& f : foo)
foo.erase(foo.begin() + 1);
相反,我只是得到标准的windows崩溃对话框,没有我的异常处理程序被调用。但是,如果我在Visual Studio中附带调试器运行它,它会正确报告访问冲突异常。其他类型的访问违规也会触发处理程序:
float* ptr = nullptr;
float value = *ptr;
上面的代码触发异常处理程序。
我也尝试过使用try/catch或捕捉SIGSEGV信号,但第一个例子都没有触发。中止/终止信号也不会被调用。简而言之,当崩溃发生时,我无法得到通知。
我想知道是否有任何方法可以在我的应用程序中获得某种通知,然后由于第一个示例导致的访问冲突而崩溃?既然VS似乎能够检测到它,我假设有一种方法。
编辑:我只是想说清楚,我是在发布模式下运行代码的,第一个例子中的错误不是由在调试模式下完成的迭代器越界检查引起的。
EDIT2:我列举了我所能想到的使用win32控制台应用的最简单的例子。http://pastebin.com/8L1SN5PQ
确保在没有附加调试器的发布模式下运行。
这类运行时错误的处理方式不同,它们不会产生SEH异常。大致归类在"编程错误"answers"恶意软件攻击"之间。如果您没有附加调试器,则默认处理程序将通过__fastfail()调用即时死亡,这与未捕获的c++异常一样具有信息。
您必须在main()函数中调用_set_invalid_parameter_handler()来更改它们的处理方式。您可以在自定义处理程序中抛出c++异常,或者调用RaiseException()来触发catch-em-all处理程序,或者直接在那里报告它们。如果选择后者,则需要确保进程始终被终止。
请注意,您的代码片段并不是最好的示例。当您在没有启用迭代器调试的情况下构建程序时,就像使用默认设置的Release构建一样,这是UB。UB不保证你会得到一个SEH异常。如果它发生了,那么你必须非常小心地编写异常过滤器,它将在堆锁仍然占用的情况下被调用,因此基本的东西无法工作。最好的方法是用一个命名事件唤醒一个守卫进程。
您看不到异常,因为它是由C运行时内部处理的。具体来说,这是一个边界检查,而不是访问冲突。
在调试器中运行它,我发现它是vector
中的第242行:
_DEBUG_ERROR("vector iterators incompatible");
最终调用_CrtDebugReportW
: https://msdn.microsoft.com/en-us/library/8hyw4sy7.aspx
可以用_CrtSetReportMode
来控制_CrtDebugReportW
的行为。
请注意,这在发布模式下不起作用,因为这些是调试模式的边界检查。
- 为什么 Windows 拒绝访问某些进程的名称?
- Windows C++:文件夹移动访问被拒绝错误
- AWS AMI 中的 Windows DPAPI 失败,访问被拒绝
- 如何在 Windows 2016 Server 版本 1607 中访问 SetThreadDescription()
- Windows 后台服务(系统配置文件)无法使用 C++ 访问 win 10 上的用户 appData 文件夹?
- 确实可以提高directory_iterator在Windows上按字母顺序访问文件和文件夹
- Windows C++静态库在初始化期间无法访问外部方法
- C++ Windows:从主进程和 CallWndProc 进程访问相同的变量
- 如何:监视Windows中另一个进程的文件访问?
- C++ Windows - 以编程方式检查软件是否访问互联网?
- 使用 NamedPipe 访问 Windows 服务之间的安全性
- 通过Delphi访问Windows API是否会导致性能损失
- 我可以直接访问 Windows 内核系统调用吗?
- 如何在C++中访问Windows设备管理器中的信息
- Qt4 - 从注册表访问 Windows Machine Guid
- std::map::operator[]违规访问windows上的内存
- 我需要同步访问Windows上的HANDLE吗
- 如何在MSYS上访问windows环境变量
- 访问Windows声音
- C++/Qt:如何远程访问windows注册表