You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by lv...@apache.org on 2019/07/21 23:36:19 UTC

[impala] 01/05: IMPALA-5031: method calls on NULL are not UBSAN-clean

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

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

commit 0604ff51e00a1dcfef5823a02bb7bf612c917efc
Author: Jim Apple <jb...@apache.org>
AuthorDate: Thu Jul 4 10:52:01 2019 -0700

    IMPALA-5031: method calls on NULL are not UBSAN-clean
    
    According to [expr.post] in the C++14 standard, a call to a member
    function like a->b() is interpreted as (a->b)(). In other words, the
    dereferencing is done separately from the call. This makes calling
    member functions on nullptr undefined behavior, since the dereference
    invokes undefined behavior.
    
    This fixes an error in hdfs-scanner.h in the end-to-end tests. The
    interesting part of the backtrace is:
    
    exec/hdfs-scanner.h:512:14: runtime error: member call on null pointer
      of type 'Tuple'
        #0 HdfsScanner::InitTuple(TupleDescriptor const*, Tuple*, Tuple*)
           exec/hdfs-scanner.h:512:14
        #1 HdfsOrcScanner::AssembleCollection(OrcComplexColumnReader
           const&, int, CollectionValueBuilder*)
           exec/hdfs-orc-scanner.cc:743:7
        #2 OrcCollectionReader::ReadValue(int, Tuple*, MemPool*)
           exec/orc-column-readers.cc:375:20
        #3 OrcStructReader::ReadValue(int, Tuple*, MemPool*)
           exec/orc-column-readers.cc:322:52
        #4 OrcStructReader::ReadValue(int, Tuple*, MemPool*)
           exec/orc-column-readers.cc:322:52
        #5 OrcStructReader::TransferTuple(Tuple*, MemPool*)
           exec/orc-column-readers.cc:346:52
        #6 HdfsOrcScanner::TransferTuples(OrcComplexColumnReader*,
           RowBatch*) exec/hdfs-orc-scanner.cc:670:58
        #7 HdfsOrcScanner::AssembleRows(RowBatch*)
           exec/hdfs-orc-scanner.cc:630:45
        #8 HdfsOrcScanner::GetNextInternal(RowBatch*)
           exec/hdfs-orc-scanner.cc:508:19
        #9 HdfsOrcScanner::ProcessSplit() exec/hdfs-orc-scanner.cc:427:21
        #10 HdfsScanNode::ProcessSplit(vector<FilterContext> const&,
            MemPool*, io::ScanRange*, long*) exec/hdfs-scan-node.cc:514:21
        #11 HdfsScanNode::ScannerThread(bool, long)
            exec/hdfs-scan-node.cc:415:7
        #12 HdfsScanNode::ThreadTokenAvailableCb(ThreadResourcePool*)::$_0
            ::operator()() const exec/hdfs-scan-node.cc:337:13
    
    Change-Id: I7e5b130848a3c8f11d9010b3378f4054a35e1612
    Reviewed-on: http://gerrit.cloudera.org:8080/13803
    Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 be/src/exec/hdfs-scanner.h | 2 +-
 be/src/runtime/tuple.h     | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/be/src/exec/hdfs-scanner.h b/be/src/exec/hdfs-scanner.h
index 9cbc99b..62c1cb7 100644
--- a/be/src/exec/hdfs-scanner.h
+++ b/be/src/exec/hdfs-scanner.h
@@ -509,7 +509,7 @@ class HdfsScanner {
     if (has_template_tuple(template_tuple)) {
       InitTupleFromTemplate(template_tuple, tuple, tuple_byte_size(*desc));
     } else {
-      tuple->ClearNullBits(desc->null_bytes_offset(), desc->num_null_bytes());
+      Tuple::ClearNullBits(tuple, desc->null_bytes_offset(), desc->num_null_bytes());
     }
   }
 
diff --git a/be/src/runtime/tuple.h b/be/src/runtime/tuple.h
index 5f2c4af..1ead5e4 100644
--- a/be/src/runtime/tuple.h
+++ b/be/src/runtime/tuple.h
@@ -103,6 +103,10 @@ class Tuple {
     ClearNullBits(tuple_desc.null_bytes_offset(), tuple_desc.num_null_bytes());
   }
 
+  static void ClearNullBits(Tuple* that, int null_bytes_offset, int num_null_bytes) {
+    if (that != nullptr) that->ClearNullBits(null_bytes_offset, num_null_bytes);
+  }
+
   void ClearNullBits(int null_bytes_offset, int num_null_bytes) {
     Ubsan::MemSet(
         reinterpret_cast<uint8_t*>(this) + null_bytes_offset, 0, num_null_bytes);