<rdar://problem/10507811>
authorGreg Clayton <gclayton@apple.com>
Wed, 4 Jan 2012 22:56:43 +0000 (22:56 +0000)
committerGreg Clayton <gclayton@apple.com>
Wed, 4 Jan 2012 22:56:43 +0000 (22:56 +0000)
Be better at detecting when DWARF changes and handle this more
gracefully than asserting and exiting.

Also fixed up a bunch of system calls that weren't properly checking
for EINTR.

llvm-svn: 147559

lldb/include/lldb/API/SBFrame.h
lldb/include/lldb/Expression/DWARFExpression.h
lldb/include/lldb/Host/File.h
lldb/scripts/build-lldb-llvm-clang
lldb/source/Core/ConnectionFileDescriptor.cpp
lldb/source/Expression/DWARFExpression.cpp
lldb/source/Host/common/File.cpp
lldb/source/Host/common/FileSpec.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

index d351fd2..bd4636c 100644 (file)
@@ -16,8 +16,6 @@
 
 namespace lldb {
 
-class SBValue;
-
 class SBFrame
 {
 public:
index 3db1a64..6831708 100644 (file)
@@ -142,6 +142,10 @@ public:
     /// @param[in] file_addr
     ///     The file address to search for in the location. 
     ///
+    /// @param[out] error
+    ///     If the location stream contains unknown DW_OP opcodes or the
+    ///     data is missing, \a error will be set to \b true.
+    ///
     /// @return
     ///     True if IsLocationList() is false and the \a file_addr was
     ///     is contained in a DW_OP_addr location opcode or if \a file_addr
@@ -149,7 +153,7 @@ public:
     ///     otherwise.
     //------------------------------------------------------------------
     bool
-    LocationContains_DW_OP_addr (lldb::addr_t file_addr = LLDB_INVALID_ADDRESS) const;
+    LocationContains_DW_OP_addr (lldb::addr_t file_addr, bool &error) const;
 
     bool
     Update_DW_OP_addr (lldb::addr_t file_addr);
index 160f2e7..69e8cc6 100644 (file)
@@ -35,9 +35,10 @@ public:
         eOpenOptionRead                 = (1u << 0),    // Open file for reading
         eOpenOptionWrite                = (1u << 1),    // Open file for writing
         eOpenOptionAppend               = (1u << 2),    // Don't truncate file when opening, append to end of file
-        eOpenOptionNonBlocking          = (1u << 3),    // File reads
-        eOpenOptionCanCreate            = (1u << 4),    // Create file if doesn't already exist
-        eOpenOptionCanCreateNewOnly     = (1u << 5)    // Can create file only if it doesn't already exist
+        eOpenOptionTruncate             = (1u << 3),    // Truncate file when opening
+        eOpenOptionNonBlocking          = (1u << 4),    // File reads
+        eOpenOptionCanCreate            = (1u << 5),    // Create file if doesn't already exist
+        eOpenOptionCanCreateNewOnly     = (1u << 6)     // Can create file only if it doesn't already exist
     };
     
     enum Permissions
@@ -362,6 +363,34 @@ public:
     Read (void *dst, size_t &num_bytes, off_t &offset);
     
     //------------------------------------------------------------------
+    /// Read bytes from a file from the specified file offset.
+    ///
+    /// NOTE: This function is thread safe in that clients manager their
+    /// own file position markers and reads on other threads won't mess
+    /// up the current read.
+    ///
+    /// @param[in/out] num_bytes
+    ///     The number of bytes to read form the current file position
+    ///     which gets modified with the number of bytes that were read.
+    ///
+    /// @param[in/out] offset
+    ///     The offset within the file from which to read \a num_bytes
+    ///     bytes. This offset gets incremented by the number of bytes
+    ///     that were read.
+    ///
+    /// @param[out] data_buffer_sp
+    ///     A data buffer to create and fill in that will contain any
+    ///     data that is read from the file. This buffer will be reset
+    ///     if an error occurs.
+    ///
+    /// @return
+    ///     An error object that indicates success or the reason for 
+    ///     failure.
+    //------------------------------------------------------------------
+    Error
+    Read (size_t &num_bytes, off_t &offset, lldb::DataBufferSP &data_buffer_sp);
+
+    //------------------------------------------------------------------
     /// Write bytes to a file at the specified file offset.
     ///
     /// NOTE: This function is thread safe in that clients manager their
index 17c7e54..822e994 100755 (executable)
@@ -22,13 +22,11 @@ svn co -q -r $LLVM_REVISION http://llvm.org/svn/llvm-project/llvm/trunk llvm
 
 # change directory to "./llvm"
 cd llvm
-rm -rf test
 
 # Checkout Clang
 # change directory to "./llvm/tools"
 cd tools
 svn co -q -r $CLANG_REVISION http://llvm.org/svn/llvm-project/cfe/trunk clang
-rm -rf clang/test
 
 # change directory to "./llvm"
 cd ..
@@ -65,8 +63,11 @@ elif [ "$LLVM_CONFIGURATION" = "Release" ]; then
        make -j8 clang-only VERBOSE=1 PROJECT_NAME='llvm'
        make -j8 tools-only VERBOSE=1 PROJECT_NAME='llvm' EDIS_VERSION=1
 elif [ "$LLVM_CONFIGURATION" = "BuildAndIntegration" ]; then
-       # Configure "BuildAndIntegration" build
-       rm -rf ./scripts/*.diff
+       # Don't configure or build for "BuildAndIntegration", this configuration 
+       # is a preparation step for a build submission
+       
+       # Remove all patches, and the llvm and clang "test" directories
+       rm -rf ./scripts/*.diff ./llvm/test ./llvm/tools/clang/test
 else
        echo "checked out llvm (revision $LLVM_REVISION) and clang (revision $CLANG_REVISION)."
        exit 0
index 5c0e97d..f83d999 100644 (file)
@@ -188,7 +188,10 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
         {
             // file:///PATH
             const char *path = s + strlen("file://");
-            m_fd_send = m_fd_recv = ::open (path, O_RDWR);
+            do
+            {
+                m_fd_send = m_fd_recv = ::open (path, O_RDWR);
+            } while (m_fd_send == -1 && errno == EINTR);
             if (m_fd_send == -1)
             {
                 if (error_ptr)
@@ -269,14 +272,22 @@ ConnectionFileDescriptor::Read (void *dst,
     case eFDTypeFile:       // Other FD requireing read/write
         status = BytesAvailable (timeout_usec, error_ptr);
         if (status == eConnectionStatusSuccess)
-            bytes_read = ::read (m_fd_recv, dst, dst_len);
+        {
+            do
+            {
+                bytes_read = ::read (m_fd_recv, dst, dst_len);
+            } while (bytes_read < 0 && errno == EINTR);
+        }
         break;
 
     case eFDTypeSocket:     // Socket requiring send/recv
         if (SetSocketReceiveTimeout (timeout_usec))
         {
             status = eConnectionStatusSuccess;
-            bytes_read = ::recv (m_fd_recv, dst, dst_len, 0);
+            do
+            {
+                bytes_read = ::recv (m_fd_recv, dst, dst_len, 0);
+            } while (bytes_read < 0 && errno == EINTR);
         }
         break;
 
@@ -286,7 +297,10 @@ ConnectionFileDescriptor::Read (void *dst,
             status = eConnectionStatusSuccess;
             SocketAddress from (m_udp_send_sockaddr);
             socklen_t from_len = m_udp_send_sockaddr.GetLength();
-            bytes_read = ::recvfrom (m_fd_recv, dst, dst_len, 0, (struct sockaddr *)&from, &from_len);
+            do
+            {
+                bytes_read = ::recvfrom (m_fd_recv, dst, dst_len, 0, (struct sockaddr *)&from, &from_len);
+            } while (bytes_read < 0 && errno == EINTR);
         }
         break;
     }
@@ -392,21 +406,30 @@ ConnectionFileDescriptor::Write (const void *src, size_t src_len, ConnectionStat
     switch (m_fd_send_type)
     {
         case eFDTypeFile:       // Other FD requireing read/write
-            bytes_sent = ::write (m_fd_send, src, src_len);
+            do
+            {
+                bytes_sent = ::write (m_fd_send, src, src_len);
+            } while (bytes_sent < 0 && errno == EINTR);
             break;
             
         case eFDTypeSocket:     // Socket requiring send/recv
-            bytes_sent = ::send (m_fd_send, src, src_len, 0);
+            do
+            {
+                bytes_sent = ::send (m_fd_send, src, src_len, 0);
+            } while (bytes_sent < 0 && errno == EINTR);
             break;
             
         case eFDTypeSocketUDP:  // Unconnected UDP socket requiring sendto/recvfrom
             assert (m_udp_send_sockaddr.GetFamily() != 0);
-            bytes_sent = ::sendto (m_fd_send, 
-                                   src, 
-                                   src_len, 
-                                   0, 
-                                   m_udp_send_sockaddr, 
-                                   m_udp_send_sockaddr.GetLength());
+            do
+            {
+                bytes_sent = ::sendto (m_fd_send, 
+                                       src, 
+                                       src_len, 
+                                       0, 
+                                       m_udp_send_sockaddr, 
+                                       m_udp_send_sockaddr.GetLength());
+            } while (bytes_sent < 0 && errno == EINTR);
             break;
     }
 
index 6ce8201..3555c41 100644 (file)
@@ -992,18 +992,15 @@ GetOpcodeDataSize (const DataExtractor &data, const uint32_t data_offset, const
             }
             
         default:
-        {
-            Host::SetCrashDescriptionWithFormat ("Unhandled DW_OP_XXX opcode: %d, add support for it.", op);
-            assert (!"Unhandled DW_OP_XXX opcode - look for actual value in Crash Description string.");
-        }
-        break;
+            break;
     }
     return UINT32_MAX;
 }
 
 bool
-DWARFExpression::LocationContains_DW_OP_addr (lldb::addr_t file_addr) const
+DWARFExpression::LocationContains_DW_OP_addr (lldb::addr_t file_addr, bool &error) const
 {
+    error = false;
     if (IsLocationList())
         return false;
     uint32_t offset = 0;
@@ -1023,7 +1020,10 @@ DWARFExpression::LocationContains_DW_OP_addr (lldb::addr_t file_addr) const
         {
             const uint32_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
             if (op_arg_size == UINT32_MAX)
+            {
+                error = true;
                 break;
+            }
             offset += op_arg_size;
         }
     }
index a12cd3a..a84266f 100644 (file)
 
 #include "lldb/Host/File.h"
 
+#include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <stdarg.h>
 #include <sys/stat.h>
 
+#include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Host/Config.h"
 #include "lldb/Host/FileSpec.h"
@@ -135,7 +137,12 @@ File::GetStream ()
         {
             const char *mode = GetStreamOpenModeFromOptions (m_options);
             if (mode)
-                m_stream = ::fdopen (m_descriptor, mode);
+            {
+                do
+                {
+                    m_stream = ::fdopen (m_descriptor, mode);
+                } while (m_stream == NULL && errno == EINTR);
+            }
         }
     }
     return m_stream;
@@ -184,40 +191,54 @@ File::Open (const char *path, uint32_t options, uint32_t permissions)
         Close ();
 
     int oflag = 0;
-    if (options & eOpenOptionRead && 
-        options & eOpenOptionWrite )
-        oflag |= O_RDWR;
-    else if (options & eOpenOptionRead)
+    const bool read = options & eOpenOptionRead;
+    const bool write = options & eOpenOptionWrite;
+    if (write)
+    {
+        if (read)
+            oflag |= O_RDWR;
+        else
+            oflag |= O_WRONLY;
+        
+        if (options & eOpenOptionAppend)
+            oflag |= O_APPEND;
+
+        if (options & eOpenOptionTruncate)
+            oflag |= O_TRUNC;
+
+        if (options & eOpenOptionCanCreate)
+            oflag |= O_CREAT;
+        
+        if (options & eOpenOptionCanCreateNewOnly)
+            oflag |= O_CREAT | O_EXCL;
+    }
+    else if (read)
+    {
         oflag |= O_RDONLY;
-    else if (options & eOpenOptionWrite)
-        oflag |= O_WRONLY;
+    }
     
     if (options & eOpenOptionNonBlocking)
         oflag |= O_NONBLOCK;
 
-    if (options & eOpenOptionAppend)
-        oflag |= O_APPEND;
-    else
-        oflag |= O_TRUNC;
-
-    if (options & eOpenOptionCanCreate)
-        oflag |= O_CREAT;
-    
-    if (options & eOpenOptionCanCreateNewOnly)
-        oflag |= O_CREAT | O_EXCL;
-    
     mode_t mode = 0;
-    if (permissions & ePermissionsUserRead)     mode |= S_IRUSR;
-    if (permissions & ePermissionsUserWrite)    mode |= S_IWUSR;
-    if (permissions & ePermissionsUserExecute)  mode |= S_IXUSR;
-    if (permissions & ePermissionsGroupRead)    mode |= S_IRGRP;
-    if (permissions & ePermissionsGroupWrite)   mode |= S_IWGRP;
-    if (permissions & ePermissionsGroupExecute) mode |= S_IXGRP;
-    if (permissions & ePermissionsWorldRead)    mode |= S_IROTH;
-    if (permissions & ePermissionsWorldWrite)   mode |= S_IWOTH;
-    if (permissions & ePermissionsWorldExecute) mode |= S_IXOTH;
-
-    m_descriptor = ::open(path, oflag, mode);
+    if (oflag & O_CREAT)
+    {
+        if (permissions & ePermissionsUserRead)     mode |= S_IRUSR;
+        if (permissions & ePermissionsUserWrite)    mode |= S_IWUSR;
+        if (permissions & ePermissionsUserExecute)  mode |= S_IXUSR;
+        if (permissions & ePermissionsGroupRead)    mode |= S_IRGRP;
+        if (permissions & ePermissionsGroupWrite)   mode |= S_IWGRP;
+        if (permissions & ePermissionsGroupExecute) mode |= S_IXGRP;
+        if (permissions & ePermissionsWorldRead)    mode |= S_IROTH;
+        if (permissions & ePermissionsWorldWrite)   mode |= S_IWOTH;
+        if (permissions & ePermissionsWorldExecute) mode |= S_IXOTH;
+    }
+
+    do
+    {
+        m_descriptor = ::open(path, oflag, mode);
+    } while (m_descriptor < 0 && errno == EINTR);
+
     if (!DescriptorIsValid())
         error.SetErrorToErrno();
     else
@@ -357,7 +378,13 @@ File::Flush ()
     Error error;
     if (StreamIsValid())
     {
-        if (::fflush (m_stream) == EOF)
+        int err = 0;
+        do
+        {
+            err = ::fflush (m_stream);
+        } while (err == EOF && errno == EINTR);
+        
+        if (err == EOF)
             error.SetErrorToErrno();
     }
     else if (!DescriptorIsValid())
@@ -374,7 +401,13 @@ File::Sync ()
     Error error;
     if (DescriptorIsValid())
     {
-        if (::fsync (m_descriptor) == -1)
+        int err = 0;
+        do
+        {
+            err = ::fsync (m_descriptor);
+        } while (err == -1 && errno == EINTR);
+        
+        if (err == -1)
             error.SetErrorToErrno();
     }
     else 
@@ -388,9 +421,14 @@ Error
 File::Read (void *buf, size_t &num_bytes)
 {
     Error error;
+    ssize_t bytes_read = -1;
     if (DescriptorIsValid())
     {
-        ssize_t bytes_read = ::read (m_descriptor, buf, num_bytes);
+        do
+        {
+            bytes_read = ::read (m_descriptor, buf, num_bytes);
+        } while (bytes_read < 0 && errno == EINTR);
+
         if (bytes_read == -1)
         {
             error.SetErrorToErrno();
@@ -401,7 +439,8 @@ File::Read (void *buf, size_t &num_bytes)
     }
     else if (StreamIsValid())
     {
-        size_t bytes_read = ::fread (buf, 1, num_bytes, m_stream);
+        bytes_read = ::fread (buf, 1, num_bytes, m_stream);
+
         if (bytes_read == 0)
         {
             if (::feof(m_stream))
@@ -425,9 +464,14 @@ Error
 File::Write (const void *buf, size_t &num_bytes)
 {
     Error error;
+    ssize_t bytes_written = -1;
     if (DescriptorIsValid())
     {
-        ssize_t bytes_written = ::write (m_descriptor, buf, num_bytes);
+        do
+        {
+            bytes_written = ::write (m_descriptor, buf, num_bytes);
+        } while (bytes_written < 0 && errno == EINTR);
+
         if (bytes_written == -1)
         {
             error.SetErrorToErrno();
@@ -438,7 +482,8 @@ File::Write (const void *buf, size_t &num_bytes)
     }
     else if (StreamIsValid())
     {
-        size_t bytes_written = ::fwrite (buf, 1, num_bytes, m_stream);
+        bytes_written = ::fwrite (buf, 1, num_bytes, m_stream);
+
         if (bytes_written == 0)
         {
             if (::feof(m_stream))
@@ -467,7 +512,12 @@ File::Read (void *buf, size_t &num_bytes, off_t &offset)
     int fd = GetDescriptor();
     if (fd != kInvalidDescriptor)
     {
-        ssize_t bytes_read = ::pread (fd, buf, num_bytes, offset);
+        ssize_t bytes_read = -1;
+        do
+        {
+            bytes_read = ::pread (fd, buf, num_bytes, offset);
+        } while (bytes_read < 0 && errno == EINTR);
+
         if (bytes_read < 0)
         {
             num_bytes = 0;
@@ -488,13 +538,71 @@ File::Read (void *buf, size_t &num_bytes, off_t &offset)
 }
 
 Error
+File::Read (size_t &num_bytes, off_t &offset, DataBufferSP &data_buffer_sp)
+{
+    Error error;
+    
+    if (num_bytes > 0)
+    {
+        int fd = GetDescriptor();
+        if (fd != kInvalidDescriptor)
+        {
+            struct stat file_stats;
+            if (::fstat (fd, &file_stats) == 0)
+            {
+                if (file_stats.st_size > offset)
+                {
+                    const size_t bytes_left = file_stats.st_size - offset;
+                    if (num_bytes > bytes_left)
+                        num_bytes = bytes_left;
+                        
+                    std::auto_ptr<DataBufferHeap> data_heap_ap;
+                    data_heap_ap.reset(new DataBufferHeap(num_bytes, '\0'));
+                        
+                    if (data_heap_ap.get())
+                    {
+                        error = Read (data_heap_ap->GetBytes(), num_bytes, offset);
+                        if (error.Success())
+                        {
+                            // Make sure we read exactly what we asked for and if we got
+                            // less, adjust the array
+                            if (num_bytes < data_heap_ap->GetByteSize())
+                                data_heap_ap->SetByteSize(num_bytes);
+                            data_buffer_sp.reset(data_heap_ap.release());
+                            return error;
+                        }
+                    }
+                }
+                else 
+                    error.SetErrorString("file is empty");
+            }
+            else
+                error.SetErrorToErrno();
+        }
+        else 
+            error.SetErrorString("invalid file handle");
+    }
+    else
+        error.SetErrorString("invalid file handle");
+
+    num_bytes = 0;
+    data_buffer_sp.reset();
+    return error;
+}
+
+Error
 File::Write (const void *buf, size_t &num_bytes, off_t &offset)
 {
     Error error;
     int fd = GetDescriptor();
     if (fd != kInvalidDescriptor)
     {
-        ssize_t bytes_written = ::pwrite (m_descriptor, buf, num_bytes, offset);
+        ssize_t bytes_written = -1;
+        do
+        {
+            bytes_written = ::pwrite (m_descriptor, buf, num_bytes, offset);
+        } while (bytes_written < 0 && errno == EINTR);
+
         if (bytes_written < 0)
         {
             num_bytes = 0;
index b6e6e94..1f0942d 100644 (file)
@@ -24,6 +24,7 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
 
+#include "lldb/Host/File.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataBufferMemoryMap.h"
@@ -776,29 +777,15 @@ FileSpec::ReadFileContents (off_t file_offset, void *dst, size_t dst_len) const
     char resolved_path[PATH_MAX];
     if (GetPath(resolved_path, sizeof(resolved_path)))
     {
-        int fd = ::open (resolved_path, O_RDONLY, 0);
-        if (fd != -1)
+        Error error;
+        File file;
+        error = file.Open(resolved_path, File::eOpenOptionRead);
+        if (error.Success())
         {
-            struct stat file_stats;
-            if (::fstat (fd, &file_stats) == 0)
-            {
-                // Read bytes directly into our basic_string buffer
-                if (file_stats.st_size > 0)
-                {
-                    off_t lseek_result = 0;
-                    if (file_offset > 0)
-                        lseek_result = ::lseek (fd, file_offset, SEEK_SET);
-
-                    if (lseek_result == file_offset)
-                    {
-                        ssize_t n = ::read (fd, dst, dst_len);
-                        if (n >= 0)
-                            bytes_read = n;
-                    }
-                }
-            }
+            off_t file_offset_after_seek = file_offset;
+            bytes_read = dst_len;
+            error = file.Read(dst, bytes_read, file_offset_after_seek);
         }
-        close(fd);
     }
     return bytes_read;
 }
@@ -821,49 +808,11 @@ FileSpec::ReadFileContents (off_t file_offset, size_t file_size) const
     char resolved_path[PATH_MAX];
     if (GetPath(resolved_path, sizeof(resolved_path)))
     {
-        int fd = ::open (resolved_path, O_RDONLY, 0);
-        if (fd != -1)
-        {
-            struct stat file_stats;
-            if (::fstat (fd, &file_stats) == 0)
-            {
-                if (file_stats.st_size > 0)
-                {
-                    off_t lseek_result = 0;
-                    if (file_offset > 0)
-                        lseek_result = ::lseek (fd, file_offset, SEEK_SET);
-
-                    if (lseek_result < 0)
-                    {
-                        // Get error from errno
-                    }
-                    else if (lseek_result == file_offset)
-                    {
-                        const size_t bytes_left = file_stats.st_size - file_offset;
-                        size_t num_bytes_to_read = file_size;
-                        if (num_bytes_to_read > bytes_left)
-                            num_bytes_to_read = bytes_left;
-
-                        std::auto_ptr<DataBufferHeap> data_heap_ap;
-                        data_heap_ap.reset(new DataBufferHeap(num_bytes_to_read, '\0'));
-
-                        if (data_heap_ap.get())
-                        {
-                            ssize_t bytesRead = ::read (fd, (void *)data_heap_ap->GetBytes(), data_heap_ap->GetByteSize());
-                            if (bytesRead >= 0)
-                            {
-                                // Make sure we read exactly what we asked for and if we got
-                                // less, adjust the array
-                                if ((size_t)bytesRead < data_heap_ap->GetByteSize())
-                                    data_heap_ap->SetByteSize(bytesRead);
-                                data_sp.reset(data_heap_ap.release());
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        close(fd);
+        Error error;
+        File file;
+        error = file.Open(resolved_path, File::eOpenOptionRead);
+        if (error.Success())
+            error = file.Read (file_size, file_offset, data_sp);
     }
     return data_sp;
 }
index 26961f4..48506de 100644 (file)
@@ -720,19 +720,16 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges
     std::vector<dw_offset_t> die_offsets;
     bool set_frame_base_loclist_addr = false;
     
-    const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(cu);
+    dw_offset_t offset;
+    const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
 
     if (abbrevDecl)
     {
         const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
-        uint32_t offset = m_offset;
 
         if (!debug_info_data.ValidOffset(offset))
             return false;
 
-        // Skip the abbreviation code
-        debug_info_data.Skip_LEB128(&offset);
-
         const uint32_t numAttributes = abbrevDecl->NumAttributes();
         uint32_t i;
         dw_attr_t attr;
@@ -914,9 +911,13 @@ DWARFDebugInfoEntry::Dump
 
         s.Printf("\n0x%8.8x: ", m_offset);
         s.Indent();
-        if (abbrCode)
+        if (abbrCode != m_abbr_idx)
+        {
+            s.Printf( "error: DWARF has been modified\n");
+        }
+        else if (abbrCode)
         {
-            const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(cu);
+            const DWARFAbbreviationDeclaration* abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration (abbrCode);
 
             if (abbrevDecl)
             {
@@ -1156,17 +1157,15 @@ DWARFDebugInfoEntry::GetAttributes
     uint32_t curr_depth
 ) const
 {
-    const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(cu);
+    uint32_t offset;
+    const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
 
     if (abbrevDecl)
     {
-        if (fixed_form_sizes == NULL)
-            fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(cu->GetAddressByteSize());
-        uint32_t offset = GetOffset();
         const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
 
-        // Skip the abbreviation code so we are at the data for the attributes
-        debug_info_data.Skip_LEB128(&offset);
+        if (fixed_form_sizes == NULL)
+            fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(cu->GetAddressByteSize());
 
         const uint32_t num_attributes = abbrevDecl->NumAttributes();
         uint32_t i;
@@ -1255,7 +1254,8 @@ DWARFDebugInfoEntry::GetAttributeValue
     dw_offset_t* end_attr_offset_ptr
 ) const
 {
-    const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(cu);
+    uint32_t offset;
+    const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
 
     if (abbrevDecl)
     {
@@ -1263,13 +1263,8 @@ DWARFDebugInfoEntry::GetAttributeValue
 
         if (attr_idx != DW_INVALID_INDEX)
         {
-            uint32_t offset = GetOffset();
-
             const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
 
-            // Skip the abbreviation code so we are at the data for the attributes
-            debug_info_data.Skip_LEB128(&offset);
-
             uint32_t idx=0;
             while (idx<attr_idx)
                 DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu);
@@ -1583,7 +1578,7 @@ DWARFDebugInfoEntry::AppendTypeName
             else
             {
                 bool result = true;
-                const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(cu);
+                const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
 
                 switch (abbrevDecl->Tag())
                 {
@@ -2071,10 +2066,29 @@ DWARFDebugInfoEntry::LookupAddress
 }
 
 const DWARFAbbreviationDeclaration* 
-DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (const DWARFCompileUnit *cu) const
+DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
+                                                    const DWARFCompileUnit *cu,
+                                                    dw_offset_t &offset) const
 {
-    if (m_abbr_idx)
-        return cu->GetAbbreviations()->GetAbbreviationDeclaration (m_abbr_idx);
+    offset = GetOffset();
+    
+    const DWARFAbbreviationDeclaration* abbrev_decl = cu->GetAbbreviations()->GetAbbreviationDeclaration (m_abbr_idx);
+    if (abbrev_decl)
+    {
+        // Make sure the abbreviation code still matches. If it doesn't and
+        // the DWARF data was mmap'ed, the backing file might have been modified
+        // which is bad news.
+        const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
+    
+        if (abbrev_decl->Code() == abbrev_code)
+            return abbrev_decl;
+
+        dwarf2Data->ReportError ("0x%8.8x: the DWARF debug info has been modified (abbrev code was %u, and is now %u)", 
+                                 GetOffset(),
+                                 (uint32_t)abbrev_decl->Code(),
+                                 (uint32_t)abbrev_code);
+    }
+    offset = DW_INVALID_OFFSET;
     return NULL;
 }
 
index 350e4de..9c2914f 100644 (file)
@@ -300,7 +300,9 @@ public:
                     lldb_private::DWARFExpression *frame_base = NULL) const;
 
     const DWARFAbbreviationDeclaration* 
-    GetAbbreviationDeclarationPtr (const DWARFCompileUnit *cu) const;
+    GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
+                                   const DWARFCompileUnit *cu,
+                                   dw_offset_t &offset) const;
 
     dw_tag_t
     Tag () const 
index 6b16f0f..3d19604 100644 (file)
@@ -5553,10 +5553,19 @@ SymbolFileDWARF::ParseVariableDIE
                     scope = eValueTypeVariableArgument;
                 else
                 {
+                    bool op_error = false;
                     // Check if the location has a DW_OP_addr with any address value...
                     addr_t location_has_op_addr = false;
                     if (!location_is_const_value_data)
-                        location_has_op_addr = location.LocationContains_DW_OP_addr ();
+                    {
+                        location_has_op_addr = location.LocationContains_DW_OP_addr (LLDB_INVALID_ADDRESS, op_error);
+                        if (op_error)
+                        {
+                            StreamString strm;
+                            location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
+                            ReportError ("0x%8.8x: %s has an invalid location: %s", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), strm.GetString().c_str());
+                        }
+                    }
 
                     if (location_has_op_addr)
                     {
@@ -5584,7 +5593,7 @@ SymbolFileDWARF::ParseVariableDIE
                                 // location for the variable, and set the variable's
                                 // symbol context scope to be that of the main executable
                                 // so the file address will resolve correctly.
-                                if (location.LocationContains_DW_OP_addr (0))
+                                if (location.LocationContains_DW_OP_addr (0, op_error))
                                 {
                                     
                                     // we have a possible uninitialized extern global