This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-1.1-lts
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-1.1-lts by this push:
     new e9f7a3ee58 [bugfix]fix segmentation fault at unalign address cast to 
int128 (#10094)
e9f7a3ee58 is described below

commit e9f7a3ee585aa867d054fb98ade4b30108183c8c
Author: Pxl <952130...@qq.com>
AuthorDate: Tue Jun 14 15:32:58 2022 +0800

    [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 88ad282e2f..4841ae388f 100644
--- a/be/src/olap/types.h
+++ b/be/src/olap/types.h
@@ -487,18 +487,27 @@ template <FieldType field_type>
 struct BaseFieldtypeTraits : public CppTypeTraits<field_type> {
     using CppType = typename CppTypeTraits<field_type>::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<const CppType*>(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<const CppType*>(left);
-        CppType r_value = *reinterpret_cast<const CppType*>(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<const CppType*>(left);
-        CppType right_int = *reinterpret_cast<const CppType*>(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<field_type> {
     }
 
     static inline void shallow_copy(void* dest, const void* src) {
-        *reinterpret_cast<CppType*>(dest) = *reinterpret_cast<const 
CppType*>(src);
+        memcpy(dest, src, sizeof(CppType));
     }
 
     static inline void deep_copy(void* dest, const void* src, MemPool* 
mem_pool) {
-        *reinterpret_cast<CppType*>(dest) = *reinterpret_cast<const 
CppType*>(src);
+        memcpy(dest, src, sizeof(CppType));
     }
 
     static inline void copy_object(void* dest, const void* src, MemPool* 
mem_pool) {
-        *reinterpret_cast<CppType*>(dest) = *reinterpret_cast<const 
CppType*>(src);
+        memcpy(dest, src, sizeof(CppType));
     }
 
     static inline void direct_copy(void* dest, const void* src) {
-        *reinterpret_cast<CppType*>(dest) = *reinterpret_cast<const 
CppType*>(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<field_type> {
     }
 
     static inline void set_to_max(void* buf) {
-        *reinterpret_cast<CppType*>(buf) = std::numeric_limits<CppType>::max();
+        set_cpp_type_value(buf, std::numeric_limits<CppType>::max());
     }
 
     static inline void set_to_min(void* buf) {
-        *reinterpret_cast<CppType*>(buf) = std::numeric_limits<CppType>::min();
+        set_cpp_type_value(buf, std::numeric_limits<CppType>::min());
     }
 
     static inline uint32_t hash_code(const void* data, uint32_t seed) {
@@ -541,7 +550,7 @@ struct BaseFieldtypeTraits : public 
CppTypeTraits<field_type> {
     }
 
     static std::string to_string(const void* src) {
-        return std::to_string(*reinterpret_cast<const CppType*>(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<field_type> {
         if (scan_key.length() > 0) {
             value = static_cast<CppType>(strtol(scan_key.c_str(), nullptr, 
10));
         }
-        *reinterpret_cast<CppType*>(buf) = value;
+        set_cpp_type_value(buf, value);
         return OLAP_SUCCESS;
     }
 };
@@ -1086,8 +1095,7 @@ struct FieldTypeTraits<OLAP_FIELD_TYPE_VARCHAR> : public 
FieldTypeTraits<OLAP_FI
         case OLAP_FIELD_TYPE_DOUBLE:
         case OLAP_FIELD_TYPE_DECIMAL: {
             auto result = src_type->to_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<Slice*>(dest);
             slice->data = 
reinterpret_cast<char*>(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 7d45141bad..b622b91aad 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 9dd2447e8f..02be4543a3 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<double*>(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);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to