/root/doris/be/src/common/stack_trace.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | // This file is copied from |
18 | | // https://github.com/ClickHouse/ClickHouse/blob/master/src/Common/StackTrace.h |
19 | | // and modified by Doris |
20 | | |
21 | | #pragma once |
22 | | |
23 | | #include <array> |
24 | | #include <csignal> |
25 | | #include <cstdint> |
26 | | #include <functional> |
27 | | #include <optional> |
28 | | #include <string> |
29 | | #include <vector> |
30 | | |
31 | | #ifdef __APPLE__ |
32 | | // ucontext is not available without _XOPEN_SOURCE |
33 | | #ifdef __clang__ |
34 | | #pragma clang diagnostic ignored "-Wreserved-id-macro" |
35 | | #endif |
36 | | #define _XOPEN_SOURCE 700 |
37 | | #endif |
38 | | #include <ucontext.h> |
39 | | |
40 | | struct NoCapture {}; |
41 | | |
42 | | /// Tries to capture current stack trace using libunwind or signal context |
43 | | /// NOTE: StackTrace calculation is signal safe only if updatePHDRCache() was called beforehand. |
44 | | class StackTrace { |
45 | | public: |
46 | | struct Frame { |
47 | | const void* virtual_addr = nullptr; |
48 | | void* physical_addr = nullptr; |
49 | | std::optional<std::string> symbol; |
50 | | std::optional<std::string> object; |
51 | | std::optional<std::string> file; |
52 | | std::optional<uint64_t> line; |
53 | | }; |
54 | | |
55 | | /* NOTE: It cannot be larger right now, since otherwise it |
56 | | * will not fit into minimal PIPE_BUF (512) in TraceCollector. |
57 | | */ |
58 | | static constexpr size_t capacity = 45; |
59 | | |
60 | | using FramePointers = std::array<void*, capacity>; |
61 | | using Frames = std::array<Frame, capacity>; |
62 | | |
63 | | /// Tries to capture stack trace |
64 | 35 | inline StackTrace() { tryCapture(); } |
65 | | |
66 | | /// Tries to capture stack trace. Fallbacks on parsing caller address from |
67 | | /// signal context if no stack trace could be captured |
68 | | explicit StackTrace(const ucontext_t& signal_context); |
69 | | |
70 | | /// Creates empty object for deferred initialization |
71 | 0 | explicit inline StackTrace(NoCapture) {} |
72 | | |
73 | 0 | [[nodiscard]] constexpr size_t getSize() const { return size; } |
74 | 0 | [[nodiscard]] constexpr size_t getOffset() const { return offset; } |
75 | 0 | [[nodiscard]] const FramePointers& getFramePointers() const { return frame_pointers; } |
76 | | [[nodiscard]] std::string toString(int start_pointers_index = 0, |
77 | | const std::string& dwarf_location_info_mode = "FAST") const; |
78 | | |
79 | | static std::string toString(void** frame_pointers, size_t offset, size_t size, |
80 | | const std::string& dwarf_location_info_mode = "FAST"); |
81 | | static void createCache(); |
82 | | static void dropCache(); |
83 | | static void symbolize(const FramePointers& frame_pointers, size_t offset, size_t size, |
84 | | StackTrace::Frames& frames); |
85 | | |
86 | | void toStringEveryLine(std::function<void(std::string_view)> callback) const; |
87 | | |
88 | | /// Displaying the addresses can be disabled for security reasons. |
89 | | /// If you turn off addresses, it will be more secure, but we will be unable to help you with debugging. |
90 | | /// Please note: addresses are also available in the system.stack_trace and system.trace_log tables. |
91 | | static void setShowAddresses(bool show); |
92 | | |
93 | | protected: |
94 | | void tryCapture(); |
95 | | |
96 | | size_t size = 0; |
97 | | size_t offset = 0; /// How many frames to skip while displaying. |
98 | | FramePointers frame_pointers {}; |
99 | | }; |
100 | | |
101 | | std::string signalToErrorMessage(int sig, const siginfo_t& info, const ucontext_t& context); |