尝试使用__debugbreak()来/catch
try/catch with __debugbreak()
我正在使用在某些情况下运行__debugbreak()的第三方c++ DLL,并且在这样做之前没有检查IsDebuggerPresent()。当这种情况发生在调试器之外时(例如,最终用户运行应用程序),这会导致我的应用程序"崩溃"。我想抓住这个问题并自己处理它,或者至少忽略它。
我实际上有一个未处理的异常过滤器,用于将SEH转换为c++异常一段时间,所以它不工作有点奇怪。
::SetUnhandledExceptionFilter(OnUnhandledException);
我一直在做一些直接的测试,和标准的__try/__except工作,所以我可以包装每个调用到DLL与此作为回退,但似乎是,如果__try/__except工作,那么::SetUnhandledExceptionFilter()也应该工作。
__try
{
__debugbreak();
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf("caught");
}
try/catch(…)不起作用
try
{
__debugbreak();
}
catch (...)
{
printf("caught");
}
_set_se_translator()也不能工作。
在https://msdn.microsoft.com/en-us/library/ms679297(VS.85).aspx的MSDN文档中,它指出它应该作为结构化异常运行。我意识到这是DebugBreak()的文档,但我已经测试过了,也有同样的问题,即使是"catch(…)"。
我正在编译/EHa。
我如何捕获__debugbreak (asm INT 3),或者至少改变行为?
断点生成EXCEPTION_BREAKPOINT
结构化异常。你不能使用try/catch来捕获它,因为它不会被转换为c++异常,无论/EHa开关还是_set_se_translator
。
EXCEPTION_BREAKPOINT
为特殊例外。首先,你应该知道catch块和__except块只有在展开堆栈后才执行。这意味着在处理程序块之后继续执行,而不是在调用__debugbreak()
之后。所以如果你只是想跳过EXCEPTION_BREAKPOINT
,同时继续执行int 3
指令。您应该使用向量异常处理程序。下面是一个例子:
// VEH is supported only on Windows XP+ and Windows Server 2003+
#define _WIN32_WINNT 0x05020000
#include <windows.h>
#include <stdio.h>
//AddVectoredExceptionHandler constants:
//CALL_FIRST means call this exception handler first;
//CALL_LAST means call this exception handler last
#define CALL_FIRST 1
#define CALL_LAST 0
LONG WINAPI
VectoredHandlerBreakPoint(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
{
/*
If a debugger is attached, this will never be executed.
*/
printf("BreakPoint at 0x%x skipped.n", ExceptionInfo->ExceptionRecord->ExceptionAddress);
PCONTEXT Context = ExceptionInfo->ContextRecord;
// The breakpoint instruction is 0xCC (int 3), just one byte in size.
// Advance to the next instruction. Otherwise, this handler will just be called ad infinitum.
#ifdef _AMD64_
Context->Rip++;
#else
Context->Eip++;
#endif
// Continue execution from the instruction at Context->Rip/Eip.
return EXCEPTION_CONTINUE_EXECUTION;
}
// IT's not a break intruction. Continue searching for an exception handler.
return EXCEPTION_CONTINUE_SEARCH;
}
void main()
{
// Register the vectored exception handler once.
PVOID hVeh = AddVectoredExceptionHandler(CALL_FIRST, VectoredHandlerBreakPoint);
if (!hVeh)
{
// AddVectoredExceptionHandler failed.
// Practically, this never happens.
}
DebugBreak();
// Unregister the handler.
if (hVeh)
RemoveVectoredExceptionHandler(hVeh);
}
这样,断点指令int 3
将被跳过,下一条指令将被执行。此外,如果附加了调试器,它将为您处理EXCEPTION_BREAKPOINT
。
然而,如果你真的想要展开堆栈,你必须使用__except(GetExceptionCode() == EXCEPTION_BREAKPOINT ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
.
- 为什么catch中的代码没有被执行
- catch框架有没有办法比较流或文件
- 从 Rcpp Catch 测试中获取有关"inst/extdata"的数据
- 在C++中使用 Catch 测试框架编译错误"error: expected ';' at end of declaration list"
- 编译器是否必须始终删除 try-catch 块(如果它被证明是非抛出的)
- 有没有更好的方法来处理异常? try-catch块真的很丑
- 不能将重载比较运算符与 Catch 测试一起使用
- #pragma 警告不适用于 catch 语句
- 我可以使用 try catch 语句来捕获任何错误而不是具体错误吗?
- 在大型应用程序的main上使用try-catch
- RapidXML 节点在 try catch 块中具有正确的值,但它在块外为 nullptr
- 提取 try-catch 时出现运行时错误
- 无法在"catch(const std::exception &ex)"中捕获 std::invalid_argument
- std::unique_ptr 在 try-catch 块中未捕获取消引用异常
- 如果一个对象是在本地创建的,并在C++中作为异常抛出,那么本地对象如何在其范围之外有效,即在 catch 块中?
- C++ Catch 是否有类似 NUnit 的测试用例的东西,具有多个参数/输入选项
- 何时删除 try-catch 块中的指针
- 抛出多个异常时,catch 块执行的顺序是什么,为什么?
- 有什么方法可以从Visual Studio 2017中的Catch C++测试中获取代码覆盖率指标?
- 为什么我们需要用Catch分别编译主测试文件