vsk created this revision. vsk added reviewers: jingham, aprantl. Value::GetValueByteSize() assumes that the size of a Value is always equal to the size of the underlying variable's CompilerType. However, llvm's DWARF generator doesn't appear to create fresh types with new sizes when emitting fragments / DW_OP_piece. It seems like there's a faulty assumption in lldb (although it's plausible that llvm is just generating weird DWARF).
This patch teaches GetValueByteSize() to report the size of a Value as the size of its data buffer if it's a host address. I'm not sure whether this is an exhaustive fix. This does fix an ASan error in lldb seen when debugging a clang binary. ASan report: F11233245: asan-report-rdar58665925.txt <https://reviews.llvm.org/F11233245> rdar://58665925 https://reviews.llvm.org/D73148 Files: lldb/source/Core/Value.cpp lldb/unittests/Expression/DWARFExpressionTest.cpp Index: lldb/unittests/Expression/DWARFExpressionTest.cpp =================================================================== --- lldb/unittests/Expression/DWARFExpressionTest.cpp +++ lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -360,4 +360,16 @@ // Note that the "00" should really be "undef", but we can't // represent that yet. llvm::HasValue(GetScalar(16, 0xff00, true))); + + for (unsigned char ByteSize = 1; ByteSize <= 8; ++ByteSize) { + llvm::Expected<Scalar> empty = Evaluate({DW_OP_piece, ByteSize}); + // Note that the "00" should really be "undef", but we can't + // represent that yet. + EXPECT_THAT_EXPECTED(empty, + llvm::HasValue(GetScalar(ByteSize * 8, 0, true))); + + Value pieces; + ASSERT_EQ(pieces.AppendDataToHostBuffer(empty.get()), ByteSize); + ASSERT_EQ(pieces.GetValueByteSize(nullptr, nullptr), ByteSize); + } } Index: lldb/source/Core/Value.cpp =================================================================== --- lldb/source/Core/Value.cpp +++ lldb/source/Core/Value.cpp @@ -222,6 +222,11 @@ case eContextTypeLLDBType: // Type * case eContextTypeVariable: // Variable * { + // The size of this Value may be less than the size of the type of its + // source variable due to truncating operations such as DW_OP_piece. + if (m_value_type == eValueTypeHostAddress) + return GetBuffer().GetByteSize(); + auto *scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr; if (llvm::Optional<uint64_t> size = GetCompilerType().GetByteSize(scope)) { if (error_ptr)
Index: lldb/unittests/Expression/DWARFExpressionTest.cpp =================================================================== --- lldb/unittests/Expression/DWARFExpressionTest.cpp +++ lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -360,4 +360,16 @@ // Note that the "00" should really be "undef", but we can't // represent that yet. llvm::HasValue(GetScalar(16, 0xff00, true))); + + for (unsigned char ByteSize = 1; ByteSize <= 8; ++ByteSize) { + llvm::Expected<Scalar> empty = Evaluate({DW_OP_piece, ByteSize}); + // Note that the "00" should really be "undef", but we can't + // represent that yet. + EXPECT_THAT_EXPECTED(empty, + llvm::HasValue(GetScalar(ByteSize * 8, 0, true))); + + Value pieces; + ASSERT_EQ(pieces.AppendDataToHostBuffer(empty.get()), ByteSize); + ASSERT_EQ(pieces.GetValueByteSize(nullptr, nullptr), ByteSize); + } } Index: lldb/source/Core/Value.cpp =================================================================== --- lldb/source/Core/Value.cpp +++ lldb/source/Core/Value.cpp @@ -222,6 +222,11 @@ case eContextTypeLLDBType: // Type * case eContextTypeVariable: // Variable * { + // The size of this Value may be less than the size of the type of its + // source variable due to truncating operations such as DW_OP_piece. + if (m_value_type == eValueTypeHostAddress) + return GetBuffer().GetByteSize(); + auto *scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr; if (llvm::Optional<uint64_t> size = GetCompilerType().GetByteSize(scope)) { if (error_ptr)
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits