diff options
author | max42 <max42@yandex-team.com> | 2023-07-29 00:02:16 +0300 |
---|---|---|
committer | max42 <max42@yandex-team.com> | 2023-07-29 00:02:16 +0300 |
commit | 73b89de71748a21e102d27b9f3ed1bf658766cb5 (patch) | |
tree | 188bbd2d622fa91cdcbb1b6d6d77fbc84a0646f5 /library/cpp/dwarf_backtrace/backtrace.cpp | |
parent | 528e321bcc2a2b67b53aeba58c3bd88305a141ee (diff) | |
download | ydb-73b89de71748a21e102d27b9f3ed1bf658766cb5.tar.gz |
YT-19210: expose YQL shared library for YT.
After this, a new target libyqlplugin.so appears. in open-source cmake build.
Diff in open-source YDB repo looks like the following: https://paste.yandex-team.ru/f302bdb4-7ef2-4362-91c7-6ca45f329264
Diffstat (limited to 'library/cpp/dwarf_backtrace/backtrace.cpp')
-rw-r--r-- | library/cpp/dwarf_backtrace/backtrace.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/library/cpp/dwarf_backtrace/backtrace.cpp b/library/cpp/dwarf_backtrace/backtrace.cpp new file mode 100644 index 0000000000..a955d07249 --- /dev/null +++ b/library/cpp/dwarf_backtrace/backtrace.cpp @@ -0,0 +1,62 @@ +#include "backtrace.h" + +#include <contrib/libs/backtrace/backtrace.h> + +#include <util/generic/yexception.h> +#include <util/system/type_name.h> +#include <util/system/execpath.h> + +namespace NDwarf { + namespace { + struct TContext { + TCallback& Callback; + int Counter = 0; + TMaybe<TError> Error; + }; + + void HandleLibBacktraceError(void* data, const char* msg, int errnum) { + auto* context = reinterpret_cast<TContext*>(data); + context->Error = TError{.Code = errnum, .Message=msg}; + } + + int HandleLibBacktraceFrame(void* data, uintptr_t pc, const char* filename, int lineno, const char* function) { + auto* context = reinterpret_cast<TContext*>(data); + TLineInfo lineInfo{ + .FileName = filename != nullptr ? filename : "???", + .Line = lineno, + .Col = 0, // libbacktrace doesn't provide column numbers, so fill this field with a dummy value. + .FunctionName = function != nullptr ? CppDemangle(function) : "???", + .Address = pc, + .Index = context->Counter++, + }; + return static_cast<int>(context->Callback(lineInfo)); + } + } + + TMaybe<TError> ResolveBacktrace(TArrayRef<const void* const> backtrace, TCallback callback) { + TContext context{.Callback = callback}; + // Intentionally never freed (see https://a.yandex-team.ru/arc/trunk/arcadia/contrib/libs/backtrace/backtrace.h?rev=6789902#L80). + static auto* state = backtrace_create_state( + GetPersistentExecPath().c_str(), + 1 /* threaded */, + HandleLibBacktraceError, + &context /* data for the error callback */ + ); + if (nullptr == state) { + static const auto initError = context.Error; + return initError; + } + for (const void* address : backtrace) { + int status = backtrace_pcinfo( + state, + reinterpret_cast<uintptr_t>(address) - 1, // last byte of the call instruction + HandleLibBacktraceFrame, + HandleLibBacktraceError, + &context /* data for both callbacks */); + if (0 != status) { + break; + } + } + return context.Error; + } +} |