From e9f7a3ee585aa867d054fb98ade4b30108183c8c Mon Sep 17 00:00:00 2001 From: Pxl <952130278@qq.com> Date: Tue, 14 Jun 2022 15:32:58 +0800 Subject: [PATCH] [bugfix]fix segmentation fault at unalign address cast to int128 (#10094) --- be/src/olap/types.h | 42 +++++++++++++++++++------------- be/src/util/types.h | 13 +++++++--- be/test/olap/row_cursor_test.cpp | 11 ++++++--- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/be/src/olap/types.h b/be/src/olap/types.h index 88ad282e2fad26..4841ae388ff0e9 100644 --- a/be/src/olap/types.h +++ b/be/src/olap/types.h @@ -487,18 +487,27 @@ template struct BaseFieldtypeTraits : public CppTypeTraits { using CppType = typename CppTypeTraits::CppType; + static inline CppType get_cpp_type_value(const void* address) { + if constexpr (field_type == OLAP_FIELD_TYPE_LARGEINT) { + return get_int128_from_unalign(address); + } + return *reinterpret_cast(address); + } + + static inline void set_cpp_type_value(void* address, const CppType& value) { + memcpy(address, &value, sizeof(CppType)); + } + static inline bool equal(const void* left, const void* right) { - CppType l_value = *reinterpret_cast(left); - CppType r_value = *reinterpret_cast(right); - return l_value == r_value; + return get_cpp_type_value(left) == get_cpp_type_value(right); } static inline int cmp(const void* left, const void* right) { - CppType left_int = *reinterpret_cast(left); - CppType right_int = *reinterpret_cast(right); - if (left_int < right_int) { + CppType left_value = get_cpp_type_value(left); + CppType right_value = get_cpp_type_value(right); + if (left_value < right_value) { return -1; - } else if (left_int > right_int) { + } else if (left_value > right_value) { return 1; } else { return 0; @@ -506,19 +515,19 @@ struct BaseFieldtypeTraits : public CppTypeTraits { } static inline void shallow_copy(void* dest, const void* src) { - *reinterpret_cast(dest) = *reinterpret_cast(src); + memcpy(dest, src, sizeof(CppType)); } static inline void deep_copy(void* dest, const void* src, MemPool* mem_pool) { - *reinterpret_cast(dest) = *reinterpret_cast(src); + memcpy(dest, src, sizeof(CppType)); } static inline void copy_object(void* dest, const void* src, MemPool* mem_pool) { - *reinterpret_cast(dest) = *reinterpret_cast(src); + memcpy(dest, src, sizeof(CppType)); } static inline void direct_copy(void* dest, const void* src) { - *reinterpret_cast(dest) = *reinterpret_cast(src); + memcpy(dest, src, sizeof(CppType)); } static inline void direct_copy_may_cut(void* dest, const void* src) { direct_copy(dest, src); } @@ -529,11 +538,11 @@ struct BaseFieldtypeTraits : public CppTypeTraits { } static inline void set_to_max(void* buf) { - *reinterpret_cast(buf) = std::numeric_limits::max(); + set_cpp_type_value(buf, std::numeric_limits::max()); } static inline void set_to_min(void* buf) { - *reinterpret_cast(buf) = std::numeric_limits::min(); + set_cpp_type_value(buf, std::numeric_limits::min()); } static inline uint32_t hash_code(const void* data, uint32_t seed) { @@ -541,7 +550,7 @@ struct BaseFieldtypeTraits : public CppTypeTraits { } static std::string to_string(const void* src) { - return std::to_string(*reinterpret_cast(src)); + return std::to_string(get_cpp_type_value(src)); } static OLAPStatus from_string(void* buf, const std::string& scan_key) { @@ -549,7 +558,7 @@ struct BaseFieldtypeTraits : public CppTypeTraits { if (scan_key.length() > 0) { value = static_cast(strtol(scan_key.c_str(), nullptr, 10)); } - *reinterpret_cast(buf) = value; + set_cpp_type_value(buf, value); return OLAP_SUCCESS; } }; @@ -1086,8 +1095,7 @@ struct FieldTypeTraits : public FieldTypeTraitsto_string(src); - if (result.size() > variable_len) - return OLAP_ERR_INPUT_PARAMETER_ERROR; + if (result.size() > variable_len) return OLAP_ERR_INPUT_PARAMETER_ERROR; auto slice = reinterpret_cast(dest); slice->data = reinterpret_cast(mem_pool->allocate(result.size())); memcpy(slice->data, result.c_str(), result.size()); diff --git a/be/src/util/types.h b/be/src/util/types.h index 7d45141badc6ae..b622b91aadb61a 100644 --- a/be/src/util/types.h +++ b/be/src/util/types.h @@ -17,6 +17,8 @@ #pragma once +#include "olap/olap_common.h" + namespace doris { // Because __int128 in memory is not aligned, but GCC7 will generate SSE instruction @@ -32,13 +34,16 @@ struct PackedInt128 { value = value_; return *this; } - PackedInt128& operator=(const PackedInt128& rhs) { - value = rhs.value; - return *this; - } + PackedInt128& operator=(const PackedInt128& rhs) = default; #pragma GCC diagnostic pop __int128 value; } __attribute__((packed)); +// unalign address directly casted to int128 will core dump +inline int128_t get_int128_from_unalign(const void* address) { + int128_t value = 0; + memcpy(&value, address, sizeof(int128_t)); + return value; +} } // namespace doris diff --git a/be/test/olap/row_cursor_test.cpp b/be/test/olap/row_cursor_test.cpp index 9dd2447e8ff26e..02be4543a35c3d 100644 --- a/be/test/olap/row_cursor_test.cpp +++ b/be/test/olap/row_cursor_test.cpp @@ -26,6 +26,7 @@ #include "runtime/mem_pool.h" #include "runtime/mem_tracker.h" #include "util/logging.h" +#include "util/types.h" namespace doris { @@ -498,9 +499,8 @@ TEST_F(TestRowCursor, AggregateWithoutNull) { agg_update_row(&row, right, nullptr); - int128_t agg_value = 0; - memcpy(&agg_value, row.cell_ptr(2), 16); - ASSERT_TRUE(agg_value == ((int128_t)(1) << 101)); + int128_t agg_value = get_int128_from_unalign(row.cell_ptr(2)); + EXPECT_TRUE(agg_value == ((int128_t)(1) << 101)); double agg_double = *reinterpret_cast(row.cell_ptr(3)); ASSERT_TRUE(agg_double == r_double); @@ -559,9 +559,14 @@ TEST_F(TestRowCursor, AggregateWithNull) { agg_update_row(&row, right, nullptr); +<<<<<<< HEAD int128_t agg_value = 0; memcpy(&agg_value, row.cell_ptr(2), 16); ASSERT_TRUE(agg_value == ((int128_t)(1) << 101)); +======= + int128_t agg_value = get_int128_from_unalign(row.cell_ptr(2)); + EXPECT_TRUE(agg_value == ((int128_t)(1) << 101)); +>>>>>>> 5d624dfe6 ([bugfix]fix segmentation fault at unalign address cast to int128 (#10094)) bool is_null_double = left.is_null(3); ASSERT_TRUE(is_null_double);