Coverage Report

Created: 2024-11-21 17:33

/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);