Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions be/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,10 @@ if (COMPILER_CLANG)
-Wunused-macros
-Wconversion
-Wthread-safety)
# Clang >= 17 flags namespace-scope shadowing (e.g. enum constants vs
# protobuf-generated enums) that older toolchains accepted; keep the
# warnings visible but non-fatal so newer compilers can build.
add_compile_options(-Wno-error=shadow)
add_compile_options(-Wno-gnu-statement-expression
-Wno-implicit-float-conversion
-Wno-sign-conversion
Expand Down Expand Up @@ -941,6 +945,9 @@ if (MAKE_TEST)
add_compile_options(
-Wno-implicit-int-conversion
-Wno-shorten-64-to-32
# Newer libstdc++ (>= 12) marks std::get_temporary_buffer deprecated;
# test code using std::stable_sort trips over it under -Werror.
-Wno-deprecated-declarations
)
endif()
endif ()
Expand Down
42 changes: 15 additions & 27 deletions be/src/common/signal_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,40 +337,28 @@ void InvokeDefaultSignalHandler(int signal_number) {
// See also comments in FailureSignalHandler().
static pthread_t* g_entered_thread_id_pointer = nullptr;

// Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't
// defined, we try the CPU specific logics (we only support x86 and
// x86_64 for now) first, then use a naive implementation, which has a
// race condition.
// Wrapper of the compiler's atomic compare-and-swap builtin.
// __atomic_compare_exchange_n is available on every architecture supported
// by GCC/Clang (x86, aarch64, ...). The previous fallback chain
// (HAVE___SYNC_VAL_COMPARE_AND_SWAP, which nothing in this CMake-based
// project ever defines, then x86-only inline asm) ended in a naive
// non-atomic read-check-write on aarch64. That races when several threads
// crash at the same time on many-core ARM machines: multiple threads win
// the FailureSignalHandler election below and dump concurrently.
template <typename T>
T sync_val_compare_and_swap(T* ptr, T oldval, T newval) {
#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP)
return __sync_val_compare_and_swap(ptr, oldval, newval);
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
T ret;
__asm__ __volatile__("lock; cmpxchg %1, (%2);"
: "=a"(ret)
// GCC may produces %sil or %dil for
// constraint "r", but some of apple's gas
// dosn't know the 8 bit registers.
// We use "q" to avoid these registers.
: "q"(newval), "q"(ptr), "a"(oldval)
: "memory", "cc");
return ret;
#else
T ret = *ptr;
if (ret == oldval) {
*ptr = newval;
}
return ret;
#endif
T expected = oldval;
__atomic_compare_exchange_n(ptr, &expected, newval, false, __ATOMIC_SEQ_CST,
__ATOMIC_SEQ_CST);
return expected;
}

// Dumps signal and stack frame information, and invokes the default
// signal handler once our job is done.
void FailureSignalHandler(int signal_number, siginfo_t* signal_info, void* ucontext) {
// First check if we've already entered the function. We use an atomic
// compare and swap operation for platforms that support it. For other
// platforms, we use a naive method that could lead to a subtle race.
// First check if we've already entered the function. The election uses
// the compiler's atomic compare-and-swap builtin, which is available on
// every supported platform (x86_64 and aarch64 alike).

// We assume pthread_self() is async signal safe, though it's not
// officially guaranteed.
Expand Down
5 changes: 4 additions & 1 deletion be/src/core/column/columns_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ size_t count_bytes_in_filter(const IColumn::Filter& filt) {
const Int8* pos = reinterpret_cast<const Int8*>(filt.data());
const Int8* end = pos + filt.size();

#if defined(__SSE2__) || defined(__aarch64__) && defined(__POPCNT__)
// NOTE: the old guard already parsed as `__SSE2__ || (__aarch64__ && __POPCNT__)`
// (`&&` binds tighter), and ARM toolchains never define __POPCNT__, so this SIMD
// block was compiled out on aarch64; dropping the __POPCNT__ gate enables it.
#if defined(__SSE2__) || defined(__aarch64__)
const __m128i zero16 = _mm_setzero_si128();
const Int8* end64 = pos + filt.size() / 64 * 64;

Expand Down
11 changes: 11 additions & 0 deletions be/src/core/value/bitmap_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -2971,12 +2971,23 @@ class BitmapValue {
_set.clear();
}

// NOTE: the enumerators (EMPTY/SINGLE/BITMAP/SET) collide with protobuf
// enum values exported at namespace scope by olap_file.pb.h (e.g.
// doris::BITMAP); clang >= 17 -Wshadow flags the shadowing as an error
// under -Werror, so suppress it just for this declaration.
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"
#endif
enum BitmapDataType {
EMPTY = 0,
SINGLE = 1, // single element
BITMAP = 2, // more than one elements
SET = 3 // elements count less or equal than 32
};
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
uint64_t _sv = 0; // store the single value when _type == SINGLE
// !FIXME: We should rethink the logic about _bitmap and _is_shared
mutable std::shared_ptr<detail::Roaring64Map> _bitmap; // used when _type == BITMAP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,10 @@ Status BucketedAggLocalState::_output_bucket(RuntimeState* state, Block* block,
Status BucketedAggLocalState::_merge_and_output_null_keys(RuntimeState* state, Block* block) {
auto& shared_state = *_shared_state;
size_t key_size = shared_state.probe_expr_ctxs.size();
int merge_target = shared_state.merge_target_instance.load(std::memory_order_relaxed);
// acquire: the loaded index is used to dereference per-instance data
// published by other threads; relaxed would rely on data-dependency
// ordering, which the C++ memory model does not guarantee (aarch64).
int merge_target = shared_state.merge_target_instance.load(std::memory_order_acquire);

// Merge null keys from all 256 buckets (in merge target) into bucket 0.
// After per-bucket merge, each bucket in merge target may have its own null key data.
Expand Down
3 changes: 1 addition & 2 deletions be/src/exprs/function/function_string_misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <format>
#include <iomanip>
#include <memory>
#include <random>
Expand Down Expand Up @@ -229,7 +228,7 @@ class FunctionAutoPartitionName : public IFunction {
// check the name of length
int len = res_p.size();
if (len > 50) {
res_p = std::format("{}_{:08x}", res_p.substr(0, 50), to_hash_code(res_p));
res_p = fmt::format("{}_{:08x}", res_p.substr(0, 50), to_hash_code(res_p));
len = res_p.size();
}
curr_len += len;
Expand Down
3 changes: 2 additions & 1 deletion be/src/format/parquet/parquet_column_convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <libdivide.h>

#include <chrono>
#include <cmath> // std::pow (used by the half-float decoding path)
#include <limits>

#include "common/cast_set.h"
Expand Down Expand Up @@ -593,7 +594,7 @@ class Float16PhysicalConverter : public PhysicalToLogicalConverter {
// half subnormal:
// value = (-1)^sign * (mant / 2^10) * 2^(1 - bias)
// half bias = 15 → exponent = 1 - 15 = -14
float f = (static_cast<float>(mant) / 1024.0F) * std::powf(2.0F, -14.0F);
float f = (static_cast<float>(mant) / 1024.0F) * std::pow(2.0F, -14.0F);
return sign ? -f : f;
}
} else if (exp == 0x1F) {
Expand Down
7 changes: 5 additions & 2 deletions be/src/glibc-compatibility/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ if (GLIBC_COMPATIBILITY)
# libcalls. Workaround: Use object file so that linker will always take a
# look at its symbol table.
list(REMOVE_ITEM glibc_compatibility_sources musl/getrandom.c)
# NOTE: the OBJECT lib must always provide the resolv_shim symbol where it
# exists (resolv_shim.c is a no-op on glibc < 2.34); keep it out of the archive.
list(REMOVE_ITEM glibc_compatibility_sources resolv_shim.c)
# NOTE(amos): sanitizers might generate memcpy references that are too late to
# refer. Let's also extract memcpy definitions explicitly to avoid UNDEF GLIBC 2.14.
#
Expand All @@ -65,9 +68,9 @@ if (GLIBC_COMPATIBILITY)
# before ASAN shadow memory is initialized, causing SIGSEGV. Skip custom memcpy in
# this case and fall back to glibc's memcpy.
if (ARCH_ARM AND (CMAKE_BUILD_TYPE STREQUAL "ASAN_UT" OR CMAKE_BUILD_TYPE STREQUAL "ASAN"))
add_library(glibc-compatibility-explicit OBJECT musl/getrandom.c)
add_library(glibc-compatibility-explicit OBJECT musl/getrandom.c resolv_shim.c)
else()
add_library(glibc-compatibility-explicit OBJECT musl/getrandom.c ${MEMCPY_SOURCE})
add_library(glibc-compatibility-explicit OBJECT musl/getrandom.c resolv_shim.c ${MEMCPY_SOURCE})
endif()
target_compile_options(glibc-compatibility-explicit PRIVATE -fPIC)
add_library(glibc-compatibility STATIC ${glibc_compatibility_sources})
Expand Down
48 changes: 48 additions & 0 deletions be/src/glibc-compatibility/resolv_shim.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

// glibc >= 2.34 demoted the double-underscore resolver entry points
// (__res_nsearch & friends) to non-default compat versions, so newly linked
// binaries cannot bind them anymore. The prebuilt thirdparty krb5 archive
// (dnsglue.o) still references __res_nsearch, which breaks the doris_be link
// on Ubuntu 22.04 (glibc 2.35). Provide a thin forwarder to the public
// res_nsearch entry point, which is the identical implementation (same
// symbol address in libc).
//
// The shim must only exist where it is needed: on glibc < 2.34,
// __res_nsearch is still a default-versioned libc symbol, and <resolv.h>
// there #defines res_nsearch as __res_nsearch, which would fold the
// forwarder below into infinite self-recursion (clang -Winfinite-recursion
// errors out under -Werror, e.g. on the AlmaLinux 8 / glibc 2.28 CI image).

#include <resolv.h>
#include <sys/types.h>

#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 34)

int __res_nsearch(res_state statp, const char* dname, int class_, int type,
unsigned char* answer, int anslen) {
return res_nsearch(statp, dname, class_, type, answer, anslen);
}

#else

// Keep the translation unit non-empty (-Wpedantic forbids an empty one);
// no shim is required on glibc < 2.34.
typedef int doris_resolv_shim_unused_t;

#endif
28 changes: 10 additions & 18 deletions be/src/io/cache/block_file_cache_profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,23 @@ namespace doris::io {

std::shared_ptr<AtomicStatistics> FileCacheMetrics::report() {
std::shared_ptr<AtomicStatistics> output_stats = std::make_shared<AtomicStatistics>();
std::lock_guard lock(_mtx);
output_stats->num_io_bytes_read_from_cache += _statistics->num_io_bytes_read_from_cache;
output_stats->num_io_bytes_read_from_remote += _statistics->num_io_bytes_read_from_remote;
output_stats->num_io_bytes_read_from_peer += _statistics->num_io_bytes_read_from_peer;
output_stats->num_io_bytes_read_from_cache += _statistics.num_io_bytes_read_from_cache;
output_stats->num_io_bytes_read_from_remote += _statistics.num_io_bytes_read_from_remote;
output_stats->num_io_bytes_read_from_peer += _statistics.num_io_bytes_read_from_peer;
output_stats->inverted_index_bytes_read_from_remote +=
_statistics->inverted_index_bytes_read_from_remote;
_statistics.inverted_index_bytes_read_from_remote;
output_stats->segment_footer_index_bytes_read_from_remote +=
_statistics->segment_footer_index_bytes_read_from_remote;
_statistics.segment_footer_index_bytes_read_from_remote;
return output_stats;
}

void FileCacheMetrics::update(FileCacheStatistics* input_stats) {
if (_statistics == nullptr) {
std::lock_guard<std::mutex> lock(_mtx);
if (_statistics == nullptr) {
_statistics = std::make_shared<AtomicStatistics>();
register_entity();
}
}
_statistics->num_io_bytes_read_from_cache += input_stats->bytes_read_from_local;
_statistics->num_io_bytes_read_from_remote += input_stats->bytes_read_from_remote;
_statistics->num_io_bytes_read_from_peer += input_stats->bytes_read_from_peer;
_statistics->inverted_index_bytes_read_from_remote +=
_statistics.num_io_bytes_read_from_cache += input_stats->bytes_read_from_local;
_statistics.num_io_bytes_read_from_remote += input_stats->bytes_read_from_remote;
_statistics.num_io_bytes_read_from_peer += input_stats->bytes_read_from_peer;
_statistics.inverted_index_bytes_read_from_remote +=
input_stats->inverted_index_bytes_read_from_remote;
_statistics->segment_footer_index_bytes_read_from_remote +=
_statistics.segment_footer_index_bytes_read_from_remote +=
input_stats->segment_footer_index_bytes_read_from_remote;
}

Expand Down
19 changes: 10 additions & 9 deletions be/src/io/cache/block_file_cache_profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <atomic>
#include <cstdint>
#include <memory>
#include <mutex>
#include <unordered_map>

#include "common/metrics/doris_metrics.h"
Expand All @@ -49,21 +48,23 @@ class FileCacheMetrics {
return s_metrics;
}

FileCacheMetrics() {
FileCacheStatistics stats;
update(&stats);
}
// The counters are value members, so they are fully constructed before this
// body runs; registering here (instead of lazily on first update) is safe
// even if a metrics callback fires right after registration, since report()
// only reads the counters. There is no publication race: instance() is a
// magic static and returns only after construction completes.
FileCacheMetrics() { register_entity(); }

void update(FileCacheStatistics* stats);
std::shared_ptr<AtomicStatistics> report();
// Public for tests: pushes the current counters into the DorisMetrics
// gauges without waiting for the periodic metrics hook.
void update_metrics_callback();

private:
void register_entity();
void update_metrics_callback();

std::mutex _mtx;
// use shared_ptr for concurrent
std::shared_ptr<AtomicStatistics> _statistics;
AtomicStatistics _statistics;
};

FileCacheStatistics diff_file_cache_statistics(const FileCacheStatistics& current,
Expand Down
10 changes: 8 additions & 2 deletions be/src/service/doris_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,15 @@ void check_required_instructions_impl(volatile InstructionFail& fail) {
__asm__ volatile("vpabsw %%zmm0, %%zmm0" : : : "zmm0");
#endif

#if defined(__ARM_NEON__)
// GCC aarch64 defines __ARM_NEON, Clang additionally defines __ARM_NEON__ on
// some targets (e.g. Apple). The 32-bit "vadd.i32 q8,..." syntax is AArch32
// only and does not assemble on AArch64, which needs "add v8.4s,...". Pick
// the spelling per architecture so every ARM toolchain passes this check.
#if defined(__ARM_NEON__) || defined(__ARM_NEON)
fail = InstructionFail::ARM_NEON;
#ifndef __APPLE__
#if defined(__aarch64__)
__asm__ volatile("add v8.4s, v8.4s, v8.4s" : : : "v8");
#elif !defined(__APPLE__)
__asm__ volatile("vadd.i32 q8, q8, q8" : : : "q8");
#endif
#endif
Expand Down
4 changes: 3 additions & 1 deletion be/src/service/http/action/be_thread_stack_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ pid_t get_current_tid() {
return static_cast<pid_t>(syscall(SYS_gettid));
}

void append_frame(SignalContextCapture* capture, uintptr_t pc) {
// Only called from the x86_64 libunwind path below; on aarch64 it is
// intentionally unused, so keep -Wunused-function quiet.
[[maybe_unused]] void append_frame(SignalContextCapture* capture, uintptr_t pc) {
if (pc == 0 || capture->size >= capture->frame_pointers.size()) {
return;
}
Expand Down
13 changes: 8 additions & 5 deletions be/src/storage/index/bloom_filter/ngram_bloom_filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <gen_cpp/segment_v2.pb.h>
#include <glog/logging.h>

#include <cstring>

#include "absl/strings/substitute.h"
#include "util/hash/city.h"

Expand All @@ -40,11 +42,12 @@ Status NGramBloomFilter::init(const char* buf, size_t size, HashStrategyPB strat
return Status::InvalidArgument(absl::Substitute("invalid strategy:$0", strategy));
}
words = (_size + sizeof(UnderType) - 1) / sizeof(UnderType);
filter.reserve(words);
const auto* from = reinterpret_cast<const UnderType*>(buf);
for (size_t i = 0; i < words; ++i) {
filter[i] = from[i];
}
filter.assign(words, 0);
// buf points into an arbitrarily-offset page buffer; a plain
// reinterpret_cast<const uint64_t*> read would be misaligned UB.
// Copy exactly size bytes: the tail bytes of the last word must stay
// zero so contains() bit comparisons match query-side filters.
memcpy(filter.data(), buf, size);

return Status::OK();
}
Expand Down
4 changes: 4 additions & 0 deletions be/src/storage/index/snii/encoding/crc32c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
#define SNII_CRC32C_X86 1
#include <cpuid.h> // __get_cpuid, bit_SSE4_2
#include <nmmintrin.h> // _mm_crc32_u8/u32/u64 (SSE4.2)
#else
// Keep the #if SNII_CRC32C_X86 uses below -Wundef-clean on non-x86 (aarch64
// UT builds compile this BE_TEST-only TU with -Werror).
#define SNII_CRC32C_X86 0
#endif

namespace doris::snii {
Expand Down
Loading