diff options
author | chai <chaifix@163.com> | 2021-10-17 11:14:00 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-10-17 11:14:00 +0800 |
commit | d35db57d457132dd9d83fa2bd51491b148530655 (patch) | |
tree | b5a29675f091f268577b5991988c723f273b0bd1 /Editor/Utils/HelperFuncs.cpp | |
parent | 7b0a6d1fe0117cf42a5776aaabda2db78599e5b8 (diff) |
*GUI
Diffstat (limited to 'Editor/Utils/HelperFuncs.cpp')
-rw-r--r-- | Editor/Utils/HelperFuncs.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/Editor/Utils/HelperFuncs.cpp b/Editor/Utils/HelperFuncs.cpp new file mode 100644 index 0000000..fd91d85 --- /dev/null +++ b/Editor/Utils/HelperFuncs.cpp @@ -0,0 +1,136 @@ +#include "HelperFuncs.h" +#include <string.h> +#include <windows.h> +#include <dbghelp.h> +#include <process.h> +#include <exception> +#include <locale.h> +#include <stdlib.h> + +using namespace std; + +#pragma comment(lib,"Dbghelp.lib") + +std::string to_string(const char* cstr) +{ + string s(cstr); + return s; +} + +void _Exceptor() +{ + throw exception(); +} + +//https://stackoverflow.com/questions/22467604/ +const int MaxNameLen = 256; +void printStack(CONTEXT* ctx) //Prints stack trace based on context record +{ + BOOL result; + HANDLE process; + HANDLE thread; + HMODULE hModule; + + STACKFRAME64 stack; + ULONG frame; + DWORD64 displacement; + + DWORD disp; + IMAGEHLP_LINE64 *line; + + char buffer[sizeof(SYMBOL_INFO) + 2000 * sizeof(TCHAR)]; + char name[MaxNameLen]; + char module[MaxNameLen]; + PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; + + memset(&stack, 0, sizeof(STACKFRAME64)); + + process = GetCurrentProcess(); + thread = GetCurrentThread(); + displacement = 0; +#if !defined(_M_AMD64) + stack.AddrPC.Offset = (*ctx).Eip; + stack.AddrPC.Mode = AddrModeFlat; + stack.AddrStack.Offset = (*ctx).Esp; + stack.AddrStack.Mode = AddrModeFlat; + stack.AddrFrame.Offset = (*ctx).Ebp; + stack.AddrFrame.Mode = AddrModeFlat; +#endif + + SymInitialize(process, NULL, TRUE); //load symbols + + for (frame = 0; ; frame++) + { + //get next call from stack + result = StackWalk64 + ( +#if defined(_M_AMD64) + IMAGE_FILE_MACHINE_AMD64 +#else + IMAGE_FILE_MACHINE_I386 +#endif + , + process, + thread, + &stack, + ctx, + NULL, + SymFunctionTableAccess64, + SymGetModuleBase64, + NULL + ); + + if (!result) break; + + //get symbol name for address + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); + pSymbol->MaxNameLen = 2000; + SymFromAddr(process, (ULONG64)stack.AddrPC.Offset, &displacement, pSymbol); + + line = (IMAGEHLP_LINE64 *)malloc(sizeof(IMAGEHLP_LINE64)); + line->SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + //try to get line + if (SymGetLineFromAddr64(process, stack.AddrPC.Offset, &disp, line)) + { + printf("\tat %s in %s: line: %lu: address: 0x%0X\n", pSymbol->Name, line->FileName, line->LineNumber, pSymbol->Address); + } + else + { + //failed to get line + printf("\tat %s, address 0x%0X.\n", pSymbol->Name, pSymbol->Address); + hModule = NULL; + lstrcpyA(module, ""); + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCTSTR)(stack.AddrPC.Offset), &hModule); + + //at least print module name + if (hModule != NULL)GetModuleFileNameA(hModule, module, MaxNameLen); + + printf("in %s\n", module); + } + + free(line); + line = NULL; + } +} + +int seh_filter(_EXCEPTION_POINTERS* ex) +{ + printf("*** Exception 0x%x occured ***\n\n", ex->ExceptionRecord->ExceptionCode); + printStack(ex->ContextRecord); + + return EXCEPTION_EXECUTE_HANDLER; +} + +void PrintCallStack() +{ + __try + { + _Exceptor(); + } + __except (seh_filter(GetExceptionInformation())) + { + printf("Exception \n"); + } +}
\ No newline at end of file |