diff --git a/far/changelog b/far/changelog index d959ce3b98..774ef40fc6 100644 --- a/far/changelog +++ b/far/changelog @@ -1,4 +1,8 @@ -drkns 19.02.2016 21:58:30 +0200 - build 4554 +drkns 20.02.2016 04:16:03 +0200 - build 4555 + +1. Продолжение 4548: загружаем pdb только тогда, когда нужно. + +drkns 19.02.2016 21:58:30 +0200 - build 4554 1. Уточнение 4552. diff --git a/far/ctrlobj.cpp b/far/ctrlobj.cpp index 0f648a4b98..4503666ae1 100644 --- a/far/ctrlobj.cpp +++ b/far/ctrlobj.cpp @@ -113,7 +113,10 @@ void ControlObject::CreateDummyFilePanels() ControlObject::~ControlObject() { if (Global->CriticalInternalError) + { + Global->WindowManager->CloseAll(); return; + } _OT(SysLog(L"[%p] ControlObject::~ControlObject()", this)); diff --git a/far/farexcpt.cpp b/far/farexcpt.cpp index a8736e4450..e55dd7da92 100644 --- a/far/farexcpt.cpp +++ b/far/farexcpt.cpp @@ -59,15 +59,16 @@ void CreatePluginStartupInfo(const Plugin *pPlugin, PluginStartupInfo *PSI, FarS #define LAST_BUTTON 14 -void ShowStackTraceImpl(const std::vector& Trace) +static void ShowStackTraceImpl(const std::vector& Trace) { + const auto Symbols = tracer::GetSymbols(Trace); if (Global && Global->WindowManager && !Global->WindowManager->ManagerIsDown()) { - Message(MSG_WARNING | MSG_LEFTALIGN, MSG(MExcTrappedException), Trace, make_vector(MSG(MOk))); + Message(MSG_WARNING | MSG_LEFTALIGN, MSG(MExcTrappedException), Symbols, make_vector(MSG(MOk))); } else { - FOR(const auto& Str, Trace) + FOR(const auto& Str, Symbols) { std::wcerr << Str << L'\n'; } diff --git a/far/imports.cpp b/far/imports.cpp index 2d08f6018c..fae848641e 100644 --- a/far/imports.cpp +++ b/far/imports.cpp @@ -105,6 +105,7 @@ ImportedFunctions::ImportedFunctions(): INIT_IMPORT(m_dbghelp, MiniDumpWriteDump), INIT_IMPORT(m_dbghelp, SymInitialize), + INIT_IMPORT(m_dbghelp, SymCleanup), INIT_IMPORT(m_dbghelp, SymFromAddr) #undef INIT_IMPORT @@ -393,6 +394,12 @@ BOOL WINAPI ImportedFunctions::stub_SymInitialize(HANDLE Process, PCSTR UserSear return FALSE; } +BOOL WINAPI ImportedFunctions::stub_SymCleanup(HANDLE Process) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + BOOL WINAPI ImportedFunctions::stub_SymFromAddr(HANDLE Process, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); diff --git a/far/imports.hpp b/far/imports.hpp index df5d2aea21..d5c7eb32aa 100644 --- a/far/imports.hpp +++ b/far/imports.hpp @@ -136,6 +136,7 @@ public: const unique_function_pointer printStack() +static std::vector GetBackTrace() { - std::vector Result; - // ## Windows Server 2003 and Windows XP: // ## The sum of the FramesToSkip and FramesToCapture parameters must be less than 63. - const int kMaxCallers = 62; + const int MaxCallers = 62; + std::vector Result(MaxCallers); + auto FramesCount = Imports().RtlCaptureStackBackTrace(0, MaxCallers, Result.data(), nullptr); + Result.resize(FramesCount); + return Result; +} + +std::vector tracer::GetSymbols(const std::vector& BackTrace) +{ + std::vector Result; + + const auto Process = GetCurrentProcess(); + if (!Imports().SymInitialize(Process, nullptr, TRUE)) + return Result; + SCOPE_EXIT{ Imports().SymCleanup(Process); }; - void* callers_stack[kMaxCallers]; - const auto process = GetCurrentProcess(); - Imports().SymInitialize(process, nullptr, TRUE); - auto frames = Imports().RtlCaptureStackBackTrace(0, kMaxCallers, callers_stack, nullptr); const auto MaxNameLen = 2047; block_ptr Symbol(sizeof(SYMBOL_INFO) + MaxNameLen + 1); Symbol->SizeOfStruct = sizeof(SYMBOL_INFO); Symbol->MaxNameLen = MaxNameLen; - frames = frames < kMaxCallers? frames : kMaxCallers; - std::wostringstream s; - for (unsigned int i = 0; i < frames; i++) + std::wostringstream Stream; + for (size_t i = 0, size = BackTrace.size(); i != size; ++i) { - Imports().SymFromAddr(process, reinterpret_cast(callers_stack[i]), nullptr, Symbol.get()); - s << i << ": " << callers_stack[i] << " " << Symbol->Name << " - 0x" << Symbol->Address; - Result.emplace_back(s.str()); - s.str(string()); + Imports().SymFromAddr(Process, reinterpret_cast(BackTrace[i]), nullptr, Symbol.get()); + Stream << i << ": " << BackTrace[i] << " " << Symbol->Name << " - 0x" << Symbol->Address; + Result.emplace_back(Stream.str()); + Stream.str(string()); } return Result; } @@ -65,9 +72,9 @@ std::vector printStack() LONG WINAPI StackLogger(EXCEPTION_POINTERS *xp) { if (xp->ExceptionRecord->ExceptionCode == 0xE06D7363) // MS C++ exception - tracer::GetInstance()->store(*reinterpret_cast(xp->ExceptionRecord->ExceptionInformation[1]), printStack()); + tracer::GetInstance()->store(*reinterpret_cast(xp->ExceptionRecord->ExceptionInformation[1]), GetBackTrace()); else - tracer::GetInstance()->store(xp->ExceptionRecord, printStack()); + tracer::GetInstance()->store(xp->ExceptionRecord, GetBackTrace()); return EXCEPTION_CONTINUE_SEARCH; } @@ -91,25 +98,25 @@ tracer::~tracer() } -void tracer::store(const EXCEPTION_RECORD* Record, std::vector&& Trace) +void tracer::store(const EXCEPTION_RECORD* Record, std::vector&& BackTrace) { SCOPED_ACTION(CriticalSectionLock)(m_CS); - m_SehMap.insert(std::make_pair(Record, std::move(Trace))); + m_SehMap.insert(std::make_pair(Record, std::move(BackTrace))); } -void tracer::store(const std::exception& e, std::vector&& Trace) +void tracer::store(const std::exception& e, std::vector&& BackTrace) { SCOPED_ACTION(CriticalSectionLock)(m_CS); - m_StdMap.insert(std::make_pair(&e, std::move(Trace))); + m_StdMap.insert(std::make_pair(&e, std::move(BackTrace))); } -std::vector tracer::get(const EXCEPTION_RECORD* Record) +std::vector tracer::get(const EXCEPTION_RECORD* Record) { SCOPED_ACTION(CriticalSectionLock)(m_CS); return m_SehMap[Record]; } -std::vector tracer::get(const std::exception& e) +std::vector tracer::get(const std::exception& e) { SCOPED_ACTION(CriticalSectionLock)(m_CS); return m_StdMap[&e]; diff --git a/far/tracer.hpp b/far/tracer.hpp index 7c8f5d3934..cd0d403237 100644 --- a/far/tracer.hpp +++ b/far/tracer.hpp @@ -41,18 +41,20 @@ class tracer: noncopyable static tracer* GetInstance(); - void store(const EXCEPTION_RECORD* Record, std::vector&& Trace); - void store(const std::exception& e, std::vector&& Trace); + void store(const EXCEPTION_RECORD* Record, std::vector&& BackTrace); + void store(const std::exception& e, std::vector&& BackTrace); - std::vector get(const EXCEPTION_RECORD* Record); - std::vector get(const std::exception& e); + std::vector get(const EXCEPTION_RECORD* Record); + std::vector get(const std::exception& e); + + static std::vector GetSymbols(const std::vector& BackTrace); private: static tracer* sTracer; CriticalSection m_CS; - std::map> m_SehMap; - std::map> m_StdMap; + std::map> m_SehMap; + std::map> m_StdMap; veh_handler m_Handler; }; diff --git a/far/vbuild.m4 b/far/vbuild.m4 index 6725d02975..22ed4fc433 100644 --- a/far/vbuild.m4 +++ b/far/vbuild.m4 @@ -1 +1 @@ -m4_define(BUILD,4554)m4_dnl +m4_define(BUILD,4555)m4_dnl