C++ DLL中的大型向量异常处理程序导致程序在没有调试器的情况下崩溃
我目前正在开发DLL(Windows10,x64),它实现了向量异常处理程序(VEH)。它导出函数是为了将其附加到可执行文件,而不是别的。在连接VEH期间,它还使用以下代码段计算基准偏移:C++ DLL中的大型向量异常处理程序导致程序在没有调试器的情况下崩溃,c++,exception,dll,dllexport,C++,Exception,Dll,Dllexport,我目前正在开发DLL(Windows10,x64),它实现了向量异常处理程序(VEH)。它导出函数是为了将其附加到可执行文件,而不是别的。在连接VEH期间,它还使用以下代码段计算基准偏移: uint64_t GetModuleBase(const char *modname) { HANDLE hModSnap; MODULEENTRY32 pe32; void *bs = NULL; // Take a snapshot of all processes in
uint64_t GetModuleBase(const char *modname)
{
HANDLE hModSnap;
MODULEENTRY32 pe32;
void *bs = NULL;
// Take a snapshot of all processes in the system.
hModSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, GetCurrentProcessId() );
if( hModSnap == INVALID_HANDLE_VALUE )
{
return NULL;
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof( MODULEENTRY32 );
if( !Module32First( hModSnap, &pe32 ) )
{
CloseHandle( hModSnap ); // Must clean up the snapshot object!
return NULL;
}
do
{
if (!StrCmpI(pe32.szModule, modname)) {
bs = pe32.modBaseAddr;
break;
}
} while( Module32Next( hModSnap, &pe32 ) );
CloseHandle( hModSnap );
return (uint64_t)bs;
}
在异常处理程序中,我只处理代码为“0xc000001d”的异常,在其他情况下,VEH将执行传递回程序
在VEH I中注册的内部处理程序函数具有以下结构(简化):
我收到来自MSVC的警告:函数使用堆栈的'81340'字节:超过/分析:堆栈大小'16384'。考虑将一些数据移动到堆。< /P>
使用调试器,一切都按预期工作。使用Windbg,一切正常
没有调试器-应用程序会自动崩溃
更深入的研究表明,它注册DLL,开始执行,甚至调用处理程序几次,但有不同的异常代码(从0x8开始…,这是调试代码),所以VEH代码在早期阶段返回。顺便说一句,我可以在正常的应用程序操作中看到相同偏移量的相同代码
当该函数调用的数量大约为1400次时,一切都能正常工作(如果我对其中的一部分进行注释,哪一个都无所谓,只要我减少该数量)
我试图:
- 注释掉相同的函数调用(以确保它不是一个函数实现错误)->只是数量问题
- 禁用优化
- 将堆栈大小增加到140 Mb
- 使用静态MSVC分析检查未初始化或归零的变量-无这些
- 阅读互联网上类似的案例
- 用于调试的文件日志记录
- 有没有办法在没有调试模式的情况下从崩溃中获取更多信息
- 有没有一种方法可以表示如此大量的调用,从而使代码速度更快,但不会使堆栈过载?注意:根据发生异常的偏移量,所有函数调用都提供了不同的参数,因此分组将减少非常小的%的调用量
- 如果为了调试它而遇到这种问题,下一步该怎么做
谢谢您并希望您的帮助。好的,我已经解决了这个问题:
欢迎来到堆栈溢出!一般来说,如果您能够提供一个解决方案,那么寻求调试帮助的问题有更高的机会得到回答和投票。我不知道这对你来说有多容易。
#define FUNCTION_1(arg1, arg2, arg3, arg4)
if (exception_offset == arg1) { \
5_lines_of_code .... \
return EXCEPTION_CONTINUE_EXECUTION; \
}
#define FUNCTION_2(arg1, arg2, arg3, arg4)
if (exception_offset == arg1) { \
5_lines_of_code .... \
return EXCEPTION_CONTINUE_EXECUTION; \
}
#define FUNCTION_3(arg1, arg2, arg3, arg4)
if (exception_offset == arg1) { \
5_lines_of_code .... \
return EXCEPTION_CONTINUE_EXECUTION; \
} \
...
# 15 functions like that.
FUNCTION_1(0x192385, CPU_REGISTER1, CPU_REGISTER2);
FUNCTION_2(0x145685, CPU_REGISTER3, CPU_REGISTER4);
FUNCTION_3(0x456685, CPU_REGISTER1, CPU_REGISTER5);
# 1719 lines like that