//#pragma warning( disable: 4786 ) #include <windows.h> #include <winnt.h> #include <string> #include <vector> #include <Psapi.h> #include <algorithm> #include <iomanip> #include <iostream> #include <stdexcept> #include <iterator> #pragma comment(lib, "psapi.lib") #pragma comment(lib, "dbghelp.lib") #pragma pack( push, before_imagehlp, 8 ) #include <imagehlp.h> #pragma pack( pop, before_imagehlp ) struct module_data { std::string image_name; std::string module_name; void *base_address; DWORD load_size; }; typedef std::vector<module_data> ModuleList; extern void __declspec(dllimport) ThreadFunc1(void (*f)()); HANDLE thread_done; HANDLE thread_ready; bool show_stack(std::ostream &, HANDLE hThread, CONTEXT& c); DWORD __stdcall TargetThread( void *arg ); void ThreadFunc1(); void ThreadFunc2(); DWORD Filter( EXCEPTION_POINTERS *ep ); void *load_modules_symbols( HANDLE hProcess, DWORD pid ); class thread_suspender { HANDLE thread; public: thread_suspender(HANDLE t) :thread(t) { SuspendThread(thread); } ~thread_suspender() { ResumeThread(thread); } }; int main() { HANDLE thread; DWORD thread_id; try { thread_ready = CreateEvent( NULL, false, false, NULL ); thread_done = CreateEvent(NULL, false, false,NULL); thread = CreateThread( NULL, 0, TargetThread, NULL, 0, &thread_id ); WaitForSingleObject( thread_ready, INFINITE ); CloseHandle(thread_ready); { thread_suspender t(thread); CONTEXT c = {0}; c.ContextFlags = CONTEXT_FULL; GetThreadContext(thread, &c); show_stack(std::cout, thread, c); } SetEvent(thread_done); WaitForSingleObject(thread, INFINITE); } catch (std::exception const &e) { std::cout << "Caught Exception: " << e.what() << "\n"; } return 0; } // if you use C++ exception handling: install a translator function // with set_se_translator(). In the context of that function (but *not* // afterwards), you can either do your stack dump, or save the CONTEXT // record as a local copy. Note that you must do the stack dump at the // earliest opportunity, to avoid the interesting stack-frames being gone // by the time you do the dump. DWORD Filter(EXCEPTION_POINTERS *ep) { HANDLE thread; DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &thread, 0, false, DUPLICATE_SAME_ACCESS); std::cout << "Walking stack from exception."; show_stack(std::cout, thread, *(ep->ContextRecord)); std::cout << "\nEnd of exception stack walk.\n"; CloseHandle(thread); return EXCEPTION_EXECUTE_HANDLER; } void ThreadFunc2() { // First, cause an exception. The filter above forces a stack dump. __try { DebugBreak(); } __except (Filter(GetExceptionInformation())) { } // Then signal that the thread is ready for a normal stack dump SetEvent(thread_ready); // and wait until the main thread finishes dumping the stack. WaitForSingleObject(thread_done, INFINITE); } DWORD __stdcall TargetThread( void *arg ) { (void) arg; ThreadFunc1(ThreadFunc2); return 0; } class SymHandler { HANDLE p; public: SymHandler(HANDLE process, char const *path=NULL, bool intrude = false) : p(process) { if (!SymInitialize(p, path, intrude)) throw(std::logic_error("Unable to initialize symbol handler")); } ~SymHandler() { SymCleanup(p); } }; #ifdef _M_X64 STACKFRAME64 init_stack_frame(CONTEXT c) { STACKFRAME64 s; s.AddrPC.Offset = c.Rip; s.AddrPC.Mode = AddrModeFlat; s.AddrStack.Offset = c.Rsp; s.AddrStack.Mode = AddrModeFlat; s.AddrFrame.Offset = c.Rbp; s.AddrFrame.Mode = AddrModeFlat; return s; } #else STACKFRAME64 init_stack_frame(CONTEXT c) { STACKFRAME64 s; s.AddrPC.Offset = c.Eip; s.AddrPC.Mode = AddrModeFlat; s.AddrStack.Offset = c.Esp; s.AddrStack.Mode = AddrModeFlat; s.AddrFrame.Offset = c.Ebp; s.AddrFrame.Mode = AddrModeFlat; return s; } #endif void sym_options(DWORD add, DWORD remove=0) { DWORD symOptions = SymGetOptions(); symOptions |= add; symOptions &= ~remove; SymSetOptions(symOptions); } class symbol { typedef IMAGEHLP_SYMBOL64 sym_type; sym_type *sym; static const int max_name_len = 1024; public: symbol(HANDLE process, DWORD64 address) : sym((sym_type *)::operator new(sizeof(*sym) + max_name_len)) { memset(sym, '\0', sizeof(*sym) + max_name_len); sym->SizeOfStruct = sizeof(*sym); sym->MaxNameLength = max_name_len; DWORD64 displacement; if (!SymGetSymFromAddr64(process, address, &displacement, sym)) throw(std::logic_error("Bad symbol")); } std::string name() { return std::string(sym->Name); } std::string undecorated_name() { std::vector<char> und_name(max_name_len); UnDecorateSymbolName(sym->Name, &und_name[0], max_name_len, UNDNAME_COMPLETE); return std::string(&und_name[0], strlen(&und_name[0])); } }; bool show_stack(std::ostream &os, HANDLE hThread, CONTEXT& c) { HANDLE process = GetCurrentProcess(); int frame_number=0; DWORD offset_from_symbol=0; IMAGEHLP_LINE64 line = {0}; SymHandler handler(process); sym_options(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME); void *base = load_modules_symbols(process, GetCurrentProcessId()); STACKFRAME64 s = init_stack_frame(c); line.SizeOfStruct = sizeof line; IMAGE_NT_HEADERS *h = ImageNtHeader(base); DWORD image_type = h->FileHeader.Machine; do { if (!StackWalk64(image_type, process, hThread, &s, &c, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) return false; os << std::setw(3) << "\n" << frame_number << "\t"; if (s.AddrPC.Offset != 0) { std::cout << symbol(process, s.AddrPC.Offset).undecorated_name(); if (SymGetLineFromAddr64(process, s.AddrPC.Offset, &offset_from_symbol, &line)) os << "\t" << line.FileName << "(" << line.LineNumber << ")"; } else os << "(No Symbols: PC == 0)"; ++frame_number; } while (s.AddrReturn.Offset != 0); return true; } class get_mod_info { HANDLE process; static const int buffer_length = 4096; public: get_mod_info(HANDLE h) : process(h) {} module_data operator()(HMODULE module) { module_data ret; char temp[buffer_length]; MODULEINFO mi; GetModuleInformation(process, module, &mi, sizeof(mi)); ret.base_address = mi.lpBaseOfDll; ret.load_size = mi.SizeOfImage; GetModuleFileNameEx(process, module, temp, sizeof(temp)); ret.image_name = temp; GetModuleBaseName(process, module, temp, sizeof(temp)); ret.module_name = temp; std::vector<char> img(ret.image_name.begin(), ret.image_name.end()); std::vector<char> mod(ret.module_name.begin(), ret.module_name.end()); SymLoadModule64(process, 0, &img[0], &mod[0], (DWORD64)ret.base_address, ret.load_size); return ret; } }; void *load_modules_symbols(HANDLE process, DWORD pid) { ModuleList modules; DWORD cbNeeded; std::vector<HMODULE> module_handles(1); EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded); module_handles.resize(cbNeeded/sizeof(HMODULE)); EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded); std::transform(module_handles.begin(), module_handles.end(), std::back_inserter(modules), get_mod_info(process)); return modules[0].base_address; }
Standard input is empty
prog.cpp:2:21: error: windows.h: No such file or directory prog.cpp:3:19: error: winnt.h: No such file or directory prog.cpp:7:19: error: Psapi.h: No such file or directory prog.cpp:14: warning: ignoring #pragma comment prog.cpp:15: warning: ignoring #pragma comment prog.cpp:18:22: error: imagehlp.h: No such file or directory prog.cpp:25: error: ‘DWORD’ does not name a type prog.cpp:29: warning: ‘__declspec’ initialized and declared ‘extern’ prog.cpp:29: error: variable or field ‘__declspec’ declared void prog.cpp:29: error: ‘dllimport’ was not declared in this scope prog.cpp:31: error: ‘HANDLE’ does not name a type prog.cpp:32: error: ‘HANDLE’ does not name a type prog.cpp:34: error: ‘HANDLE’ has not been declared prog.cpp:34: error: ‘CONTEXT’ has not been declared prog.cpp:35: error: ‘DWORD’ does not name a type prog.cpp:38: error: ‘DWORD’ does not name a type prog.cpp:39: error: ‘HANDLE’ was not declared in this scope prog.cpp:39: error: ‘DWORD’ was not declared in this scope prog.cpp:39: error: initializer expression list treated as compound expression prog.cpp:42: error: ‘HANDLE’ does not name a type prog.cpp:44: error: expected `)' before ‘t’ prog.cpp: In destructor ‘thread_suspender::~thread_suspender()’: prog.cpp:45: error: ‘thread’ was not declared in this scope prog.cpp:45: error: ‘ResumeThread’ was not declared in this scope prog.cpp: In function ‘int main()’: prog.cpp:49: error: ‘HANDLE’ was not declared in this scope prog.cpp:49: error: expected `;' before ‘thread’ prog.cpp:50: error: ‘DWORD’ was not declared in this scope prog.cpp:50: error: expected `;' before ‘thread_id’ prog.cpp:53: error: ‘thread_ready’ was not declared in this scope prog.cpp:53: error: ‘CreateEvent’ was not declared in this scope prog.cpp:54: error: ‘thread_done’ was not declared in this scope prog.cpp:56: error: ‘thread’ was not declared in this scope prog.cpp:56: error: ‘TargetThread’ was not declared in this scope prog.cpp:56: error: ‘thread_id’ was not declared in this scope prog.cpp:56: error: ‘CreateThread’ was not declared in this scope prog.cpp:58: error: ‘INFINITE’ was not declared in this scope prog.cpp:58: error: ‘WaitForSingleObject’ was not declared in this scope prog.cpp:59: error: ‘CloseHandle’ was not declared in this scope prog.cpp:64: error: ‘CONTEXT’ was not declared in this scope prog.cpp:64: error: expected `;' before ‘c’ prog.cpp:65: error: ‘c’ was not declared in this scope prog.cpp:65: error: ‘CONTEXT_FULL’ was not declared in this scope prog.cpp:66: error: ‘GetThreadContext’ was not declared in this scope prog.cpp:69: error: ‘SetEvent’ was not declared in this scope prog.cpp: At global scope: prog.cpp:84: error: ‘DWORD’ does not name a type prog.cpp: In function ‘void ThreadFunc2()’: prog.cpp:99: error: ‘__try’ was not declared in this scope prog.cpp:99: error: expected `;' before ‘{’ token prog.cpp:100: error: ‘GetExceptionInformation’ was not declared in this scope prog.cpp:100: error: ‘Filter’ was not declared in this scope prog.cpp:100: error: ‘__except’ was not declared in this scope prog.cpp:100: error: expected `;' before ‘{’ token prog.cpp:103: error: ‘thread_ready’ was not declared in this scope prog.cpp:103: error: ‘SetEvent’ was not declared in this scope prog.cpp:105: error: ‘thread_done’ was not declared in this scope prog.cpp:105: error: ‘INFINITE’ was not declared in this scope prog.cpp:105: error: ‘WaitForSingleObject’ was not declared in this scope prog.cpp: At global scope: prog.cpp:108: error: ‘DWORD’ does not name a type prog.cpp:115: error: ‘HANDLE’ does not name a type prog.cpp:117: error: expected `)' before ‘process’ prog.cpp: In destructor ‘SymHandler::~SymHandler()’: prog.cpp:121: error: ‘p’ was not declared in this scope prog.cpp:121: error: ‘SymCleanup’ was not declared in this scope prog.cpp: At global scope: prog.cpp:136: error: ‘STACKFRAME64’ does not name a type prog.cpp:148: error: variable or field ‘sym_options’ declared void prog.cpp:148: error: ‘DWORD’ was not declared in this scope prog.cpp:148: error: ‘DWORD’ was not declared in this scope prog.cpp:156: error: ‘IMAGEHLP_SYMBOL64’ does not name a type prog.cpp:157: error: ISO C++ forbids declaration of ‘sym_type’ with no type prog.cpp:157: error: expected ‘;’ before ‘*’ token prog.cpp:160: error: expected `)' before ‘process’ prog.cpp: In member function ‘std::string symbol::name()’: prog.cpp:170: error: ‘sym’ was not declared in this scope prog.cpp: In member function ‘std::string symbol::undecorated_name()’: prog.cpp:173: error: ‘sym’ was not declared in this scope prog.cpp:173: error: ‘UNDNAME_COMPLETE’ was not declared in this scope prog.cpp:173: error: ‘UnDecorateSymbolName’ was not declared in this scope prog.cpp:174: error: ‘strlen’ was not declared in this scope prog.cpp: At global scope: prog.cpp:178: error: ‘HANDLE’ has not been declared prog.cpp:178: error: ‘CONTEXT’ has not been declared prog.cpp: In function ‘bool show_stack(std::ostream&, int, int&)’: prog.cpp:179: error: ‘HANDLE’ was not declared in this scope prog.cpp:179: error: expected `;' before ‘process’ prog.cpp:181: error: ‘DWORD’ was not declared in this scope prog.cpp:181: error: expected `;' before ‘offset_from_symbol’ prog.cpp:182: error: ‘IMAGEHLP_LINE64’ was not declared in this scope prog.cpp:182: error: expected `;' before ‘line’ prog.cpp:184: error: ‘process’ was not declared in this scope prog.cpp:186: error: ‘SYMOPT_LOAD_LINES’ was not declared in this scope prog.cpp:186: error: ‘SYMOPT_UNDNAME’ was not declared in this scope prog.cpp:186: error: ‘sym_options’ was not declared in this scope prog.cpp:188: error: ‘GetCurrentProcessId’ was not declared in this scope prog.cpp:188: error: ‘load_modules_symbols’ cannot be used as a function prog.cpp:190: error: ‘STACKFRAME64’ was not declared in this scope prog.cpp:190: error: expected `;' before ‘s’ prog.cpp:192: error: ‘line’ was not declared in this scope prog.cpp:194: error: ‘IMAGE_NT_HEADERS’ was not declared in this scope prog.cpp:194: error: ‘h’ was not declared in this scope prog.cpp:194: error: ‘ImageNtHeader’ was not declared in this scope prog.cpp:195: error: expected `;' before ‘image_type’ prog.cpp:198: error: ‘image_type’ was not declared in this scope prog.cpp:198: error: ‘s’ was not declared in this scope prog.cpp:198: error: ‘SymFunctionTableAccess64’ was not declared in this scope prog.cpp:198: error: ‘SymGetModuleBase64’ was not declared in this scope prog.cpp:198: error: ‘StackWalk64’ was not declared in this scope prog.cpp:202: error: ‘s’ was not declared in this scope prog.cpp:205: error: ‘offset_from_symbol’ was not declared in this scope prog.cpp:205: error: ‘SymGetLineFromAddr64’ was not declared in this scope prog.cpp:211: error: ‘s’ was not declared in this scope prog.cpp: At global scope: prog.cpp:216: error: ‘HANDLE’ does not name a type prog.cpp:219: error: expected `)' before ‘h’ prog.cpp:221: error: ‘HMODULE’ has not been declared prog.cpp: In member function ‘module_data get_mod_info::operator()(int)’: prog.cpp:224: error: ‘MODULEINFO’ was not declared in this scope prog.cpp:224: error: expected `;' before ‘mi’ prog.cpp:226: error: ‘process’ was not declared in this scope prog.cpp:226: error: ‘mi’ was not declared in this scope prog.cpp:226: error: ‘GetModuleInformation’ was not declared in this scope prog.cpp:228: error: ‘struct module_data’ has no member named ‘load_size’ prog.cpp:230: error: ‘GetModuleFileNameEx’ was not declared in this scope prog.cpp:232: error: ‘GetModuleBaseName’ was not declared in this scope prog.cpp:236: error: ‘DWORD64’ was not declared in this scope prog.cpp:236: error: ‘struct module_data’ has no member named ‘load_size’ prog.cpp:236: error: ‘SymLoadModule64’ was not declared in this scope prog.cpp: At global scope: prog.cpp:241: error: redefinition of ‘void* load_modules_symbols’ prog.cpp:39: error: ‘void* load_modules_symbols’ previously defined here prog.cpp:241: error: ‘HANDLE’ was not declared in this scope prog.cpp:241: error: ‘DWORD’ was not declared in this scope
Standard output is empty