feat(ExceptionHandler): Don't log repeating exceptions (#1244)
This commit is contained in:
parent
60e1c2e3c6
commit
fc52860e02
@ -35,6 +35,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -6,6 +6,14 @@
|
|||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
|
inline auto hash_stack_trace(std::vector<uint64_t> stack_trace)
|
||||||
|
{
|
||||||
|
auto data = reinterpret_cast<const char*>(stack_trace.data());
|
||||||
|
std::size_t size = stack_trace.size() * sizeof(uint64_t);
|
||||||
|
|
||||||
|
return std::hash<std::string_view>()({ data, size });
|
||||||
|
}
|
||||||
|
|
||||||
exception_handler::exception_handler()
|
exception_handler::exception_handler()
|
||||||
{
|
{
|
||||||
SetErrorMode(0);
|
SetErrorMode(0);
|
||||||
@ -14,8 +22,8 @@ namespace big
|
|||||||
|
|
||||||
exception_handler::~exception_handler()
|
exception_handler::~exception_handler()
|
||||||
{
|
{
|
||||||
// passing NULL / 0 will make it go back to normal exception handling
|
// passing nullptr will make it go back to normal exception handling
|
||||||
SetUnhandledExceptionFilter(0);
|
SetUnhandledExceptionFilter(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static stack_trace trace;
|
inline static stack_trace trace;
|
||||||
@ -25,9 +33,17 @@ namespace big
|
|||||||
if (exception_code == EXCEPTION_BREAKPOINT || exception_code == DBG_PRINTEXCEPTION_C || exception_code == DBG_PRINTEXCEPTION_WIDE_C)
|
if (exception_code == EXCEPTION_BREAKPOINT || exception_code == DBG_PRINTEXCEPTION_C || exception_code == DBG_PRINTEXCEPTION_WIDE_C)
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
|
||||||
|
static std::set<std::size_t> logged_exceptions;
|
||||||
|
|
||||||
trace.new_stack_trace(exception_info);
|
trace.new_stack_trace(exception_info);
|
||||||
|
const auto trace_hash = hash_stack_trace(trace.frame_pointers());
|
||||||
|
if (const auto it = logged_exceptions.find(trace_hash); it == logged_exceptions.end())
|
||||||
|
{
|
||||||
LOG(FATAL) << trace;
|
LOG(FATAL) << trace;
|
||||||
|
|
||||||
|
logged_exceptions.insert(trace_hash);
|
||||||
|
}
|
||||||
|
|
||||||
ZyanU64 opcode_address = exception_info->ContextRecord->Rip;
|
ZyanU64 opcode_address = exception_info->ContextRecord->Rip;
|
||||||
ZydisDisassembledInstruction instruction;
|
ZydisDisassembledInstruction instruction;
|
||||||
ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LONG_64, opcode_address, reinterpret_cast<void*>(opcode_address), 32, &instruction);
|
ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LONG_64, opcode_address, reinterpret_cast<void*>(opcode_address), 32, &instruction);
|
||||||
|
@ -19,6 +19,11 @@ namespace big
|
|||||||
SymCleanup(GetCurrentProcess());
|
SymCleanup(GetCurrentProcess());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<uint64_t>& stack_trace::frame_pointers()
|
||||||
|
{
|
||||||
|
return m_frame_pointers;
|
||||||
|
}
|
||||||
|
|
||||||
void stack_trace::new_stack_trace(EXCEPTION_POINTERS* exception_info)
|
void stack_trace::new_stack_trace(EXCEPTION_POINTERS* exception_info)
|
||||||
{
|
{
|
||||||
static std::mutex m;
|
static std::mutex m;
|
||||||
|
@ -9,6 +9,7 @@ namespace big
|
|||||||
stack_trace();
|
stack_trace();
|
||||||
virtual ~stack_trace();
|
virtual ~stack_trace();
|
||||||
|
|
||||||
|
const std::vector<uint64_t>& frame_pointers();
|
||||||
void new_stack_trace(EXCEPTION_POINTERS* exception_info);
|
void new_stack_trace(EXCEPTION_POINTERS* exception_info);
|
||||||
std::string str() const;
|
std::string str() const;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user