VC++中的异常处理堆栈跟踪
exception handling stack trace in VC++
我是C++编程的新手_当我将无效参数传递给C++系统函数时,set_invalid_parameter_handler会给我函数名、文件和行,例如:在_tmain printf中,行生成错误,但我想获得编程的函数名、文档和行,而不是系统函数。
void myInvalidParameterHandler(const wchar_t* expression,
const wchar_t* function,
const wchar_t* file,
unsigned int line,
uintptr_t pReserved)
{
wprintf(L"Invalid parameter detected in function %s."
L" File: %s Line: %dn", function, file, line);
wprintf(L"Expression: %sn", expression);
call_stack st;
st.stack.back();
cout << st.stack.back().to_string();
cout << st.to_string();
}
int _tmain(int argc, _TCHAR* argv[])
{
char* formatString;
_invalid_parameter_handler oldHandler, newHandler;
newHandler = myInvalidParameterHandler;
oldHandler = _set_invalid_parameter_handler(newHandler);
formatString = NULL;
printf(formatString); // I want to get this line
return 0;
}
在此示例中,myInvalidParameterHandler生成以下输出:函数=printf,文件=f:\dd\vctools\crt\crtw32\stdio\printf.c,表达式=(format!=NULL),行=54
但我想得到这样的东西:函数=_tmain,文件:。。。\MySample.cpp,line=(MySample.cpp中的printf行)我该怎么做?(像C#堆栈跟踪)?
我还尝试了stackwalker(call_stack),它给了我自己的线路,我无法通过这种方式获得我的需求。
编辑:还没有回答任何人。请帮忙。2015.02.25 16:42土耳其(雅典地区)
问题是,在C++中,调用堆栈不像C#中那样容易使用。
要在向公众发布的应用程序中获得调用堆栈,您需要原始源代码、原始DLL文件、原始PDB文件和转储文件。
您可以使用崩溃处理程序中的MiniDumpWriteDump()
在代码中生成转储文件。但这需要一个结构化的例外。
所以你必须写:
#define SEH_ARG_EXCEPTION 0xE0415247 // "ARG"
void myInvalidParameterHandler(....) // all params are NULL in a release build
{
RaiseException(SEH_ARG_EXCEPTION, EXCEPTION_NONCONTINUABLE, 0, NULL);
}
在一个结构化的异常处理程序中,你会发现:
__try
{
Execute your code with invalid argument
}
__except(ExceptionHandler(GetExceptionInformation()))
{
}
static int ExceptionHandler(EXCEPTION_POINTERS* pk_Ptr)
{
switch (pk_Ptr->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_BREAKPOINT:
case EXCEPTION_SINGLE_STEP:
return EXCEPTION_CONTINUE_SEARCH;
}
MINIDUMP_EXCEPTION_INFORMATION k_Mini;
k_Mini.ThreadId = GetCurrentThreadId();
k_Mini.ExceptionPointers = pk_Ptr;
k_Mini.ClientPointers = FALSE;
HANDLE h_File = CreateFile(L"DumpPath\XYZ.dmp", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), h_File, MINIDUMP_TYPE, &k_Mini, 0, 0);
CloseHandle(h_File);
MessageBox(NULL, L"The application has crashed.nA Minidump has been written to: XYZ.dmpnPlease send this file to xyz@abc.com", L"Fatal Error", MB_ICONSTOP | MB_TOPMOST);
TerminateProcess(GetCurrentProcess(), 0);
return EXCEPTION_EXECUTE_HANDLER;
}
然后,您将在磁盘上有一个DMP文件,用户必须将该文件发送给您,以便将其加载到Visual Studio中,并从堆栈中获取崩溃位置。
重要提示:您需要确切的原始代码、DLL和PDB文件才能正常工作。
相关文章:
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 提升堆栈跟踪不显示函数名称和行号
- cygwin_exception::open_stackdumpfile:将堆栈跟踪转储到 class4.exe.sta
- 如何按指针查看堆栈跟踪
- WinDbg 不显示某些小型转储文件的完整堆栈跟踪
- 发布代码的 gdb 堆栈跟踪可读性如何影响 x64?
- 提升::堆栈跟踪::safe_dump_to输出大小
- Qt 5.9中的QML崩溃-帮助读取堆栈跟踪
- 如何获取崩溃的DLL的堆栈跟踪?
- 当外部源代码中发生异常时,无法正确使用自创建的小型转储文件的堆栈跟踪
- 在 Linux 平台上以 C/C++ 打印进程的所有线程堆栈跟踪
- Boost 堆栈跟踪异步信号安全吗?
- 使用 gdb 时无法获取堆栈跟踪
- VC++ 堆栈跟踪不会解析生产环境中的函数名称
- 从堆栈跟踪中查找共享库中的源代码行
- 捕获异常后的堆栈跟踪
- 是否有一种便携式/标准的方法可以在堆栈跟踪中获取文件名和亚麻布
- 为什么谷歌测试不打印堆栈跟踪或文件名
- 在明夫中打印堆栈跟踪
- GDB 显示奇怪的堆栈跟踪