Skip to content

Commit

Permalink
more 4548 - load pdb only when needed
Browse files Browse the repository at this point in the history
  • Loading branch information
alabuzhev committed Feb 20, 2016
1 parent e4166d9 commit 08674c2
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 34 deletions.
6 changes: 5 additions & 1 deletion 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.

Expand Down
3 changes: 3 additions & 0 deletions far/ctrlobj.cpp
Expand Up @@ -113,7 +113,10 @@ void ControlObject::CreateDummyFilePanels()
ControlObject::~ControlObject()
{
if (Global->CriticalInternalError)
{
Global->WindowManager->CloseAll();
return;
}

_OT(SysLog(L"[%p] ControlObject::~ControlObject()", this));

Expand Down
7 changes: 4 additions & 3 deletions far/farexcpt.cpp
Expand Up @@ -59,15 +59,16 @@ void CreatePluginStartupInfo(const Plugin *pPlugin, PluginStartupInfo *PSI, FarS

#define LAST_BUTTON 14

void ShowStackTraceImpl(const std::vector<string>& Trace)
static void ShowStackTraceImpl(const std::vector<void*>& Trace)
{
const auto Symbols = tracer::GetSymbols(Trace);
if (Global && Global->WindowManager && !Global->WindowManager->ManagerIsDown())
{
Message(MSG_WARNING | MSG_LEFTALIGN, MSG(MExcTrappedException), Trace, make_vector<string>(MSG(MOk)));
Message(MSG_WARNING | MSG_LEFTALIGN, MSG(MExcTrappedException), Symbols, make_vector<string>(MSG(MOk)));
}
else
{
FOR(const auto& Str, Trace)
FOR(const auto& Str, Symbols)
{
std::wcerr << Str << L'\n';
}
Expand Down
7 changes: 7 additions & 0 deletions far/imports.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions far/imports.hpp
Expand Up @@ -136,6 +136,7 @@ public: const unique_function_pointer<decltype(&ImportedFunctions::stub_##NAME),
// dbghelp
DECLARE_IMPORT_FUNCTION(BOOL, WINAPI, MiniDumpWriteDump, HANDLE Process, DWORD ProcessId, HANDLE File, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
DECLARE_IMPORT_FUNCTION(BOOL, WINAPI, SymInitialize, HANDLE Process, PCSTR UserSearchPath, BOOL InvadeProcess);
DECLARE_IMPORT_FUNCTION(BOOL, WINAPI, SymCleanup, HANDLE Process);
DECLARE_IMPORT_FUNCTION(BOOL, WINAPI, SymFromAddr, HANDLE Process, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol);

#undef DECLARE_IMPORT_FUNCTION
Expand Down
53 changes: 30 additions & 23 deletions far/tracer.cpp
Expand Up @@ -34,40 +34,47 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "tracer.hpp"
#include "imports.hpp"

std::vector<string> printStack()
static std::vector<void*> GetBackTrace()
{
std::vector<string> 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<void*> Result(MaxCallers);
auto FramesCount = Imports().RtlCaptureStackBackTrace(0, MaxCallers, Result.data(), nullptr);
Result.resize(FramesCount);
return Result;
}

std::vector<string> tracer::GetSymbols(const std::vector<void*>& BackTrace)
{
std::vector<string> 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_INFO> 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<DWORD_PTR>(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<DWORD_PTR>(BackTrace[i]), nullptr, Symbol.get());
Stream << i << ": " << BackTrace[i] << " " << Symbol->Name << " - 0x" << Symbol->Address;
Result.emplace_back(Stream.str());
Stream.str(string());
}
return Result;
}

LONG WINAPI StackLogger(EXCEPTION_POINTERS *xp)
{
if (xp->ExceptionRecord->ExceptionCode == 0xE06D7363) // MS C++ exception
tracer::GetInstance()->store(*reinterpret_cast<const std::exception*>(xp->ExceptionRecord->ExceptionInformation[1]), printStack());
tracer::GetInstance()->store(*reinterpret_cast<const std::exception*>(xp->ExceptionRecord->ExceptionInformation[1]), GetBackTrace());
else
tracer::GetInstance()->store(xp->ExceptionRecord, printStack());
tracer::GetInstance()->store(xp->ExceptionRecord, GetBackTrace());

return EXCEPTION_CONTINUE_SEARCH;
}
Expand All @@ -91,25 +98,25 @@ tracer::~tracer()
}


void tracer::store(const EXCEPTION_RECORD* Record, std::vector<string>&& Trace)
void tracer::store(const EXCEPTION_RECORD* Record, std::vector<void*>&& 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<string>&& Trace)
void tracer::store(const std::exception& e, std::vector<void*>&& 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<string> tracer::get(const EXCEPTION_RECORD* Record)
std::vector<void*> tracer::get(const EXCEPTION_RECORD* Record)
{
SCOPED_ACTION(CriticalSectionLock)(m_CS);
return m_SehMap[Record];
}

std::vector<string> tracer::get(const std::exception& e)
std::vector<void*> tracer::get(const std::exception& e)
{
SCOPED_ACTION(CriticalSectionLock)(m_CS);
return m_StdMap[&e];
Expand Down
14 changes: 8 additions & 6 deletions far/tracer.hpp
Expand Up @@ -41,18 +41,20 @@ class tracer: noncopyable

static tracer* GetInstance();

void store(const EXCEPTION_RECORD* Record, std::vector<string>&& Trace);
void store(const std::exception& e, std::vector<string>&& Trace);
void store(const EXCEPTION_RECORD* Record, std::vector<void*>&& BackTrace);
void store(const std::exception& e, std::vector<void*>&& BackTrace);

std::vector<string> get(const EXCEPTION_RECORD* Record);
std::vector<string> get(const std::exception& e);
std::vector<void*> get(const EXCEPTION_RECORD* Record);
std::vector<void*> get(const std::exception& e);

static std::vector<string> GetSymbols(const std::vector<void*>& BackTrace);

private:
static tracer* sTracer;

CriticalSection m_CS;
std::map<const EXCEPTION_RECORD*, std::vector<string>> m_SehMap;
std::map<const std::exception*, std::vector<string>> m_StdMap;
std::map<const EXCEPTION_RECORD*, std::vector<void*>> m_SehMap;
std::map<const std::exception*, std::vector<void*>> m_StdMap;

veh_handler m_Handler;
};
2 changes: 1 addition & 1 deletion far/vbuild.m4
@@ -1 +1 @@
m4_define(BUILD,4554)m4_dnl
m4_define(BUILD,4555)m4_dnl

0 comments on commit 08674c2

Please sign in to comment.