Skip to content

Commit

Permalink
[bugfix]fix segmentation fault at unalign address cast to int128 (#10094
Browse files Browse the repository at this point in the history
)
  • Loading branch information
BiteTheDDDDt authored and Doris-Extras committed Sep 16, 2022
1 parent e1971e7 commit e9f7a3e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 24 deletions.
42 changes: 25 additions & 17 deletions be/src/olap/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -487,38 +487,47 @@ 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;
}
}

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); }
Expand All @@ -529,27 +538,27 @@ 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) {
return HashUtil::hash(data, sizeof(CppType), seed);
}

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) {
CppType value = 0;
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;
}
};
Expand Down Expand Up @@ -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());
Expand Down
13 changes: 9 additions & 4 deletions be/src/util/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
11 changes: 8 additions & 3 deletions be/test/olap/row_cursor_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "runtime/mem_pool.h"
#include "runtime/mem_tracker.h"
#include "util/logging.h"
#include "util/types.h"

namespace doris {

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit e9f7a3e

Please sign in to comment.