namespace lldb {
-class SBValue;
-
class SBFrame
{
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
/// 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);
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
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
# 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 ..
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
{
// 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)
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;
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;
}
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;
}
}
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;
{
const uint32_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
if (op_arg_size == UINT32_MAX)
+ {
+ error = true;
break;
+ }
offset += op_arg_size;
}
}
#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"
{
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;
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
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())
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
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();
}
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))
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();
}
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))
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;
}
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;
#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"
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;
}
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;
}
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;
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)
{
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;
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)
{
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);
else
{
bool result = true;
- const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(cu);
+ const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
switch (abbrevDecl->Tag())
{
}
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;
}
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
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)
{
// 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