aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/dwarf_backtrace/backtrace.cpp
diff options
context:
space:
mode:
authormax42 <max42@yandex-team.com>2023-07-29 00:02:16 +0300
committermax42 <max42@yandex-team.com>2023-07-29 00:02:16 +0300
commit73b89de71748a21e102d27b9f3ed1bf658766cb5 (patch)
tree188bbd2d622fa91cdcbb1b6d6d77fbc84a0646f5 /library/cpp/dwarf_backtrace/backtrace.cpp
parent528e321bcc2a2b67b53aeba58c3bd88305a141ee (diff)
downloadydb-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.cpp62
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;
+ }
+}