Coverage Report

Created: 2026-07-03 12:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/common/stack_trace.h
Line
Count
Source
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: Signal-context unwinding must enable ScopedPHDRCacheRead around the libunwind call so an
44
/// interrupted thread does not re-enter glibc's loader lock through dl_iterate_phdr.
45
class StackTrace {
46
public:
47
    struct Frame {
48
        const void* virtual_addr = nullptr;
49
        void* physical_addr = nullptr;
50
        std::optional<std::string> symbol;
51
        std::optional<std::string> object;
52
        std::optional<std::string> file;
53
        std::optional<uint64_t> line;
54
    };
55
56
    /* NOTE: It cannot be larger right now, since otherwise it
57
     * will not fit into minimal PIPE_BUF (512) in TraceCollector.
58
     */
59
    static constexpr size_t capacity = 45;
60
61
    using FramePointers = std::array<void*, capacity>;
62
    using Frames = std::array<Frame, capacity>;
63
64
    /// Tries to capture stack trace
65
79.7M
    inline StackTrace() { tryCapture(); }
66
67
    /// Tries to capture stack trace. Fallbacks on parsing caller address from
68
    /// signal context if no stack trace could be captured
69
    explicit StackTrace(const ucontext_t& signal_context);
70
71
    /// Creates empty object for deferred initialization
72
0
    explicit inline StackTrace(NoCapture) {}
73
74
0
    [[nodiscard]] constexpr size_t getSize() const { return size; }
75
0
    [[nodiscard]] constexpr size_t getOffset() const { return offset; }
76
0
    [[nodiscard]] const FramePointers& getFramePointers() const { return frame_pointers; }
77
    [[nodiscard]] std::string toString(int start_pointers_index = 0,
78
                                       const std::string& dwarf_location_info_mode = "FAST") const;
79
80
    static std::string toString(void** frame_pointers, size_t offset, size_t size,
81
                                const std::string& dwarf_location_info_mode = "FAST");
82
    static void createCache();
83
    static void dropCache();
84
    static void symbolize(const FramePointers& frame_pointers, size_t offset, size_t size,
85
                          StackTrace::Frames& frames);
86
87
    void toStringEveryLine(std::function<void(std::string_view)> callback) const;
88
89
    /// Displaying the addresses can be disabled for security reasons.
90
    /// If you turn off addresses, it will be more secure, but we will be unable to help you with debugging.
91
    /// Please note: addresses are also available in the system.stack_trace and system.trace_log tables.
92
    static void setShowAddresses(bool show);
93
94
protected:
95
    void tryCapture();
96
97
    size_t size = 0;
98
    size_t offset = 0; /// How many frames to skip while displaying.
99
    FramePointers frame_pointers {};
100
};
101
102
std::string signalToErrorMessage(int sig, const siginfo_t& info, const ucontext_t& context);