Coverage Report

Created: 2026-08-06 13:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/common/signal_handler.h
Line
Count
Source
1
// Copyright (c) 2008, Google Inc.
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are
6
// met:
7
//
8
//     * Redistributions of source code must retain the above copyright
9
// notice, this list of conditions and the following disclaimer.
10
//     * Redistributions in binary form must reproduce the above
11
// copyright notice, this list of conditions and the following disclaimer
12
// in the documentation and/or other materials provided with the
13
// distribution.
14
//     * Neither the name of Google Inc. nor the names of its
15
// contributors may be used to endorse or promote products derived from
16
// this software without specific prior written permission.
17
//
18
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
//
30
// Author: Satoru Takabayashi
31
//
32
// Implementation of InstallFailureSignalHandler().
33
34
#pragma once
35
36
#include <butil/macros.h> // ARRAYSIZE_UNSAFE
37
#include <glog/logging.h>
38
39
#include <boost/stacktrace.hpp>
40
#include <csignal>
41
#include <ctime>
42
43
#include "common/version_internal.h"
44
#ifdef HAVE_UCONTEXT_H
45
#include <ucontext.h>
46
#endif
47
#ifdef HAVE_SYS_UCONTEXT_H
48
#include <sys/ucontext.h>
49
#endif
50
#include <algorithm>
51
52
namespace doris::signal {
53
54
inline thread_local uint64_t query_id_hi;
55
inline thread_local uint64_t query_id_lo;
56
inline thread_local int64_t tablet_id = 0;
57
inline thread_local bool is_nereids = false;
58
59
namespace {
60
61
// We'll install the failure signal handler for these signals.  We could
62
// use strsignal() to get signal names, but we don't use it to avoid
63
// introducing yet another #ifdef complication.
64
//
65
// The list should be synced with the comment in signalhandler.h.
66
const struct {
67
    int number;
68
    const char* name = nullptr;
69
} kFailureSignals[] = {
70
        {SIGSEGV, "SIGSEGV"}, {SIGILL, "SIGILL"}, {SIGFPE, "SIGFPE"},
71
        {SIGABRT, "SIGABRT"}, {SIGBUS, "SIGBUS"}, {SIGTERM, "SIGTERM"},
72
};
73
74
static bool kFailureSignalHandlerInstalled = false;
75
76
/*
77
 * Copyright (c) Meta Platforms, Inc. and affiliates.
78
 *
79
 * Licensed under the Apache License, Version 2.0 (the "License");
80
 * you may not use this file except in compliance with the License.
81
 * You may obtain a copy of the License at
82
 *
83
 *     http://www.apache.org/licenses/LICENSE-2.0
84
 *
85
 * Unless required by applicable law or agreed to in writing, software
86
 * distributed under the License is distributed on an "AS IS" BASIS,
87
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88
 * See the License for the specific language governing permissions and
89
 * limitations under the License.
90
 * These signal explainer is copied from Meta's Folly
91
 */
92
0
const char* sigill_reason(int si_code) {
93
0
    switch (si_code) {
94
0
    case ILL_ILLOPC:
95
0
        return "illegal opcode";
96
0
    case ILL_ILLOPN:
97
0
        return "illegal operand";
98
0
    case ILL_ILLADR:
99
0
        return "illegal addressing mode";
100
0
    case ILL_ILLTRP:
101
0
        return "illegal trap";
102
0
    case ILL_PRVOPC:
103
0
        return "privileged opcode";
104
0
    case ILL_PRVREG:
105
0
        return "privileged register";
106
0
    case ILL_COPROC:
107
0
        return "coprocessor error";
108
0
    case ILL_BADSTK:
109
0
        return "internal stack error";
110
0
111
0
    default:
112
0
        return nullptr;
113
0
    }
114
0
}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_113sigill_reasonEi
115
116
0
const char* sigfpe_reason(int si_code) {
117
0
    switch (si_code) {
118
0
    case FPE_INTDIV:
119
0
        return "integer divide by zero";
120
0
    case FPE_INTOVF:
121
0
        return "integer overflow";
122
0
    case FPE_FLTDIV:
123
0
        return "floating-point divide by zero";
124
0
    case FPE_FLTOVF:
125
0
        return "floating-point overflow";
126
0
    case FPE_FLTUND:
127
0
        return "floating-point underflow";
128
0
    case FPE_FLTRES:
129
0
        return "floating-point inexact result";
130
0
    case FPE_FLTINV:
131
0
        return "floating-point invalid operation";
132
0
    case FPE_FLTSUB:
133
0
        return "subscript out of range";
134
0
135
0
    default:
136
0
        return nullptr;
137
0
    }
138
0
}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_113sigfpe_reasonEi
139
140
0
const char* sigsegv_reason(int si_code) {
141
0
    switch (si_code) {
142
0
    case SEGV_MAPERR:
143
0
        return "address not mapped to object";
144
0
    case SEGV_ACCERR:
145
0
        return "invalid permissions for mapped object";
146
0
147
0
    default:
148
0
        return nullptr;
149
0
    }
150
0
}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_114sigsegv_reasonEi
151
152
0
const char* sigbus_reason(int si_code) {
153
0
    switch (si_code) {
154
0
    case BUS_ADRALN:
155
0
        return "invalid address alignment";
156
0
    case BUS_ADRERR:
157
0
        return "nonexistent physical address";
158
0
    case BUS_OBJERR:
159
0
        return "object-specific hardware error";
160
0
161
0
        // MCEERR_AR and MCEERR_AO: in sigaction(2) but not in headers.
162
0
163
0
    default:
164
0
        return nullptr;
165
0
    }
166
0
}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_113sigbus_reasonEi
167
168
0
const char* signal_reason(int signum, int si_code) {
169
0
    switch (signum) {
170
0
    case SIGILL:
171
0
        return sigill_reason(si_code);
172
0
    case SIGFPE:
173
0
        return sigfpe_reason(si_code);
174
0
    case SIGSEGV:
175
0
        return sigsegv_reason(si_code);
176
0
    case SIGBUS:
177
0
        return sigbus_reason(si_code);
178
0
    default:
179
0
        return nullptr;
180
0
    }
181
0
}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_113signal_reasonEii
182
183
// The class is used for formatting error messages.  We don't use printf()
184
// as it's not async signal safe.
185
class MinimalFormatter {
186
public:
187
    MinimalFormatter(char* buffer, size_t size)
188
0
            : buffer_(buffer), cursor_(buffer), end_(buffer + size) {}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatterC2EPcm
189
190
    // Returns the number of bytes written in the buffer.
191
0
    std::size_t num_bytes_written() const { return static_cast<std::size_t>(cursor_ - buffer_); }
Unexecuted instantiation: rowid_fetcher.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
Unexecuted instantiation: vtablet_writer.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
Unexecuted instantiation: schema_change.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
Unexecuted instantiation: tablet.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
Unexecuted instantiation: thread_context.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
Unexecuted instantiation: internal_service.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
Unexecuted instantiation: fold_constant_executor.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
Unexecuted instantiation: load_stream.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
Unexecuted instantiation: memtable_flush_executor.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
Unexecuted instantiation: cloud_storage_engine.cpp:_ZNK5doris6signal12_GLOBAL__N_116MinimalFormatter17num_bytes_writtenEv
192
193
    // Appends string from "str" and updates the internal cursor.
194
0
    void AppendString(const char* str) {
195
0
        ptrdiff_t i = 0;
196
0
        while (str[i] != '\0' && cursor_ + i < end_) {
197
0
            cursor_[i] = str[i];
198
0
            ++i;
199
0
        }
200
0
        cursor_ += i;
201
0
    }
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendStringEPKc
202
203
    // Formats "number" in "radix" and updates the internal cursor.
204
    // Lowercase letters are used for 'a' - 'z'.
205
0
    void AppendUint64(uint64_t number, unsigned radix) {
206
0
        unsigned i = 0;
207
0
        while (cursor_ + i < end_) {
208
0
            const uint64_t tmp = number % radix;
209
0
            number /= radix;
210
0
            cursor_[i] = static_cast<char>(tmp < 10 ? '0' + tmp : 'a' + tmp - 10);
211
0
            ++i;
212
0
            if (number == 0) {
213
0
                break;
214
0
            }
215
0
        }
216
0
        // Reverse the bytes written.
217
0
        std::reverse(cursor_, cursor_ + i);
218
0
        cursor_ += i;
219
0
    }
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_116MinimalFormatter12AppendUint64Emj
220
221
private:
222
    char* buffer_ = nullptr;
223
    char* cursor_ = nullptr;
224
    const char* const end_;
225
};
226
227
// Writes the given data with the size to the standard error.
228
0
void WriteToStderr(const char* data, size_t size) {
229
0
    if (write(STDERR_FILENO, data, size) < 0) {
230
0
        // Ignore errors.
231
0
    }
232
0
}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_113WriteToStderrEPKcm
233
234
// The writer function can be changed by InstallFailureWriter().
235
void (*g_failure_writer)(const char* data, size_t size) = WriteToStderr;
236
237
// Dumps time information.  We don't dump human-readable time information
238
// as localtime() is not guaranteed to be async signal safe.
239
0
void DumpTimeInfo() {
240
0
    time_t time_in_sec = time(nullptr);
241
0
    char buf[256]; // Big enough for time info.
242
0
    MinimalFormatter formatter(buf, sizeof(buf));
243
0
    formatter.AppendString("*** Query id: ");
244
0
    formatter.AppendUint64(query_id_hi, 16);
245
0
    formatter.AppendString("-");
246
0
    formatter.AppendUint64(query_id_lo, 16);
247
0
    formatter.AppendString(" ***\n");
248
0
    formatter.AppendString("*** tablet id: ");
249
0
    formatter.AppendUint64(tablet_id, 10);
250
0
    formatter.AppendString(" ***\n");
251
0
    formatter.AppendString("*** Aborted at ");
252
0
    formatter.AppendUint64(static_cast<uint64_t>(time_in_sec), 10);
253
0
    formatter.AppendString(" (unix time)");
254
0
    formatter.AppendString(" try \"date -d @");
255
0
    formatter.AppendUint64(static_cast<uint64_t>(time_in_sec), 10);
256
0
    formatter.AppendString("\" if you are using GNU date ***\n");
257
0
    formatter.AppendString("*** Current BE git commitID: ");
258
0
    formatter.AppendString(version::doris_build_short_hash());
259
0
    formatter.AppendString(" ***\n");
260
0
    g_failure_writer(buf, formatter.num_bytes_written());
261
0
}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_112DumpTimeInfoEv
262
263
// Dumps information about the signal to STDERR.
264
0
void DumpSignalInfo(int signal_number, siginfo_t* siginfo) {
265
0
    // Get the signal name.
266
0
    const char* signal_name = nullptr;
267
0
    for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kFailureSignals); ++i) {
268
0
        if (signal_number == kFailureSignals[i].number) {
269
0
            signal_name = kFailureSignals[i].name;
270
0
        }
271
0
    }
272
0
273
0
    char buf[256]; // Big enough for signal info.
274
0
    MinimalFormatter formatter(buf, sizeof(buf));
275
0
276
0
    formatter.AppendString("*** ");
277
0
    if (signal_name) {
278
0
        formatter.AppendString(signal_name);
279
0
    } else {
280
0
        // Use the signal number if the name is unknown.  The signal name
281
0
        // should be known, but just in case.
282
0
        formatter.AppendString("Signal ");
283
0
        formatter.AppendUint64(static_cast<uint64_t>(signal_number), 10);
284
0
    }
285
0
    formatter.AppendString(" ");
286
0
    // Detail reason explain
287
0
    auto reason = signal_reason(signal_number, siginfo->si_code);
288
0
289
0
    // If we can't find a reason code make a best effort to print the (int) code.
290
0
    if (reason != nullptr) {
291
0
        formatter.AppendString(reason);
292
0
    } else {
293
0
        formatter.AppendString("unknown detail explain");
294
0
    }
295
0
    formatter.AppendString(" (@0x");
296
0
    formatter.AppendUint64(reinterpret_cast<uintptr_t>(siginfo->si_addr), 16);
297
0
    formatter.AppendString(")");
298
0
    formatter.AppendString(" received by PID ");
299
0
    formatter.AppendUint64(static_cast<uint64_t>(getpid()), 10);
300
0
    formatter.AppendString(" (TID ");
301
0
    uint64_t tid;
302
0
#ifdef __APPLE__
303
0
    pthread_threadid_np(nullptr, &tid);
304
0
#else
305
0
    tid = syscall(SYS_gettid);
306
0
#endif
307
0
    formatter.AppendUint64(tid, 10);
308
0
    formatter.AppendString(" OR 0x");
309
0
    // We assume pthread_t is an integral number or a pointer, rather
310
0
    // than a complex struct.  In some environments, pthread_self()
311
0
    // returns an uint64 but in some other environments pthread_self()
312
0
    // returns a pointer.
313
0
    pthread_t id = pthread_self();
314
0
    formatter.AppendUint64(reinterpret_cast<uint64_t>(reinterpret_cast<const char*>(id)), 16);
315
0
    formatter.AppendString(") ");
316
0
    // Only linux has the PID of the signal sender in si_pid.
317
0
    formatter.AppendString("from PID ");
318
0
    formatter.AppendUint64(static_cast<uint64_t>(siginfo->si_pid), 10);
319
0
    formatter.AppendString("; ");
320
0
    formatter.AppendString("stack trace: ***\n");
321
0
    g_failure_writer(buf, formatter.num_bytes_written());
322
0
}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_114DumpSignalInfoEiP9siginfo_t
323
324
// Invoke the default signal handler.
325
0
void InvokeDefaultSignalHandler(int signal_number) {
326
0
    struct sigaction sig_action;
327
0
    memset(&sig_action, 0, sizeof(sig_action));
328
0
    sigemptyset(&sig_action.sa_mask);
329
0
    sig_action.sa_handler = SIG_DFL;
330
0
    sigaction(signal_number, &sig_action, nullptr);
331
0
    kill(getpid(), signal_number);
332
0
}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_126InvokeDefaultSignalHandlerEi
333
334
// This variable is used for protecting FailureSignalHandler() from
335
// dumping stuff while another thread is doing it.  Our policy is to let
336
// the first thread dump stuff and let other threads wait.
337
// See also comments in FailureSignalHandler().
338
static pthread_t* g_entered_thread_id_pointer = nullptr;
339
340
// Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't
341
// defined, we try the CPU specific logics (we only support x86 and
342
// x86_64 for now) first, then use a naive implementation, which has a
343
// race condition.
344
template <typename T>
345
0
T sync_val_compare_and_swap(T* ptr, T oldval, T newval) {
346
0
#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP)
347
0
    return __sync_val_compare_and_swap(ptr, oldval, newval);
348
0
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
349
0
    T ret;
350
0
    __asm__ __volatile__("lock; cmpxchg %1, (%2);"
351
0
                         : "=a"(ret)
352
0
                         // GCC may produces %sil or %dil for
353
0
                         // constraint "r", but some of apple's gas
354
0
                         // dosn't know the 8 bit registers.
355
0
                         // We use "q" to avoid these registers.
356
0
                         : "q"(newval), "q"(ptr), "a"(oldval)
357
0
                         : "memory", "cc");
358
0
    return ret;
359
0
#else
360
0
    T ret = *ptr;
361
0
    if (ret == oldval) {
362
0
        *ptr = newval;
363
0
    }
364
0
    return ret;
365
0
#endif
366
0
}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_125sync_val_compare_and_swapIPmEET_PS4_S4_S4_
367
368
// Dumps signal and stack frame information, and invokes the default
369
// signal handler once our job is done.
370
0
void FailureSignalHandler(int signal_number, siginfo_t* signal_info, void* ucontext) {
371
0
    // First check if we've already entered the function.  We use an atomic
372
0
    // compare and swap operation for platforms that support it.  For other
373
0
    // platforms, we use a naive method that could lead to a subtle race.
374
0
375
0
    // We assume pthread_self() is async signal safe, though it's not
376
0
    // officially guaranteed.
377
0
    pthread_t my_thread_id = pthread_self();
378
0
    // NOTE: We could simply use pthread_t rather than pthread_t* for this,
379
0
    // if pthread_self() is guaranteed to return non-zero value for thread
380
0
    // ids, but there is no such guarantee.  We need to distinguish if the
381
0
    // old value (value returned from __sync_val_compare_and_swap) is
382
0
    // different from the original value (in this case NULL).
383
0
    pthread_t* old_thread_id_pointer = sync_val_compare_and_swap(
384
0
            &g_entered_thread_id_pointer, static_cast<pthread_t*>(nullptr), &my_thread_id);
385
0
    if (old_thread_id_pointer != nullptr) {
386
0
        // We've already entered the signal handler.  What should we do?
387
0
        if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) {
388
0
            // It looks the current thread is reentering the signal handler.
389
0
            // Something must be going wrong (maybe we are reentering by another
390
0
            // type of signal?).  Kill ourself by the default signal handler.
391
0
            InvokeDefaultSignalHandler(signal_number);
392
0
        }
393
0
        // Another thread is dumping stuff.  Let's wait until that thread
394
0
        // finishes the job and kills the process.
395
0
        while (true) {
396
0
            sleep(1);
397
0
        }
398
0
    }
399
0
    // This is the first time we enter the signal handler.  We are going to
400
0
    // do some interesting stuff from here.
401
0
    // TODO(satorux): We might want to set timeout here using alarm(), but
402
0
    // mixing alarm() and sleep() can be a bad idea.
403
0
404
0
    // First dump time info.
405
0
    DumpTimeInfo();
406
0
    DumpSignalInfo(signal_number, signal_info);
407
0
408
0
    // *** TRANSITION ***
409
0
    //
410
0
    // BEFORE this point, all code must be async-termination-safe!
411
0
    // (See WARNING above.)
412
0
    //
413
0
    // AFTER this point, we do unsafe things, like using LOG()!
414
0
    // The process could be terminated or hung at any time.  We try to
415
0
    // do more useful things first and riskier things later.
416
0
417
0
    // Use boost stacktrace to print more detail info
418
0
    std::cout << boost::stacktrace::stacktrace() << std::endl;
419
0
420
0
    // Flush the logs before we do anything in case 'anything'
421
0
    // causes problems.
422
0
    google::FlushLogFilesUnsafe(0);
423
0
424
0
    // Kill ourself by the default signal handler.
425
0
    InvokeDefaultSignalHandler(signal_number);
426
0
}
Unexecuted instantiation: rowid_fetcher.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
Unexecuted instantiation: vtablet_writer.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
Unexecuted instantiation: vtablet_writer_v2.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
Unexecuted instantiation: schema_change.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
Unexecuted instantiation: tablet.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
Unexecuted instantiation: thread_mem_tracker_mgr.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
Unexecuted instantiation: thread_context.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
Unexecuted instantiation: internal_service.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
Unexecuted instantiation: fold_constant_executor.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
Unexecuted instantiation: load_stream.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
Unexecuted instantiation: memtable_flush_executor.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
Unexecuted instantiation: cloud_storage_engine.cpp:_ZN5doris6signal12_GLOBAL__N_120FailureSignalHandlerEiP9siginfo_tPv
427
428
} // namespace
429
430
76
inline void set_signal_task_id(PUniqueId tid) {
431
76
    query_id_hi = tid.hi();
432
76
    query_id_lo = tid.lo();
433
76
}
434
435
1.10k
inline void set_signal_task_id(TUniqueId tid) {
436
1.10k
    query_id_hi = tid.hi;
437
1.10k
    query_id_lo = tid.lo;
438
1.10k
}
439
440
// this struct is used to set signal task id in the constructor and reset it in the destructor
441
// thread pool will reuse pthread, so we need to clean thread local data
442
struct SignalTaskIdKeeper {
443
    template <typename T>
444
0
    SignalTaskIdKeeper(const T& id) {
445
0
        set_signal_task_id(id);
446
0
    }
Unexecuted instantiation: _ZN5doris6signal18SignalTaskIdKeeperC2INS_9PUniqueIdEEERKT_
Unexecuted instantiation: _ZN5doris6signal18SignalTaskIdKeeperC2INS_9TUniqueIdEEERKT_
447
0
    ~SignalTaskIdKeeper() { set_signal_task_id(PUniqueId {}); }
448
};
449
450
74
inline void set_signal_is_nereids(bool is_nereids_arg) {
451
74
    is_nereids = is_nereids_arg;
452
74
}
453
454
0
inline void InstallFailureSignalHandler() {
455
0
    // Build the sigaction struct.
456
0
    struct sigaction sig_action;
457
0
    memset(&sig_action, 0, sizeof(sig_action));
458
0
    sigemptyset(&sig_action.sa_mask);
459
0
    sig_action.sa_flags |= SA_SIGINFO;
460
0
    sig_action.sa_sigaction = &FailureSignalHandler;
461
0
462
0
    for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kFailureSignals); ++i) {
463
0
        CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, nullptr));
464
0
    }
465
0
    kFailureSignalHandlerInstalled = true;
466
0
}
467
468
} // namespace doris::signal