Skip to content

Commit 32f9f28

Browse files
authored
Merge 14e4664 into c192563
2 parents c192563 + 14e4664 commit 32f9f28

13 files changed

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

3+
#include "backtrace_lib.h"
4+
#include "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,150 @@ 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+
const int Limit = 400;
82+
NYql::NBacktrace::TCollectedFrame Frames[Limit];
83+
84+
void CallCallbacks(decltype(Before)& where, int signum) {
85+
for (const auto &fn: where) {
86+
if (fn) {
87+
fn(signum);
88+
}
9189
}
9290
}
93-
}
9491

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]);
92+
void PrintFrames(IOutputStream* out, const NYql::NBacktrace::TCollectedFrame* frames, size_t cnt);
93+
94+
void DoBacktrace(IOutputStream* out, void* data) {
95+
auto cnt = NYql::NBacktrace::CollectFrames(Frames, data);
96+
PrintFrames(out, Frames, cnt);
10097
}
10198

102-
}
99+
void DoBacktrace(IOutputStream* out, void** stack, size_t cnt) {
100+
Y_UNUSED(NYql::NBacktrace::CollectFrames(Frames, stack, cnt));
101+
PrintFrames(out, Frames, cnt);
102+
}
103+
103104

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

108-
if (!NMalloc::IsAllocatorCorrupted) {
109-
if (!AtomicTryLock(&BacktraceStarted)) {
110-
return;
108+
if (!NMalloc::IsAllocatorCorrupted) {
109+
if (!AtomicTryLock(&BacktraceStarted)) {
110+
return;
111+
}
112+
113+
UnlockAllMemory();
114+
DoBacktrace(&Cerr, nullptr);
111115
}
112116

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

124121
#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);
122+
void SignalAction(int signum, siginfo_t*, void* context) {
123+
Y_UNUSED(SignalHandler);
124+
CallCallbacks(Before, signum);
130125

131-
if (!NMalloc::IsAllocatorCorrupted) {
132-
if (!AtomicTryLock(&BacktraceStarted)) {
133-
return;
134-
}
126+
if (!NMalloc::IsAllocatorCorrupted) {
127+
if (!AtomicTryLock(&BacktraceStarted)) {
128+
return;
129+
}
135130

136-
UnlockAllMemory();
137-
const size_t s = BackTrace(Stack, Y_ARRAY_SIZE(Stack), (ucontext_t*)context);
138-
StackFilledCallback(&Cerr, s);
131+
UnlockAllMemory();
132+
DoBacktrace(&Cerr, context);
133+
}
134+
135+
CallCallbacks(After, signum);
136+
raise(signum);
139137
}
140-
141-
CallCallbacks(After, signum);
142-
143-
raise(signum);
144-
}
145138
#endif
146-
147139
}
148140

149141
namespace NYql {
142+
namespace NBacktrace {
143+
THashMap<TString, TString> Mapping;
150144

151-
namespace NBacktrace {
152-
153-
THashMap<TString, TString> Mapping;
145+
void SetModulesMapping(const THashMap<TString, TString>& mapping) {
146+
Mapping = mapping;
147+
}
154148

155-
void SetModulesMapping(const THashMap<TString, TString>& mapping) {
156-
Mapping = mapping;
157-
}
149+
void AddBeforeFatalCallback(const std::function<void(int)>& before) {
150+
Before.push_back(before);
151+
}
158152

159-
void AddBeforeFatalCallback(const std::function<void(int)>& before) {
160-
Before.push_back(before);
161-
}
153+
void AddAfterFatalCallback(const std::function<void(int)>& after) {
154+
After.push_back(after);
155+
}
162156

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

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

175-
void EnableKikimrSymbolize() {
176-
KikimrSymbolize = true;
177-
}
169+
void KikimrBackTrace() {
170+
KikimrBackTraceFormatImpl(&Cerr);
171+
}
178172

179-
void KikimrBackTrace() {
180-
KikimrBackTraceFormatImpl(&Cerr);
181-
}
173+
void KikimrBackTraceFormatImpl(IOutputStream* out) {
174+
KikimrSymbolize = true;
175+
UnlockAllMemory();
176+
DoBacktrace(out, nullptr);
177+
}
182178

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-
}
179+
void KikimrBacktraceFormatImpl(IOutputStream* out, void* const* stack, size_t stackSize) {
180+
KikimrSymbolize = true;
181+
DoBacktrace(out, (void**)stack, stackSize);
182+
}
190183

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];
195184
}
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() {
208185
}
209186

210187
void EnableKikimrBacktraceFormat() {
211188
SetFormatBackTraceFn(NYql::NBacktrace::KikimrBacktraceFormatImpl);
189+
}
190+
191+
namespace {
192+
void PrintFrames(IOutputStream* out, const NYql::NBacktrace::TCollectedFrame* frames, size_t count) {
193+
auto& outp = *out;
194+
if (KikimrSymbolize) {
195+
TVector<NYql::NBacktrace::TStackFrame> sFrames(count);
196+
for (size_t i = 0; i < count; ++i) {
197+
sFrames[i] = NYql::NBacktrace::TStackFrame{frames[i].File, frames[i].Address};
198+
}
199+
auto symbolized = NYql::NBacktrace::Symbolize(sFrames);
200+
for (auto& line: symbolized) {
201+
outp << line << "\n";
202+
}
203+
return;
204+
}
205+
outp << "StackFrames: " << count << "\n";
206+
for (size_t i = 0; i < count; ++i) {
207+
auto& frame = frames[i];
208+
auto fileName = frame.File;
209+
if (!strcmp(fileName, "/proc/self/exe")) {
210+
fileName = "EXE";
211+
}
212+
auto it = NYql::NBacktrace::Mapping.find(fileName);
213+
outp << "StackFrame: " << (it == NYql::NBacktrace::Mapping.end() ? fileName : it->second) << " " << frame.Address << "\n";
214+
}
215+
}
212216
}

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>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "backtrace_lib.h"
2+
3+
#include <util/system/backtrace.h>
4+
5+
namespace NYql {
6+
namespace NBacktrace {
7+
size_t CollectBacktrace(void** addresses, size_t limit, void*) {
8+
return BackTrace(addresses, limit);
9+
}
10+
}
11+
}

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

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)