diff options
| author | vvvv <[email protected]> | 2025-10-06 11:26:09 +0300 |
|---|---|---|
| committer | vvvv <[email protected]> | 2025-10-06 11:53:26 +0300 |
| commit | 60f45e69a4d7dbc6131208e16c45faf35aa5a985 (patch) | |
| tree | 4daa45b52c295a178c7620e4c93921465fcf7950 /yql/essentials/utils/backtrace | |
| parent | 1bded1a65a7e6e9171418f3e1c691d390125b64e (diff) | |
YQL-20086 utils
init
commit_hash:54feccd520ebd0ab23612bc0cb830914dff9d0e8
Diffstat (limited to 'yql/essentials/utils/backtrace')
| -rw-r--r-- | yql/essentials/utils/backtrace/backtrace.cpp | 223 | ||||
| -rw-r--r-- | yql/essentials/utils/backtrace/backtrace.h | 2 | ||||
| -rw-r--r-- | yql/essentials/utils/backtrace/backtrace_dummy.cpp | 12 | ||||
| -rw-r--r-- | yql/essentials/utils/backtrace/backtrace_lib.cpp | 99 | ||||
| -rw-r--r-- | yql/essentials/utils/backtrace/backtrace_lib.h | 24 | ||||
| -rw-r--r-- | yql/essentials/utils/backtrace/backtrace_linux.cpp | 90 | ||||
| -rw-r--r-- | yql/essentials/utils/backtrace/backtrace_ut.cpp | 30 | ||||
| -rw-r--r-- | yql/essentials/utils/backtrace/symbolize.cpp | 88 | ||||
| -rw-r--r-- | yql/essentials/utils/backtrace/symbolizer.h | 16 | ||||
| -rw-r--r-- | yql/essentials/utils/backtrace/symbolizer_linux.cpp | 122 | ||||
| -rw-r--r-- | yql/essentials/utils/backtrace/ut/ya.make | 1 | ||||
| -rw-r--r-- | yql/essentials/utils/backtrace/ya.make | 5 |
12 files changed, 358 insertions, 354 deletions
diff --git a/yql/essentials/utils/backtrace/backtrace.cpp b/yql/essentials/utils/backtrace/backtrace.cpp index 938ac90501a..5d289454210 100644 --- a/yql/essentials/utils/backtrace/backtrace.cpp +++ b/yql/essentials/utils/backtrace/backtrace.cpp @@ -18,7 +18,7 @@ #include <util/system/mlock.h> #ifdef _linux_ -#include <signal.h> + #include <signal.h> #endif #include <functional> @@ -38,16 +38,16 @@ bool SetSignalHandler(int signo, void (*handler)(int)) { } namespace { -#if defined(_linux_) && defined(_x86_64_) - bool SetSignalAction(int signo, void (*handler)(int, siginfo_t*, void*)) { - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_flags = SA_RESETHAND | SA_SIGINFO; - sa.sa_sigaction = (decltype(sa.sa_sigaction))handler; - sigfillset(&sa.sa_mask); - return sigaction(signo, &sa, nullptr) != -1; - } -#endif + #if defined(_linux_) && defined(_x86_64_) +bool SetSignalAction(int signo, void (*handler)(int, siginfo_t*, void*)) { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_RESETHAND | SA_SIGINFO; + sa.sa_sigaction = (decltype(sa.sa_sigaction))handler; + sigfillset(&sa.sa_mask); + return sigaction(signo, &sa, nullptr) != -1; +} + #endif } // namespace #endif // _win_ @@ -56,7 +56,7 @@ TAtomic BacktraceStarted = 0; void SetFatalSignalHandler(void (*handler)(int)) { Y_UNUSED(handler); #ifndef _win_ - for (int signo: {SIGSEGV, SIGILL, SIGABRT, SIGFPE}) { + for (int signo : {SIGSEGV, SIGILL, SIGABRT, SIGFPE}) { if (!SetSignalHandler(signo, handler)) { ythrow TSystemError() << "Cannot set handler for signal " << strsignal(signo); } @@ -67,7 +67,7 @@ void SetFatalSignalHandler(void (*handler)(int)) { #if defined(_linux_) && defined(_x86_64_) void SetFatalSignalAction(void (*sigaction)(int, siginfo_t*, void*)) { - for (int signo: {SIGSEGV, SIGILL, SIGABRT, SIGFPE}) { + for (int signo : {SIGSEGV, SIGILL, SIGABRT, SIGFPE}) { if (!SetSignalAction(signo, sigaction)) { ythrow TSystemError() << "Cannot set sigaction for signal " << strsignal(signo); } @@ -76,140 +76,139 @@ void SetFatalSignalAction(void (*sigaction)(int, siginfo_t*, void*)) #endif namespace { - std::vector<std::function<void(int)>> Before, After; - bool KikimrSymbolize = false; - NYql::NBacktrace::TCollectedFrame Frames[NYql::NBacktrace::Limit]; - - void CallCallbacks(decltype(Before)& where, int signum) { - for (const auto &fn: where) { - if (fn) { - fn(signum); - } +std::vector<std::function<void(int)>> Before, After; +bool KikimrSymbolize = false; +NYql::NBacktrace::TCollectedFrame Frames[NYql::NBacktrace::Limit]; + +void CallCallbacks(decltype(Before)& where, int signum) { + for (const auto& fn : where) { + if (fn) { + fn(signum); } } +} - void PrintFrames(IOutputStream* out, const NYql::NBacktrace::TCollectedFrame* frames, size_t cnt); +void PrintFrames(IOutputStream* out, const NYql::NBacktrace::TCollectedFrame* frames, size_t cnt); - void DoBacktrace(IOutputStream* out, void* data) { - auto cnt = NYql::NBacktrace::CollectFrames(Frames, data); - PrintFrames(out, Frames, cnt); - } +void DoBacktrace(IOutputStream* out, void* data) { + auto cnt = NYql::NBacktrace::CollectFrames(Frames, data); + PrintFrames(out, Frames, cnt); +} - void DoBacktrace(IOutputStream* out, void** stack, size_t cnt) { - Y_UNUSED(NYql::NBacktrace::CollectFrames(Frames, stack, cnt)); - PrintFrames(out, Frames, cnt); - } - - - void SignalHandler(int signum) { - CallCallbacks(Before, signum); - - if (!NMalloc::IsAllocatorCorrupted) { - if (!AtomicTryLock(&BacktraceStarted)) { - return; - } - - UnlockAllMemory(); - DoBacktrace(&Cerr, nullptr); +void DoBacktrace(IOutputStream* out, void** stack, size_t cnt) { + Y_UNUSED(NYql::NBacktrace::CollectFrames(Frames, stack, cnt)); + PrintFrames(out, Frames, cnt); +} + +void SignalHandler(int signum) { + CallCallbacks(Before, signum); + + if (!NMalloc::IsAllocatorCorrupted) { + if (!AtomicTryLock(&BacktraceStarted)) { + return; } - - CallCallbacks(After, signum); - raise(signum); + + UnlockAllMemory(); + DoBacktrace(&Cerr, nullptr); } -#if defined(_linux_) && defined(_x86_64_) - void SignalAction(int signum, siginfo_t*, void* context) { - Y_UNUSED(SignalHandler); - CallCallbacks(Before, signum); + CallCallbacks(After, signum); + raise(signum); +} - if (!NMalloc::IsAllocatorCorrupted) { - if (!AtomicTryLock(&BacktraceStarted)) { - return; - } +#if defined(_linux_) && defined(_x86_64_) +void SignalAction(int signum, siginfo_t*, void* context) { + Y_UNUSED(SignalHandler); + CallCallbacks(Before, signum); - UnlockAllMemory(); - DoBacktrace(&Cerr, context); + if (!NMalloc::IsAllocatorCorrupted) { + if (!AtomicTryLock(&BacktraceStarted)) { + return; } - - CallCallbacks(After, signum); - raise(signum); + + UnlockAllMemory(); + DoBacktrace(&Cerr, context); } -#endif + + CallCallbacks(After, signum); + raise(signum); } +#endif +} // namespace namespace NYql { - namespace NBacktrace { - THashMap<TString, TString> Mapping; +namespace NBacktrace { +THashMap<TString, TString> Mapping; - void SetModulesMapping(const THashMap<TString, TString>& mapping) { - Mapping = mapping; - } +void SetModulesMapping(const THashMap<TString, TString>& mapping) { + Mapping = mapping; +} - void AddBeforeFatalCallback(const std::function<void(int)>& before) { - Before.push_back(before); - } +void AddBeforeFatalCallback(const std::function<void(int)>& before) { + Before.push_back(before); +} - void AddAfterFatalCallback(const std::function<void(int)>& after) { - After.push_back(after); - } +void AddAfterFatalCallback(const std::function<void(int)>& after) { + After.push_back(after); +} - void RegisterKikimrFatalActions() { +void RegisterKikimrFatalActions() { #if defined(_linux_) && defined(_x86_64_) - SetFatalSignalAction(SignalAction); + SetFatalSignalAction(SignalAction); #else - SetFatalSignalHandler(SignalHandler); + SetFatalSignalHandler(SignalHandler); #endif - } - - void EnableKikimrSymbolize() { - KikimrSymbolize = true; - } +} - void KikimrBackTrace() { - FormatBackTrace(&Cerr); - } +void EnableKikimrSymbolize() { + KikimrSymbolize = true; +} - void KikimrBackTraceFormatImpl(IOutputStream* out) { - KikimrSymbolize = true; - UnlockAllMemory(); - DoBacktrace(out, nullptr); - } +void KikimrBackTrace() { + FormatBackTrace(&Cerr); +} - void KikimrBacktraceFormatImpl(IOutputStream* out, void* const* stack, size_t stackSize) { - KikimrSymbolize = true; - DoBacktrace(out, (void**)stack, stackSize); - } +void KikimrBackTraceFormatImpl(IOutputStream* out) { + KikimrSymbolize = true; + UnlockAllMemory(); + DoBacktrace(out, nullptr); +} - } +void KikimrBacktraceFormatImpl(IOutputStream* out, void* const* stack, size_t stackSize) { + KikimrSymbolize = true; + DoBacktrace(out, (void**)stack, stackSize); } +} // namespace NBacktrace +} // namespace NYql + void EnableKikimrBacktraceFormat() { SetFormatBackTraceFn(NYql::NBacktrace::KikimrBacktraceFormatImpl); } namespace { - NYql::NBacktrace::TStackFrame SFrames[NYql::NBacktrace::Limit]; - void PrintFrames(IOutputStream* out, const NYql::NBacktrace::TCollectedFrame* frames, size_t count) { - auto& outp = *out; - Y_UNUSED(SFrames); +NYql::NBacktrace::TStackFrame SFrames[NYql::NBacktrace::Limit]; +void PrintFrames(IOutputStream* out, const NYql::NBacktrace::TCollectedFrame* frames, size_t count) { + auto& outp = *out; + Y_UNUSED(SFrames); #if defined(_linux_) && defined(_x86_64_) - if (KikimrSymbolize) { - for (size_t i = 0; i < count; ++i) { - SFrames[i] = NYql::NBacktrace::TStackFrame{frames[i].File, frames[i].Address}; - } - NYql::NBacktrace::Symbolize(SFrames, count, out); - return; + if (KikimrSymbolize) { + for (size_t i = 0; i < count; ++i) { + SFrames[i] = NYql::NBacktrace::TStackFrame{frames[i].File, frames[i].Address}; } + NYql::NBacktrace::Symbolize(SFrames, count, out); + return; + } #endif - outp << "StackFrames: " << count << "\n"; - for (size_t i = 0; i < count; ++i) { - auto& frame = frames[i]; - auto fileName = frame.File; - if (!strcmp(fileName, "/proc/self/exe")) { - fileName = "EXE"; - } - auto it = NYql::NBacktrace::Mapping.find(fileName); - outp << "StackFrame: " << (it == NYql::NBacktrace::Mapping.end() ? fileName : it->second) << " " << frame.Address << " 0\n"; + outp << "StackFrames: " << count << "\n"; + for (size_t i = 0; i < count; ++i) { + auto& frame = frames[i]; + auto fileName = frame.File; + if (!strcmp(fileName, "/proc/self/exe")) { + fileName = "EXE"; } + auto it = NYql::NBacktrace::Mapping.find(fileName); + outp << "StackFrame: " << (it == NYql::NBacktrace::Mapping.end() ? fileName : it->second) << " " << frame.Address << " 0\n"; } -}
\ No newline at end of file +} +} // namespace diff --git a/yql/essentials/utils/backtrace/backtrace.h b/yql/essentials/utils/backtrace/backtrace.h index cd843d8cb41..c401392cfed 100644 --- a/yql/essentials/utils/backtrace/backtrace.h +++ b/yql/essentials/utils/backtrace/backtrace.h @@ -29,6 +29,6 @@ void SetModulesMapping(const THashMap<TString, TString>& mapping); TString Symbolize(const TString& input, const THashMap<TString, TString>& mapping); -} /* namespace Backtrace */ +} // namespace NBacktrace } /* namespace NYql */ diff --git a/yql/essentials/utils/backtrace/backtrace_dummy.cpp b/yql/essentials/utils/backtrace/backtrace_dummy.cpp index ec54e55dcab..5035aa918e7 100644 --- a/yql/essentials/utils/backtrace/backtrace_dummy.cpp +++ b/yql/essentials/utils/backtrace/backtrace_dummy.cpp @@ -3,9 +3,9 @@ #include <util/system/backtrace.h> namespace NYql { - namespace NBacktrace { - size_t CollectBacktrace(void** addresses, size_t limit, void*) { - return BackTrace(addresses, limit); - } - } -}
\ No newline at end of file +namespace NBacktrace { +size_t CollectBacktrace(void** addresses, size_t limit, void*) { + return BackTrace(addresses, limit); +} +} // namespace NBacktrace +} // namespace NYql diff --git a/yql/essentials/utils/backtrace/backtrace_lib.cpp b/yql/essentials/utils/backtrace/backtrace_lib.cpp index dd2d295dc30..473b227cc4a 100644 --- a/yql/essentials/utils/backtrace/backtrace_lib.cpp +++ b/yql/essentials/utils/backtrace/backtrace_lib.cpp @@ -6,74 +6,73 @@ #include <algorithm> #if defined(_linux_) && defined(_x86_64_) -#include <dlfcn.h> -#include <link.h> + #include <dlfcn.h> + #include <link.h> #endif namespace { - const size_t Limit = 400; - void* Stack[Limit]; +const size_t Limit = 400; +void* Stack[Limit]; - struct TDllInfo { - const char* Path; - ui64 BaseAddress; - }; +struct TDllInfo { + const char* Path; + ui64 BaseAddress; +}; - const size_t MaxDLLCnt = 100; - TDllInfo DLLs[MaxDLLCnt]; - size_t DLLCount = 0; +const size_t MaxDLLCnt = 100; +TDllInfo DLLs[MaxDLLCnt]; +size_t DLLCount = 0; #if defined(_linux_) && defined(_x86_64_) - int DlIterCallback(struct dl_phdr_info *info, size_t, void *data) { - if (*info->dlpi_name) { - if (DLLCount + 1 < MaxDLLCnt) { - reinterpret_cast<std::remove_reference_t<decltype(DLLs[0])>*>(data)[DLLCount++] = { info->dlpi_name, (ui64)info->dlpi_addr }; - } +int DlIterCallback(struct dl_phdr_info* info, size_t, void* data) { + if (*info->dlpi_name) { + if (DLLCount + 1 < MaxDLLCnt) { + reinterpret_cast<std::remove_reference_t<decltype(DLLs[0])>*>(data)[DLLCount++] = {info->dlpi_name, (ui64)info->dlpi_addr}; } - return 0; } + return 0; +} #endif - bool Comp(const TDllInfo& a, const TDllInfo& b) { - return strcmp(a.Path, b.Path) < 0; - } - +bool Comp(const TDllInfo& a, const TDllInfo& b) { + return strcmp(a.Path, b.Path) < 0; } +} // namespace + namespace NYql { - namespace NBacktrace { - TCollectedFrame::TCollectedFrame(uintptr_t addr) { - File = GetPersistentExecPath().c_str(); - Address = addr; +namespace NBacktrace { +TCollectedFrame::TCollectedFrame(uintptr_t addr) { + File = GetPersistentExecPath().c_str(); + Address = addr; #if defined(_linux_) && defined(_x86_64_) - Dl_info dlInfo; - memset(&dlInfo, 0, sizeof(dlInfo)); - auto ret = dladdr(reinterpret_cast<void*>(addr), &dlInfo); - if (ret) { - auto it = std::lower_bound(DLLs, DLLs + DLLCount, std::remove_reference_t<decltype(DLLs[0])> {dlInfo.dli_fname, {}}, Comp); - if (it != DLLs + DLLCount && !strcmp(it->Path, dlInfo.dli_fname)) { - File = it->Path; - Address -= it->BaseAddress; - } - } -#endif + Dl_info dlInfo; + memset(&dlInfo, 0, sizeof(dlInfo)); + auto ret = dladdr(reinterpret_cast<void*>(addr), &dlInfo); + if (ret) { + auto it = std::lower_bound(DLLs, DLLs + DLLCount, std::remove_reference_t<decltype(DLLs[0])>{dlInfo.dli_fname, {}}, Comp); + if (it != DLLs + DLLCount && !strcmp(it->Path, dlInfo.dli_fname)) { + File = it->Path; + Address -= it->BaseAddress; } + } +#endif +} - size_t CollectFrames(TCollectedFrame* frames, void* data) { +size_t CollectFrames(TCollectedFrame* frames, void* data) { #if defined(_linux_) && defined(_x86_64_) - DLLCount = 0; - dl_iterate_phdr(DlIterCallback, &DLLs); + DLLCount = 0; + dl_iterate_phdr(DlIterCallback, &DLLs); #endif - std::stable_sort(DLLs, DLLs + DLLCount, Comp); - size_t cnt = CollectBacktrace(Stack, Limit, data); - return CollectFrames(frames, Stack, cnt); - } + std::stable_sort(DLLs, DLLs + DLLCount, Comp); + size_t cnt = CollectBacktrace(Stack, Limit, data); + return CollectFrames(frames, Stack, cnt); +} - size_t CollectFrames(TCollectedFrame* frames, void** stack, size_t cnt) { - for (size_t i = 0; i < cnt; ++i) { - new (frames + i)TCollectedFrame(reinterpret_cast<uintptr_t>(stack[i])); - } - return cnt; - } +size_t CollectFrames(TCollectedFrame* frames, void** stack, size_t cnt) { + for (size_t i = 0; i < cnt; ++i) { + new (frames + i) TCollectedFrame(reinterpret_cast<uintptr_t>(stack[i])); } + return cnt; } - +} // namespace NBacktrace +} // namespace NYql diff --git a/yql/essentials/utils/backtrace/backtrace_lib.h b/yql/essentials/utils/backtrace/backtrace_lib.h index 3404716da68..d0a390bf9ea 100644 --- a/yql/essentials/utils/backtrace/backtrace_lib.h +++ b/yql/essentials/utils/backtrace/backtrace_lib.h @@ -4,15 +4,15 @@ #include <util/generic/vector.h> namespace NYql { - namespace NBacktrace { - size_t CollectBacktrace(void** addresses, size_t limit, void* data); - struct TCollectedFrame { - TCollectedFrame(uintptr_t addr); - TCollectedFrame() = default; - const char* File; - size_t Address; - }; - size_t CollectFrames(TCollectedFrame* frames, void* data); - size_t CollectFrames(TCollectedFrame* frames, void** stack, size_t cnt); - } -}
\ No newline at end of file +namespace NBacktrace { +size_t CollectBacktrace(void** addresses, size_t limit, void* data); +struct TCollectedFrame { + TCollectedFrame(uintptr_t addr); + TCollectedFrame() = default; + const char* File; + size_t Address; +}; +size_t CollectFrames(TCollectedFrame* frames, void* data); +size_t CollectFrames(TCollectedFrame* frames, void** stack, size_t cnt); +} // namespace NBacktrace +} // namespace NYql diff --git a/yql/essentials/utils/backtrace/backtrace_linux.cpp b/yql/essentials/utils/backtrace/backtrace_linux.cpp index c9a1bd5a225..f819a04ae90 100644 --- a/yql/essentials/utils/backtrace/backtrace_linux.cpp +++ b/yql/essentials/utils/backtrace/backtrace_linux.cpp @@ -6,57 +6,57 @@ #include <util/system/backtrace.h> namespace { - size_t BackTrace(void** p, size_t len, ucontext_t* con) { - unw_context_t context; - unw_cursor_t cursor; - if (unw_getcontext(&context)) { - return 0; - } +size_t BackTrace(void** p, size_t len, ucontext_t* con) { + unw_context_t context; + unw_cursor_t cursor; + if (unw_getcontext(&context)) { + return 0; + } - if (unw_init_local(&cursor, &context)) { - return 0; - } - const sigcontext* signal_mcontext = (const sigcontext*)&(con->uc_mcontext); - unw_set_reg(&cursor, UNW_X86_64_RSI, signal_mcontext->rsi); - unw_set_reg(&cursor, UNW_X86_64_RDI, signal_mcontext->rdi); - unw_set_reg(&cursor, UNW_X86_64_RBP, signal_mcontext->rbp); - unw_set_reg(&cursor, UNW_X86_64_RAX, signal_mcontext->rax); - unw_set_reg(&cursor, UNW_X86_64_RBX, signal_mcontext->rbx); - unw_set_reg(&cursor, UNW_X86_64_RCX, signal_mcontext->rcx); - unw_set_reg(&cursor, UNW_X86_64_R8, signal_mcontext->r8); - unw_set_reg(&cursor, UNW_X86_64_R9, signal_mcontext->r9); - unw_set_reg(&cursor, UNW_X86_64_R10, signal_mcontext->r10); - unw_set_reg(&cursor, UNW_X86_64_R11, signal_mcontext->r11); - unw_set_reg(&cursor, UNW_X86_64_R12, signal_mcontext->r12); - unw_set_reg(&cursor, UNW_X86_64_R13, signal_mcontext->r13); - unw_set_reg(&cursor, UNW_X86_64_R14, signal_mcontext->r14); - unw_set_reg(&cursor, UNW_X86_64_R15, signal_mcontext->r15); - unw_set_reg(&cursor, UNW_X86_64_RSP, signal_mcontext->rsp); + if (unw_init_local(&cursor, &context)) { + return 0; + } + const sigcontext* signal_mcontext = (const sigcontext*)&(con->uc_mcontext); + unw_set_reg(&cursor, UNW_X86_64_RSI, signal_mcontext->rsi); + unw_set_reg(&cursor, UNW_X86_64_RDI, signal_mcontext->rdi); + unw_set_reg(&cursor, UNW_X86_64_RBP, signal_mcontext->rbp); + unw_set_reg(&cursor, UNW_X86_64_RAX, signal_mcontext->rax); + unw_set_reg(&cursor, UNW_X86_64_RBX, signal_mcontext->rbx); + unw_set_reg(&cursor, UNW_X86_64_RCX, signal_mcontext->rcx); + unw_set_reg(&cursor, UNW_X86_64_R8, signal_mcontext->r8); + unw_set_reg(&cursor, UNW_X86_64_R9, signal_mcontext->r9); + unw_set_reg(&cursor, UNW_X86_64_R10, signal_mcontext->r10); + unw_set_reg(&cursor, UNW_X86_64_R11, signal_mcontext->r11); + unw_set_reg(&cursor, UNW_X86_64_R12, signal_mcontext->r12); + unw_set_reg(&cursor, UNW_X86_64_R13, signal_mcontext->r13); + unw_set_reg(&cursor, UNW_X86_64_R14, signal_mcontext->r14); + unw_set_reg(&cursor, UNW_X86_64_R15, signal_mcontext->r15); + unw_set_reg(&cursor, UNW_X86_64_RSP, signal_mcontext->rsp); - unw_set_reg(&cursor, UNW_REG_SP, signal_mcontext->rsp); - unw_set_reg(&cursor, UNW_REG_IP, signal_mcontext->rip); + unw_set_reg(&cursor, UNW_REG_SP, signal_mcontext->rsp); + unw_set_reg(&cursor, UNW_REG_IP, signal_mcontext->rip); - size_t pos = 0; - p[pos++] = (void*)signal_mcontext->rip; - while (pos < len && unw_step(&cursor) > 0) { - unw_word_t ip = 0; - unw_get_reg(&cursor, UNW_REG_IP, &ip); - if (unw_is_signal_frame(&cursor)) { - continue; - } - p[pos++] = (void*)ip; + size_t pos = 0; + p[pos++] = (void*)signal_mcontext->rip; + while (pos < len && unw_step(&cursor) > 0) { + unw_word_t ip = 0; + unw_get_reg(&cursor, UNW_REG_IP, &ip); + if (unw_is_signal_frame(&cursor)) { + continue; } - return pos; + p[pos++] = (void*)ip; } + return pos; } +} // namespace namespace NYql { - namespace NBacktrace { - size_t CollectBacktrace(void** addresses, size_t limit, void* data) { - if (!data) { - return BackTrace(addresses, limit); - } - return BackTrace(addresses, limit, reinterpret_cast<ucontext_t*>(data)); - } +namespace NBacktrace { +size_t CollectBacktrace(void** addresses, size_t limit, void* data) { + if (!data) { + return BackTrace(addresses, limit); } -}
\ No newline at end of file + return BackTrace(addresses, limit, reinterpret_cast<ucontext_t*>(data)); +} +} // namespace NBacktrace +} // namespace NYql diff --git a/yql/essentials/utils/backtrace/backtrace_ut.cpp b/yql/essentials/utils/backtrace/backtrace_ut.cpp index 7cf363325e2..741af647ba8 100644 --- a/yql/essentials/utils/backtrace/backtrace_ut.cpp +++ b/yql/essentials/utils/backtrace/backtrace_ut.cpp @@ -3,26 +3,26 @@ #include <util/generic/string.h> #include <library/cpp/testing/unittest/registar.h> namespace { - Y_NO_INLINE void TestTrace394() { - TStringStream ss; - NYql::NBacktrace::KikimrBackTraceFormatImpl(&ss); +Y_NO_INLINE void TestTrace394() { + TStringStream ss; + NYql::NBacktrace::KikimrBackTraceFormatImpl(&ss); #if !defined(_hardening_enabled_) && !defined(_win_) - UNIT_ASSERT_STRING_CONTAINS(ss.Str(), "TestTrace394"); + UNIT_ASSERT_STRING_CONTAINS(ss.Str(), "TestTrace394"); #endif - } - Y_NO_INLINE void TestTrace39114() { - TStringStream ss; - NYql::NBacktrace::KikimrBackTraceFormatImpl(&ss); +} +Y_NO_INLINE void TestTrace39114() { + TStringStream ss; + NYql::NBacktrace::KikimrBackTraceFormatImpl(&ss); #if !defined(_hardening_enabled_) && !defined(_win_) - UNIT_ASSERT_STRING_CONTAINS(ss.Str(), "TestTrace39114"); + UNIT_ASSERT_STRING_CONTAINS(ss.Str(), "TestTrace39114"); #endif - } } +} // namespace Y_UNIT_TEST_SUITE(TEST_BACKTRACE_AND_SYMBOLIZE) { - Y_UNIT_TEST(TEST_NO_KIKIMR) { - NYql::NBacktrace::EnableKikimrSymbolize(); - TestTrace394(); - TestTrace39114(); - } +Y_UNIT_TEST(TEST_NO_KIKIMR) { + NYql::NBacktrace::EnableKikimrSymbolize(); + TestTrace394(); + TestTrace39114(); } +} // Y_UNIT_TEST_SUITE(TEST_BACKTRACE_AND_SYMBOLIZE) diff --git a/yql/essentials/utils/backtrace/symbolize.cpp b/yql/essentials/utils/backtrace/symbolize.cpp index 360ff408c7d..e96c0a313dd 100644 --- a/yql/essentials/utils/backtrace/symbolize.cpp +++ b/yql/essentials/utils/backtrace/symbolize.cpp @@ -7,56 +7,56 @@ namespace NYql { - namespace NBacktrace { - TString Symbolize(const TString& input, const THashMap<TString, TString>& mapping) { +namespace NBacktrace { +TString Symbolize(const TString& input, const THashMap<TString, TString>& mapping) { #if defined(__linux__) && defined(__x86_64__) - TString output; - TStringOutput out(output); - - i64 stackSize = -1; - TVector<TStackFrame> frames; - TVector<TString> usedFilenames; - for (TStringBuf line: StringSplitter(input).SplitByString("\n")) { - if (line.StartsWith("StackFrames:")) { - TVector<TString> parts; - Split(TString(line), " ", parts); - if (parts.size() > 1) { - TryFromString<i64>(parts[1], stackSize); - frames.reserve(stackSize); - } - } else if (line.StartsWith("StackFrame:")) { - TVector<TString> parts; - Split(TString(line), " ", parts); - TString modulePath; - ui64 address; - ui64 offset; - if (parts.size() > 3) { - modulePath = parts[1]; - TryFromString<ui64>(parts[2], address); - TryFromString<ui64>(parts[3], offset); - auto it = mapping.find(modulePath); - if (it != mapping.end()) { - modulePath = it->second; - } - usedFilenames.emplace_back(std::move(modulePath)); - frames.emplace_back(TStackFrame{usedFilenames.back().c_str(), address - offset}); - } - } else { - out << line << "\n"; + TString output; + TStringOutput out(output); + + i64 stackSize = -1; + TVector<TStackFrame> frames; + TVector<TString> usedFilenames; + for (TStringBuf line : StringSplitter(input).SplitByString("\n")) { + if (line.StartsWith("StackFrames:")) { + TVector<TString> parts; + Split(TString(line), " ", parts); + if (parts.size() > 1) { + TryFromString<i64>(parts[1], stackSize); + frames.reserve(stackSize); + } + } else if (line.StartsWith("StackFrame:")) { + TVector<TString> parts; + Split(TString(line), " ", parts); + TString modulePath; + ui64 address; + ui64 offset; + if (parts.size() > 3) { + modulePath = parts[1]; + TryFromString<ui64>(parts[2], address); + TryFromString<ui64>(parts[3], offset); + auto it = mapping.find(modulePath); + if (it != mapping.end()) { + modulePath = it->second; } + usedFilenames.emplace_back(std::move(modulePath)); + frames.emplace_back(TStackFrame{usedFilenames.back().c_str(), address - offset}); } + } else { + out << line << "\n"; + } + } - if (stackSize == 0) { - out << "Empty stack trace\n"; - } - Symbolize(frames.data(), frames.size(), &out); - return output; + if (stackSize == 0) { + out << "Empty stack trace\n"; + } + Symbolize(frames.data(), frames.size(), &out); + return output; #else - Y_UNUSED(mapping); - return input; + Y_UNUSED(mapping); + return input; #endif - } +} - } /* namespace NBacktrace */ +} /* namespace NBacktrace */ } /* namespace NYql */ diff --git a/yql/essentials/utils/backtrace/symbolizer.h b/yql/essentials/utils/backtrace/symbolizer.h index 0d32ba25d35..a3fcb0e6054 100644 --- a/yql/essentials/utils/backtrace/symbolizer.h +++ b/yql/essentials/utils/backtrace/symbolizer.h @@ -5,11 +5,11 @@ #include <util/generic/vector.h> namespace NYql { - namespace NBacktrace { - struct TStackFrame { - const char* File; - size_t Address; - }; - void Symbolize(const TStackFrame* frames, size_t count, IOutputStream* out); - } -}
\ No newline at end of file +namespace NBacktrace { +struct TStackFrame { + const char* File; + size_t Address; +}; +void Symbolize(const TStackFrame* frames, size_t count, IOutputStream* out); +} // namespace NBacktrace +} // namespace NYql diff --git a/yql/essentials/utils/backtrace/symbolizer_linux.cpp b/yql/essentials/utils/backtrace/symbolizer_linux.cpp index 222bc5df2e3..d92e9fc7c03 100644 --- a/yql/essentials/utils/backtrace/symbolizer_linux.cpp +++ b/yql/essentials/utils/backtrace/symbolizer_linux.cpp @@ -23,9 +23,12 @@ const size_t MaxStrLen = 512; const size_t MaxDemangleLen = 1024 * 1024; char Buff[MaxDemangleLen]; -class TNoThrowingMemoryOutput : public TMemoryOutput { +class TNoThrowingMemoryOutput: public TMemoryOutput { public: - TNoThrowingMemoryOutput(void* c, size_t l) : TMemoryOutput(c, l) {} + TNoThrowingMemoryOutput(void* c, size_t l) + : TMemoryOutput(c, l) + { + } void Truncate() { *(Buf_ - 1) = '.'; *(Buf_ - 2) = '.'; @@ -84,67 +87,66 @@ int HandleLibBacktraceFrame(void* data, uintptr_t, const char* filename, int lin out << functionName << " at " << fileName << ":" << lineno << ":0"; return 0; } -} +} // namespace namespace NYql { - namespace NBacktrace { - namespace { - std::mutex Mutex; - char* Result[Limit]; - size_t Order[Limit]; - char TmpBuffer[MaxStrLen * Limit]{}; - auto CreateState(const char* filename) { - return backtrace_create_state( - filename, - 0, - HandleLibBacktraceError, - nullptr - ); - } +namespace NBacktrace { +namespace { +std::mutex Mutex; +char* Result[Limit]; +size_t Order[Limit]; +char TmpBuffer[MaxStrLen * Limit]{}; +auto CreateState(const char* filename) { + return backtrace_create_state( + filename, + 0, + HandleLibBacktraceError, + nullptr); +} +} // namespace + +void Symbolize(const TStackFrame* frames, size_t count, IOutputStream* out) { + if (!count) { + return; + } + memset(TmpBuffer, 0, sizeof(TmpBuffer)); + Result[0] = TmpBuffer; + for (size_t i = 1; i < Limit; ++i) { + Result[i] = Result[i - 1] + MaxStrLen; + } + const std::lock_guard lock{Mutex}; + + std::iota(Order, Order + count, 0u); + std::sort(Order, Order + count, [&frames](auto a, auto b) { return strcmp(frames[a].File, frames[b].File) < 0; }); + + struct backtrace_state* state = nullptr; + for (size_t i = 0; i < count; ++i) { + if (!i || frames[Order[i - 1]].File != frames[Order[i]].File) { + state = CreateState(frames[Order[i]].File); + } + + if (!state) { + Result[Order[i]] = nullptr; // File not found + continue; } - void Symbolize(const TStackFrame* frames, size_t count, IOutputStream* out) { - if (!count) { - return; - } - memset(TmpBuffer, 0, sizeof(TmpBuffer)); - Result[0] = TmpBuffer; - for (size_t i = 1; i < Limit; ++i) { - Result[i] = Result[i - 1] + MaxStrLen; - } - const std::lock_guard lock{Mutex}; - - std::iota(Order, Order + count, 0u); - std::sort(Order, Order + count, [&frames](auto a, auto b) { return strcmp(frames[a].File, frames[b].File) < 0; }); - - struct backtrace_state* state = nullptr; - for (size_t i = 0; i < count; ++i) { - if (!i || frames[Order[i - 1]].File != frames[Order[i]].File) { - state = CreateState(frames[Order[i]].File); - } - - if (!state) { - Result[Order[i]] = nullptr; // File not found - continue; - } - - int status = backtrace_pcinfo( - state, - reinterpret_cast<uintptr_t>(frames[Order[i]].Address) - 1, // last byte of the call instruction - HandleLibBacktraceFrame, - HandleLibBacktraceError, - reinterpret_cast<void*>(Result[Order[i]])); - if (0 != status) { - break; - } - } - for (size_t i = 0; i < count; ++i) { - if (Result[i]) { - *out << Result[i] << "\n"; - } else { - *out << "File `" << frames[i].File << "` not found\n"; - } - } + int status = backtrace_pcinfo( + state, + reinterpret_cast<uintptr_t>(frames[Order[i]].Address) - 1, // last byte of the call instruction + HandleLibBacktraceFrame, + HandleLibBacktraceError, + reinterpret_cast<void*>(Result[Order[i]])); + if (0 != status) { + break; } } -}
\ No newline at end of file + for (size_t i = 0; i < count; ++i) { + if (Result[i]) { + *out << Result[i] << "\n"; + } else { + *out << "File `" << frames[i].File << "` not found\n"; + } + } +} +} // namespace NBacktrace +} // namespace NYql diff --git a/yql/essentials/utils/backtrace/ut/ya.make b/yql/essentials/utils/backtrace/ut/ya.make index c54c56275a9..f81359303ce 100644 --- a/yql/essentials/utils/backtrace/ut/ya.make +++ b/yql/essentials/utils/backtrace/ut/ya.make @@ -1,5 +1,6 @@ UNITTEST_FOR(yql/essentials/utils/backtrace) +ENABLE(YQL_STYLE_CPP) IF (OS_LINUX AND ARCH_X86_64) SRCS( diff --git a/yql/essentials/utils/backtrace/ya.make b/yql/essentials/utils/backtrace/ya.make index 30c2dd1cc11..c9457e772b7 100644 --- a/yql/essentials/utils/backtrace/ya.make +++ b/yql/essentials/utils/backtrace/ya.make @@ -1,5 +1,7 @@ LIBRARY() +ENABLE(YQL_STYLE_CPP) + SRCS( backtrace.cpp backtrace_lib.cpp @@ -31,4 +33,5 @@ ENDIF() END() -RECURSE_FOR_TESTS(ut)
\ No newline at end of file +RECURSE_FOR_TESTS(ut) + |
