gpt4 book ai didi

c++ - 是否有将 EXCEPTION_POINTERS 结构转换为字符串的函数?

转载 作者:可可西里 更新时间:2023-11-01 12:44:37 28 4
gpt4 key购买 nike

有人知道一个函数可以将 GetExceptionInformation() 返回的 EXCEPTION_POINTERS 结构转换为我可以记录的字符串吗?

如果已经完成,我不想自己滚动。

编辑:基本上,我添加了 __try{} __except(){} block 来帮助应用在出现严重错误时优雅地失败。当我在做的时候,我正在尝试记录尽可能详细的错误消息,以找到我们要解决的问题。理想情况下,我想打印出文件名和它失败的行,但我怀疑这是可能的,所以我希望转储所有异常信息,希望我们能够尽可能接近查明问题的确切原因。

最佳答案

// Compile with /EHa
#include <windows.h>
#include <eh.h>
#include <Psapi.h>
#include <string>
#include <sstream>

class InfoFromSE
{
public:
typedef unsigned int exception_code_t;

static const char* opDescription( const ULONG opcode )
{
switch( opcode ) {
case 0: return "read";
case 1: return "write";
case 8: return "user-mode data execution prevention (DEP) violation";
default: return "unknown";
}
}

static const char* seDescription( const exception_code_t& code )
{
switch( code ) {
case EXCEPTION_ACCESS_VIOLATION: return "EXCEPTION_ACCESS_VIOLATION" ;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED" ;
case EXCEPTION_BREAKPOINT: return "EXCEPTION_BREAKPOINT" ;
case EXCEPTION_DATATYPE_MISALIGNMENT: return "EXCEPTION_DATATYPE_MISALIGNMENT" ;
case EXCEPTION_FLT_DENORMAL_OPERAND: return "EXCEPTION_FLT_DENORMAL_OPERAND" ;
case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "EXCEPTION_FLT_DIVIDE_BY_ZERO" ;
case EXCEPTION_FLT_INEXACT_RESULT: return "EXCEPTION_FLT_INEXACT_RESULT" ;
case EXCEPTION_FLT_INVALID_OPERATION: return "EXCEPTION_FLT_INVALID_OPERATION" ;
case EXCEPTION_FLT_OVERFLOW: return "EXCEPTION_FLT_OVERFLOW" ;
case EXCEPTION_FLT_STACK_CHECK: return "EXCEPTION_FLT_STACK_CHECK" ;
case EXCEPTION_FLT_UNDERFLOW: return "EXCEPTION_FLT_UNDERFLOW" ;
case EXCEPTION_ILLEGAL_INSTRUCTION: return "EXCEPTION_ILLEGAL_INSTRUCTION" ;
case EXCEPTION_IN_PAGE_ERROR: return "EXCEPTION_IN_PAGE_ERROR" ;
case EXCEPTION_INT_DIVIDE_BY_ZERO: return "EXCEPTION_INT_DIVIDE_BY_ZERO" ;
case EXCEPTION_INT_OVERFLOW: return "EXCEPTION_INT_OVERFLOW" ;
case EXCEPTION_INVALID_DISPOSITION: return "EXCEPTION_INVALID_DISPOSITION" ;
case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "EXCEPTION_NONCONTINUABLE_EXCEPTION" ;
case EXCEPTION_PRIV_INSTRUCTION: return "EXCEPTION_PRIV_INSTRUCTION" ;
case EXCEPTION_SINGLE_STEP: return "EXCEPTION_SINGLE_STEP" ;
case EXCEPTION_STACK_OVERFLOW: return "EXCEPTION_STACK_OVERFLOW" ;
default: return "UNKNOWN EXCEPTION" ;
}
}

static std::string information( struct _EXCEPTION_POINTERS* ep, bool has_exception_code = false, exception_code_t code = 0 )
{
HMODULE hm;
::GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, static_cast<LPCTSTR>(ep->ExceptionRecord->ExceptionAddress), &hm );
MODULEINFO mi;
::GetModuleInformation( ::GetCurrentProcess(), hm, &mi, sizeof(mi) );
char fn[MAX_PATH];
::GetModuleFileNameExA( ::GetCurrentProcess(), hm, fn, MAX_PATH );

std::ostringstream oss;
oss << "SE " << (has_exception_code?seDescription( code ):"") << " at address 0x" << std::hex << ep->ExceptionRecord->ExceptionAddress << std::dec
<< " inside " << fn << " loaded at base address 0x" << std::hex << mi.lpBaseOfDll << "\n";

if ( has_exception_code && (
code == EXCEPTION_ACCESS_VIOLATION ||
code == EXCEPTION_IN_PAGE_ERROR ) ) {
oss << "Invalid operation: " << opDescription(ep->ExceptionRecord->ExceptionInformation[0]) << " at address 0x" << std::hex << ep->ExceptionRecord->ExceptionInformation[1] << std::dec << "\n";
}

if ( has_exception_code && code == EXCEPTION_IN_PAGE_ERROR ) {
oss << "Underlying NTSTATUS code that resulted in the exception " << ep->ExceptionRecord->ExceptionInformation[2] << "\n";
}

return oss.str();
}
};

#include <iostream>
#include <exception>

void translator( InfoFromSE::exception_code_t code, struct _EXCEPTION_POINTERS* ep )
{
throw std::exception( InfoFromSE::information(ep,true,code).c_str() );
}

int main(int argc, char* argv[])
{
_set_se_translator(translator);
try{
int* p = 0;
std::cout << *p;
}catch( const std::exception& e ){
std::cerr << e.what() << "\n";
}

try{
int* p = 0;
*p = 0;
std::cout << *p;
}catch( const std::exception& e ){
std::cerr << e.what() << "\n";
}

try{
int a = 42;
volatile int b = 0;
std::cout << a/b;
}catch( const std::exception& e ){
std::cerr << e.what() << "\n";
}
return 0;
}

关于c++ - 是否有将 EXCEPTION_POINTERS 结构转换为字符串的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3523716/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com