Skip to content

Commit 0589396

Browse files
authored
Merge 43e40a5 into 71f7291
2 parents 71f7291 + 43e40a5 commit 0589396

16 files changed

+450
-447
lines changed
Lines changed: 109 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include "backtrace.h"
22

3+
#include <ydb/library/yql/utils/backtrace/libbacktrace/backtrace.h>
4+
#include <ydb/library/yql/utils/backtrace/libbacktrace/symbolizer.h>
5+
36
#include <library/cpp/deprecated/atomic/atomic.h>
47
#include <library/cpp/malloc/api/malloc.h>
58

@@ -15,14 +18,13 @@
1518
#include <util/system/mlock.h>
1619

1720
#ifdef _linux_
18-
#include <dlfcn.h>
19-
#include <link.h>
2021
#include <signal.h>
21-
size_t BackTrace(void** p, size_t len, ucontext_t* signal_ucontext);
2222
#endif
2323

2424
#include <functional>
2525
#include <vector>
26+
#include <sstream>
27+
#include <iostream>
2628

2729
#ifndef _win_
2830

@@ -37,22 +39,21 @@ bool SetSignalHandler(int signo, void (*handler)(int)) {
3739

3840
namespace {
3941
#if defined(_linux_) && defined(_x86_64_)
40-
bool SetSignalAction(int signo, void (*handler)(int, siginfo_t*, void*)) {
41-
struct sigaction sa;
42-
memset(&sa, 0, sizeof(sa));
43-
sa.sa_flags = SA_RESETHAND | SA_SIGINFO;
44-
sa.sa_sigaction = (decltype(sa.sa_sigaction))handler;
45-
sigfillset(&sa.sa_mask);
46-
return sigaction(signo, &sa, nullptr) != -1;
47-
}
42+
bool SetSignalAction(int signo, void (*handler)(int, siginfo_t*, void*)) {
43+
struct sigaction sa;
44+
memset(&sa, 0, sizeof(sa));
45+
sa.sa_flags = SA_RESETHAND | SA_SIGINFO;
46+
sa.sa_sigaction = (decltype(sa.sa_sigaction))handler;
47+
sigfillset(&sa.sa_mask);
48+
return sigaction(signo, &sa, nullptr) != -1;
49+
}
4850
#endif
4951
} // namespace
5052
#endif // _win_
5153

5254
TAtomic BacktraceStarted = 0;
5355

54-
void SetFatalSignalHandler(void (*handler)(int))
55-
{
56+
void SetFatalSignalHandler(void (*handler)(int)) {
5657
Y_UNUSED(handler);
5758
#ifndef _win_
5859
for (int signo: {SIGSEGV, SIGILL, SIGABRT, SIGFPE}) {
@@ -66,147 +67,141 @@ void SetFatalSignalHandler(void (*handler)(int))
6667
#if defined(_linux_) && defined(_x86_64_)
6768
void SetFatalSignalAction(void (*sigaction)(int, siginfo_t*, void*))
6869
{
69-
Y_UNUSED(sigaction);
70-
#ifndef _win_
7170
for (int signo: {SIGSEGV, SIGILL, SIGABRT, SIGFPE}) {
7271
if (!SetSignalAction(signo, sigaction)) {
7372
ythrow TSystemError() << "Cannot set sigaction for signal " << strsignal(signo);
7473
}
7574
}
76-
#endif
7775
}
7876
#endif
7977

80-
#include <sstream>
81-
#include <iostream>
8278
namespace {
83-
std::vector<std::function<void(int)>> Before, After;
84-
void* Stack[300];
85-
bool KikimrSymbolize = false;
86-
87-
void CallCallbacks(decltype(Before)& where, int signum) {
88-
for (const auto &fn: where) {
89-
if (fn) {
90-
fn(signum);
79+
std::vector<std::function<void(int)>> Before, After;
80+
bool KikimrSymbolize = false;
81+
82+
void CallCallbacks(decltype(Before)& where, int signum) {
83+
for (const auto &fn: where) {
84+
if (fn) {
85+
fn(signum);
86+
}
9187
}
9288
}
93-
}
9489

95-
void StackFilledCallback(IOutputStream* out, size_t stack_size) {
96-
auto symbolizer = BuildSymbolizer(KikimrSymbolize);
97-
98-
for (size_t i = 0; i < stack_size; ++i) {
99-
*out << symbolizer->SymbolizeFrame(Stack[i]);
90+
void PrintFrames(IOutputStream* out, const TVector<NYql::NBacktrace::TCollectedFrame>& frames);
91+
92+
void DoBacktrace(IOutputStream* out, void* data) {
93+
PrintFrames(out, NYql::NBacktrace::CollectFrames(data));
10094
}
10195

102-
}
96+
void DoBacktrace(IOutputStream* out, void** stack, size_t cnt) {
97+
PrintFrames(out, NYql::NBacktrace::CollectFrames(stack, cnt));
98+
}
99+
103100

104-
void SignalHandler(int signum)
105-
{
106-
CallCallbacks(Before, signum);
101+
void SignalHandler(int signum) {
102+
CallCallbacks(Before, signum);
107103

108-
if (!NMalloc::IsAllocatorCorrupted) {
109-
if (!AtomicTryLock(&BacktraceStarted)) {
110-
return;
104+
if (!NMalloc::IsAllocatorCorrupted) {
105+
if (!AtomicTryLock(&BacktraceStarted)) {
106+
return;
107+
}
108+
109+
UnlockAllMemory();
110+
DoBacktrace(&Cerr, nullptr);
111111
}
112112

113-
UnlockAllMemory();
114-
115-
const size_t s = BackTrace(Stack, Y_ARRAY_SIZE(Stack));
116-
StackFilledCallback(&Cerr, s);
113+
CallCallbacks(After, signum);
114+
raise(signum);
117115
}
118-
119-
CallCallbacks(After, signum);
120-
121-
raise(signum);
122-
}
123116

124117
#if defined(_linux_) && defined(_x86_64_)
125-
void SignalAction(int signum, siginfo_t* sinfo, void* context)
126-
{
127-
Y_UNUSED(SignalHandler);
128-
CallCallbacks(Before, signum);
129-
Y_UNUSED(sinfo);
118+
void SignalAction(int signum, siginfo_t*, void* context) {
119+
Y_UNUSED(SignalHandler);
120+
CallCallbacks(Before, signum);
130121

131-
if (!NMalloc::IsAllocatorCorrupted) {
132-
if (!AtomicTryLock(&BacktraceStarted)) {
133-
return;
134-
}
122+
if (!NMalloc::IsAllocatorCorrupted) {
123+
if (!AtomicTryLock(&BacktraceStarted)) {
124+
return;
125+
}
135126

136-
UnlockAllMemory();
137-
const size_t s = BackTrace(Stack, Y_ARRAY_SIZE(Stack), (ucontext_t*)context);
138-
StackFilledCallback(&Cerr, s);
127+
UnlockAllMemory();
128+
DoBacktrace(&Cerr, context);
129+
}
130+
131+
CallCallbacks(After, signum);
132+
raise(signum);
139133
}
140-
141-
CallCallbacks(After, signum);
142-
143-
raise(signum);
144-
}
145134
#endif
146-
147135
}
148136

149137
namespace NYql {
138+
namespace NBacktrace {
139+
THashMap<TString, TString> Mapping;
150140

151-
namespace NBacktrace {
152-
153-
THashMap<TString, TString> Mapping;
141+
void SetModulesMapping(const THashMap<TString, TString>& mapping) {
142+
Mapping = mapping;
143+
}
154144

155-
void SetModulesMapping(const THashMap<TString, TString>& mapping) {
156-
Mapping = mapping;
157-
}
145+
void AddBeforeFatalCallback(const std::function<void(int)>& before) {
146+
Before.push_back(before);
147+
}
158148

159-
void AddBeforeFatalCallback(const std::function<void(int)>& before) {
160-
Before.push_back(before);
161-
}
149+
void AddAfterFatalCallback(const std::function<void(int)>& after) {
150+
After.push_back(after);
151+
}
162152

163-
void AddAfterFatalCallback(const std::function<void(int)>& after) {
164-
After.push_back(after);
165-
}
153+
void RegisterKikimrFatalActions() {
154+
#if defined(_linux_) && defined(_x86_64_)
155+
SetFatalSignalAction(SignalAction);
156+
#else
157+
SetFatalSignalHandler(SignalHandler);
158+
#endif
159+
}
166160

167-
void RegisterKikimrFatalActions() {
168-
#if !defined(_linux_) || !defined(_x86_64_)
169-
SetFatalSignalHandler(SignalHandler);
170-
#else
171-
SetFatalSignalAction(SignalAction);
172-
#endif
173-
}
161+
void EnableKikimrSymbolize() {
162+
KikimrSymbolize = true;
163+
}
174164

175-
void EnableKikimrSymbolize() {
176-
KikimrSymbolize = true;
177-
}
165+
void KikimrBackTrace() {
166+
KikimrBackTraceFormatImpl(&Cerr);
167+
}
178168

179-
void KikimrBackTrace() {
180-
KikimrBackTraceFormatImpl(&Cerr);
181-
}
169+
void KikimrBackTraceFormatImpl(IOutputStream* out) {
170+
KikimrSymbolize = true;
171+
UnlockAllMemory();
172+
DoBacktrace(out, nullptr);
173+
}
182174

183-
void KikimrBackTraceFormatImpl(IOutputStream* out) {
184-
KikimrSymbolize = true;
185-
UnlockAllMemory();
186-
void* array[300];
187-
const size_t s = BackTrace(array, Y_ARRAY_SIZE(array));
188-
StackFilledCallback(out, s);
189-
}
175+
void KikimrBacktraceFormatImpl(IOutputStream* out, void* const* stack, size_t stackSize) {
176+
KikimrSymbolize = true;
177+
DoBacktrace(out, (void**)stack, stackSize);
178+
}
190179

191-
void KikimrBacktraceFormatImpl(IOutputStream* out, void* const* stack, size_t stackSize) {
192-
KikimrSymbolize = true;
193-
for (size_t i = 0; i < stackSize; ++i) {
194-
Stack[i] = stack[i];
195180
}
196-
197-
StackFilledCallback(out, stackSize);
198-
}
199-
200-
}
201-
}
202-
203-
TString IBacktraceSymbolizer::SymbolizeFrame(void* ptr) {
204-
Y_UNUSED(ptr);
205-
return "";
206-
}
207-
IBacktraceSymbolizer::~IBacktraceSymbolizer() {
208181
}
209182

210183
void EnableKikimrBacktraceFormat() {
211184
SetFormatBackTraceFn(NYql::NBacktrace::KikimrBacktraceFormatImpl);
185+
}
186+
187+
namespace {
188+
void PrintFrames(IOutputStream* out, const TVector<NYql::NBacktrace::TCollectedFrame>& frames) {
189+
auto& outp = *out;
190+
if (KikimrSymbolize) {
191+
TVector<NYql::NBacktrace::TStackFrame> sFrames(frames.size());
192+
for (size_t i = 0; i < frames.size(); ++i) {
193+
sFrames[i] = NYql::NBacktrace::TStackFrame{frames[i].File, frames[i].Address};
194+
}
195+
auto symbolized = NYql::NBacktrace::Symbolize(sFrames);
196+
for (auto& line: symbolized) {
197+
outp << line << "\n";
198+
}
199+
return;
200+
}
201+
outp << "StackFrames: " << frames.size() << "\n";
202+
for (auto &frame: frames) {
203+
auto it = NYql::NBacktrace::Mapping.find(frame.File);
204+
Cerr << "StackFrame: " << (it == NYql::NBacktrace::Mapping.end() ? frame.File : it->second) << " " << frame.Address << "\n";
205+
}
206+
}
212207
}

ydb/library/yql/utils/backtrace/backtrace.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#pragma once
2-
#include "symbolizer.h"
32

43
#include <util/system/types.h>
54
#include <util/generic/string.h>

ydb/library/yql/utils/backtrace/backtrace_in_context.cpp

Lines changed: 0 additions & 46 deletions
This file was deleted.
Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
#include "backtrace.h"
2-
#include "symbolizer.h"
32
#include <util/generic/vector.h>
43
#include <util/generic/string.h>
54
#include <library/cpp/testing/unittest/registar.h>
65
namespace {
7-
Y_NO_INLINE void TestTrace() {
8-
void* array[300];
9-
const size_t s = BackTrace(array, Y_ARRAY_SIZE(array));
10-
auto symbolizer = BuildSymbolizer(false);
11-
TStringBuilder output;
12-
for (size_t i = 0; i < s; ++i) {
13-
output << symbolizer->SymbolizeFrame(array[i]);
14-
}
6+
Y_NO_INLINE void TestTrace394() {
7+
TStringStream ss;
8+
NYql::NBacktrace::KikimrBackTraceFormatImpl(&ss);
159
#if !defined(_hardening_enabled_) && !defined(_win_)
16-
UNIT_ASSERT_STRING_CONTAINS(NYql::NBacktrace::Symbolize(output, {}), "(anonymous namespace)::TestTrace");
10+
UNIT_ASSERT_STRING_CONTAINS(ss.Str(), "(anonymous namespace)::TestTrace394()");
11+
#endif
12+
}
13+
Y_NO_INLINE void TestTrace39114() {
14+
TStringStream ss;
15+
NYql::NBacktrace::KikimrBackTraceFormatImpl(&ss);
16+
#if !defined(_hardening_enabled_) && !defined(_win_)
17+
UNIT_ASSERT_STRING_CONTAINS(ss.Str(), "(anonymous namespace)::TestTrace39114()");
1718
#endif
1819
}
1920
}
2021

2122
Y_UNIT_TEST_SUITE(TEST_BACKTRACE_AND_SYMBOLIZE) {
2223
Y_UNIT_TEST(TEST_NO_KIKIMR) {
23-
TestTrace();
24+
NYql::NBacktrace::EnableKikimrSymbolize();
25+
TestTrace394();
26+
TestTrace39114();
2427
}
2528
}

0 commit comments

Comments
 (0)