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

joemcdonnell pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git


The following commit(s) were added to refs/heads/master by this push:
     new b188340  Reapply IMPALA-9781: Fix GCC 7 unaligned 128-bit loads / 
stores
b188340 is described below

commit b1883405cd59988b92df2799656666ff2f733c0e
Author: Joe McDonnell <joemcdonn...@cloudera.com>
AuthorDate: Wed May 27 16:21:36 2020 -0700

    Reapply IMPALA-9781: Fix GCC 7 unaligned 128-bit loads / stores
    
    When running a release binary built with GCC 7.5.0, it crashes
    with an unaligned memory error in multiple pieces of code.
    In these locations, we are doing stores to 128-bit values, but we
    cannot guarantee alignment. GCC 7 must be optimizing the code to
    use instructions that require a higher level of alignment than
    we can provide.
    
    This switches the code locations to use memcpy to avoid the
    unaligned stores (with local variables as necessary).
    
    Testing:
     - Ran exhaustive tests with a release binary built by GCC 7.5.0
     - Ran UBSAN core tests
     - Add unaligned test case in decimal-test
    
    Change-Id: I7edd8beeb15e4fbb69126a9f97a1476a4b8f12a9
    Reviewed-on: http://gerrit.cloudera.org:8080/16009
    Tested-by: Impala Public Jenkins <impala-public-jenk...@cloudera.com>
    Reviewed-by: Tim Armstrong <tarmstr...@cloudera.com>
---
 be/src/exprs/slot-ref.cc       | 5 ++++-
 be/src/runtime/decimal-test.cc | 4 ++++
 be/src/runtime/decimal-value.h | 3 ++-
 be/src/util/dict-encoding.h    | 5 +++--
 4 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/be/src/exprs/slot-ref.cc b/be/src/exprs/slot-ref.cc
index 634a989..661c7ef 100644
--- a/be/src/exprs/slot-ref.cc
+++ b/be/src/exprs/slot-ref.cc
@@ -422,7 +422,10 @@ DecimalVal SlotRef::GetDecimalValInterpreted(
     case 8:
       return DecimalVal(*reinterpret_cast<int64_t*>(t->GetSlot(slot_offset_)));
     case 16:
-      return 
DecimalVal(*reinterpret_cast<int128_t*>(t->GetSlot(slot_offset_)));
+      // Avoid an unaligned load by using memcpy
+      __int128_t val;
+      memcpy(&val, t->GetSlot(slot_offset_), sizeof(val));
+      return DecimalVal(val);
     default:
       DCHECK(false);
       return DecimalVal::null();
diff --git a/be/src/runtime/decimal-test.cc b/be/src/runtime/decimal-test.cc
index 9a2f7a8..c5aed53 100644
--- a/be/src/runtime/decimal-test.cc
+++ b/be/src/runtime/decimal-test.cc
@@ -726,6 +726,10 @@ TEST(DecimalTest, UnalignedValues) {
   stringstream ss;
   RawValue::PrintValue(unaligned, ColumnType::CreateDecimalType(28, 2), 0, 
&ss);
   EXPECT_EQ("123.45", ss.str());
+  // Regression test for IMPALA-9781: Verify that operator=() works
+  *unaligned = 0;
+  __int128_t val = unaligned->value();
+  EXPECT_EQ(val, 0);
   free(unaligned_mem);
 }
 
diff --git a/be/src/runtime/decimal-value.h b/be/src/runtime/decimal-value.h
index 761d474..e329476 100644
--- a/be/src/runtime/decimal-value.h
+++ b/be/src/runtime/decimal-value.h
@@ -49,7 +49,8 @@ class DecimalValue {
   DecimalValue(const T& s) : value_(s) { }
 
   DecimalValue& operator=(const T& s) {
-    value_ = s;
+    // 'value_' may be unaligned. Use memcpy to avoid an unaligned store.
+    memcpy(&value_, &s, sizeof(T));
     return *this;
   }
 
diff --git a/be/src/util/dict-encoding.h b/be/src/util/dict-encoding.h
index f440332..e6e01bc 100644
--- a/be/src/util/dict-encoding.h
+++ b/be/src/util/dict-encoding.h
@@ -346,10 +346,11 @@ class DictDecoder : public DictDecoderBase {
   virtual int num_entries() const { return dict_.size(); }
 
   virtual void GetValue(int index, void* buffer) {
-    T* val_ptr = reinterpret_cast<T*>(buffer);
     DCHECK_GE(index, 0);
     DCHECK_LT(index, dict_.size());
-    *val_ptr = dict_[index];
+    // Avoid an unaligned store by using memcpy
+    T val = dict_[index];
+    memcpy(buffer, reinterpret_cast<const void*>(&val), sizeof(T));
   }
 
   /// Returns the next value.  Returns false if the data is invalid.

Reply via email to