aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/utils/backtrace/symbolize.cpp
blob: 360ff408c7d655d62feaa19498cbb3e7a73c8dce (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "backtrace.h"

#include "symbolizer.h"

#include <util/string/split.h>
#include <util/stream/str.h>

namespace NYql {

    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";
                }
            }

            if (stackSize == 0) {
                out << "Empty stack trace\n";
            }
            Symbolize(frames.data(), frames.size(), &out);
            return output;
#else
            Y_UNUSED(mapping);
            return input;
#endif
        }

    } /* namespace NBacktrace */

} /* namespace NYql */