summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2015-02-23 23:47:09 +0000
committerGreg Clayton <gclayton@apple.com>2015-02-23 23:47:09 +0000
commit736888c84b51c7cf1f8eccea6738ad54503c2d0a (patch)
treee3d33c87985a4395053a078f387abea669744315 /lldb/source
parent18c243b933740506b3262e56ef6f9a3a6e4afc08 (diff)
downloadbcm5719-llvm-736888c84b51c7cf1f8eccea6738ad54503c2d0a.tar.gz
bcm5719-llvm-736888c84b51c7cf1f8eccea6738ad54503c2d0a.zip
Avoid crashing by not mmap'ing files on network mounted file systems.
This is implemented by making a new FileSystem function: bool FileSystem::IsLocal(const FileSpec &spec) Then using this in a new function: DataBufferSP FileSpec::MemoryMapFileContentsIfLocal(off_t file_offset, size_t file_size) const; This function only mmaps data if the file is a local file since that means we can reliably page in data. We were experiencing crashes where people would use debug info files on network mounted file systems and that mount would go away and cause the next access to a page that wasn't paged in to crash LLDB. We now avoid this by just copying the data into a heap buffer and keeping a permanent copy to avoid the crash. Updated all previous users of FileSpec::MemoryMapFileContentsIfLocal() in ObjectFile subclasses over to use the new FileSpec::MemoryMapFileContentsIfLocal() function. <rdar://problem/19470249> llvm-svn: 230283
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Host/common/FileSpec.cpp9
-rw-r--r--lldb/source/Host/posix/FileSystem.cpp12
-rw-r--r--lldb/source/Host/windows/FileSystem.cpp12
-rw-r--r--lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp4
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp12
-rw-r--r--lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp10
-rw-r--r--lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp4
7 files changed, 48 insertions, 15 deletions
diff --git a/lldb/source/Host/common/FileSpec.cpp b/lldb/source/Host/common/FileSpec.cpp
index 6a6de53cd31..19f3b93f087 100644
--- a/lldb/source/Host/common/FileSpec.cpp
+++ b/lldb/source/Host/common/FileSpec.cpp
@@ -852,6 +852,15 @@ FileSpec::MemoryMapFileContents(off_t file_offset, size_t file_size) const
return data_sp;
}
+DataBufferSP
+FileSpec::MemoryMapFileContentsIfLocal(off_t file_offset, size_t file_size) const
+{
+ if (FileSystem::IsLocal(*this))
+ return MemoryMapFileContents(file_offset, file_size);
+ else
+ return ReadFileContents(file_offset, file_size, NULL);
+}
+
//------------------------------------------------------------------
// Return the size in bytes that this object takes in memory. This
diff --git a/lldb/source/Host/posix/FileSystem.cpp b/lldb/source/Host/posix/FileSystem.cpp
index b55b01b4569..b8a455727ae 100644
--- a/lldb/source/Host/posix/FileSystem.cpp
+++ b/lldb/source/Host/posix/FileSystem.cpp
@@ -10,6 +10,8 @@
#include "lldb/Host/FileSystem.h"
// C includes
+#include <sys/mount.h>
+#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -172,3 +174,13 @@ FileSystem::Readlink(const char *path, char *buf, size_t buf_len)
error.SetErrorString("'buf' buffer is too small to contain link contents");
return error;
}
+
+bool
+FileSystem::IsLocal(const FileSpec &spec)
+{
+ struct statfs statfs_info;
+ std::string path (spec.GetPath());
+ if (statfs(path.c_str(), &statfs_info) == 0)
+ return (statfs_info.f_flags & MNT_LOCAL) != 0;
+ return false;
+}
diff --git a/lldb/source/Host/windows/FileSystem.cpp b/lldb/source/Host/windows/FileSystem.cpp
index a58ddef13ad..f1926357b55 100644
--- a/lldb/source/Host/windows/FileSystem.cpp
+++ b/lldb/source/Host/windows/FileSystem.cpp
@@ -138,3 +138,15 @@ FileSystem::Readlink(const char *path, char *buf, size_t buf_len)
::CloseHandle(h);
return error;
}
+
+bool
+FileSystem::IsLocal(const FileSpec &spec)
+{
+ if (spec)
+ {
+ // TODO: return true if the file is on a locally mounted file system
+ return true;
+ }
+
+ return false;
+}
diff --git a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index 1e2a0c721ff..87bf75321ed 100644
--- a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -364,7 +364,7 @@ ObjectContainerBSDArchive::CreateInstance
// Map the entire .a file to be sure that we don't lose any data if the file
// gets updated by a new build while this .a file is being used for debugging
- DataBufferSP archive_data_sp (file->MemoryMapFileContents(file_offset, length));
+ DataBufferSP archive_data_sp (file->MemoryMapFileContentsIfLocal(file_offset, length));
lldb::offset_t archive_data_offset = 0;
Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file,
@@ -570,7 +570,7 @@ ObjectContainerBSDArchive::GetModuleSpecifications (const lldb_private::FileSpec
if (!archive_sp)
{
set_archive_arch = true;
- DataBufferSP data_sp (file.MemoryMapFileContents(file_offset, file_size));
+ DataBufferSP data_sp (file.MemoryMapFileContentsIfLocal(file_offset, file_size));
data.SetData (data_sp, 0, data_sp->GetByteSize());
archive_sp = Archive::ParseAndCacheArchiveForFile(file, ArchSpec(), file_mod_time, file_offset, data);
}
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index bf466c7ee9b..1b49aab0df1 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -365,7 +365,7 @@ ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp,
{
if (!data_sp)
{
- data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
data_offset = 0;
}
@@ -376,7 +376,7 @@ ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp,
{
// Update the data to contain the entire file if it doesn't already
if (data_sp->GetByteSize() < length) {
- data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
data_offset = 0;
magic = data_sp->GetBytes();
}
@@ -636,7 +636,7 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
size_t section_header_end = header.e_shoff + header.e_shnum * header.e_shentsize;
if (section_header_end > data_sp->GetByteSize())
{
- data_sp = file.MemoryMapFileContents (file_offset, section_header_end);
+ data_sp = file.MemoryMapFileContentsIfLocal (file_offset, section_header_end);
data.SetData(data_sp);
}
@@ -678,7 +678,7 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
size_t program_headers_end = header.e_phoff + header.e_phnum * header.e_phentsize;
if (program_headers_end > data_sp->GetByteSize())
{
- data_sp = file.MemoryMapFileContents(file_offset, program_headers_end);
+ data_sp = file.MemoryMapFileContentsIfLocal(file_offset, program_headers_end);
data.SetData(data_sp);
}
ProgramHeaderColl program_headers;
@@ -693,7 +693,7 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
if (segment_data_end > data_sp->GetByteSize())
{
- data_sp = file.MemoryMapFileContents(file_offset, segment_data_end);
+ data_sp = file.MemoryMapFileContentsIfLocal(file_offset, segment_data_end);
data.SetData(data_sp);
}
@@ -702,7 +702,7 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
else
{
// Need to map entire file into memory to calculate the crc.
- data_sp = file.MemoryMapFileContents (file_offset, SIZE_MAX);
+ data_sp = file.MemoryMapFileContentsIfLocal (file_offset, SIZE_MAX);
data.SetData(data_sp);
gnu_debuglink_crc = calc_gnu_debuglink_crc32 (data.GetDataStart(), data.GetByteSize());
}
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index ec14450c4b8..7b49daa59ab 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -931,7 +931,7 @@ ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp,
{
if (!data_sp)
{
- data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
data_offset = 0;
}
@@ -940,7 +940,7 @@ ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp,
// Update the data to contain the entire file if it doesn't already
if (data_sp->GetByteSize() < length)
{
- data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
data_offset = 0;
}
std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, data_offset, file, file_offset, length));
@@ -2650,7 +2650,7 @@ ObjectFileMachO::ParseSymtab ()
// Save some VM space, do not map the entire cache in one shot.
DataBufferSP dsc_data_sp;
- dsc_data_sp = dsc_filespec.MemoryMapFileContents(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
+ dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
if (dsc_data_sp)
{
@@ -2704,7 +2704,7 @@ ObjectFileMachO::ParseSymtab ()
if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v0))
{
- DataBufferSP dsc_mapping_info_data_sp = dsc_filespec.MemoryMapFileContents(mappingOffset, sizeof (struct lldb_copy_dyld_cache_mapping_info));
+ DataBufferSP dsc_mapping_info_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(mappingOffset, sizeof (struct lldb_copy_dyld_cache_mapping_info));
DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size);
offset = 0;
@@ -2721,7 +2721,7 @@ ObjectFileMachO::ParseSymtab ()
if (localSymbolsOffset && localSymbolsSize)
{
// Map the local symbols
- if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContents(localSymbolsOffset, localSymbolsSize))
+ if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(localSymbolsOffset, localSymbolsSize))
{
DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 6defd643a43..5f7935e1275 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -76,7 +76,7 @@ ObjectFilePECOFF::CreateInstance (const lldb::ModuleSP &module_sp,
{
if (!data_sp)
{
- data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
data_offset = 0;
}
@@ -84,7 +84,7 @@ ObjectFilePECOFF::CreateInstance (const lldb::ModuleSP &module_sp,
{
// Update the data to contain the entire file if it doesn't already
if (data_sp->GetByteSize() < length)
- data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
std::unique_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF (module_sp, data_sp, data_offset, file, file_offset, length));
if (objfile_ap.get() && objfile_ap->ParseHeader())
return objfile_ap.release();
OpenPOWER on IntegriCloud