llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

<details>
<summary>Changes</summary>

Even if a file has a valid modification time, it's possible that reading the 
data fails. The SourceManager wasn't accounting for that, which would result in 
a crash due to an unchecked read from a null `data_sp`.

We were seeing the issue when trying to read from a buggy virtual file system, 
but presumably the same thing can happen with a poorly timed unmount of a drive.

rdar://166414707

---
Full diff: https://github.com/llvm/llvm-project/pull/174346.diff


1 Files Affected:

- (modified) lldb/source/Core/SourceManager.cpp (+11-2) 


``````````diff
diff --git a/lldb/source/Core/SourceManager.cpp 
b/lldb/source/Core/SourceManager.cpp
index c60288c633e4c..5f0848c0abfd9 100644
--- a/lldb/source/Core/SourceManager.cpp
+++ b/lldb/source/Core/SourceManager.cpp
@@ -570,7 +570,11 @@ void 
SourceManager::File::CommonInitializerImpl(SupportFileNSP support_file_nsp,
   if (m_mod_time != llvm::sys::TimePoint<>()) {
     m_data_sp = FileSystem::Instance().CreateDataBuffer(
         m_support_file_nsp->GetSpecOnly());
-    m_checksum = llvm::MD5::hash(m_data_sp->GetData());
+    // Even if we have a valid modification time, reading the data might fail.
+    // Use the checksum from the line entry so we don't show a checksum
+    // mismatch.
+    m_checksum = m_data_sp ? llvm::MD5::hash(m_data_sp->GetData())
+                           : m_support_file_nsp->GetChecksum();
   }
 }
 
@@ -605,6 +609,8 @@ const char *SourceManager::File::PeekLineData(uint32_t 
line) {
   if (!LineIsValid(line))
     return nullptr;
 
+  assert(m_data_sp);
+
   size_t line_offset = GetLineOffset(line);
   if (line_offset < m_data_sp->GetByteSize())
     return (const char *)m_data_sp->GetBytes() + line_offset;
@@ -616,6 +622,8 @@ uint32_t SourceManager::File::GetLineLength(uint32_t line,
   if (!LineIsValid(line))
     return false;
 
+  assert(m_data_sp);
+
   size_t start_offset = GetLineOffset(line);
   size_t end_offset = GetLineOffset(line + 1);
   if (end_offset == UINT32_MAX)
@@ -764,7 +772,7 @@ bool SourceManager::File::CalculateLineOffsets(uint32_t 
line) {
       return true;
 
     if (m_offsets.empty()) {
-      if (m_data_sp.get() == nullptr)
+      if (!m_data_sp)
         return false;
 
       const char *start = (const char *)m_data_sp->GetBytes();
@@ -812,6 +820,7 @@ bool SourceManager::File::GetLine(uint32_t line_no, 
std::string &buffer) {
   if (!LineIsValid(line_no))
     return false;
 
+  assert(m_data_sp);
   size_t start_offset = GetLineOffset(line_no);
   size_t end_offset = GetLineOffset(line_no + 1);
   if (end_offset == UINT32_MAX) {

``````````

</details>


https://github.com/llvm/llvm-project/pull/174346
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to