From 5acc12550f8d94cad2b5498a4842a5079c69ac04 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Fri, 15 Aug 2014 18:00:45 +0000 Subject: [PATCH] Don't crash when specifying a core file that isn't readable. Fixes include: 1 - added new FileSpec method: bool FileSpec::Readable() 2 - detect when an executable is not readable and give an appropriate error for: (lldb) file /tmp/unreadablefile 3 - detect when a core file is not readable and give an appropriate error 4 - detect when a specified core file doesn't exist and give an appropriate error llvm-svn: 215741 --- lldb/include/lldb/Host/FileSpec.h | 9 ++++++ lldb/source/Commands/CommandObjectTarget.cpp | 28 ++++++++++++++++++- lldb/source/Host/common/FileSpec.cpp | 9 ++++++ .../Platform/MacOSX/PlatformDarwin.cpp | 28 ++++++++++++++----- .../Process/mach-core/ProcessMachCore.cpp | 2 +- 5 files changed, 67 insertions(+), 9 deletions(-) diff --git a/lldb/include/lldb/Host/FileSpec.h b/lldb/include/lldb/Host/FileSpec.h index b8166914eb27..ef73bb2ede0f 100644 --- a/lldb/include/lldb/Host/FileSpec.h +++ b/lldb/include/lldb/Host/FileSpec.h @@ -270,6 +270,15 @@ public: bool Exists () const; + //------------------------------------------------------------------ + /// Check if a file is readable by the current user + /// + /// @return + /// \b true if the file exists on disk and is readable, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + Readable () const; //------------------------------------------------------------------ /// Expanded existence test. diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 95eec4dd4bcf..c5e8826cc577 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -230,12 +230,38 @@ protected: FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue()); FileSpec remote_file (m_remote_file.GetOptionValue().GetCurrentValue()); + if (core_file) + { + if (!core_file.Exists()) + { + result.AppendErrorWithFormat("core file '%s' doesn't exist", core_file.GetPath().c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + + } + if (!core_file.Readable()) + { + result.AppendErrorWithFormat("core file '%s' is not readable", core_file.GetPath().c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + if (argc == 1 || core_file || remote_file) { FileSpec symfile (m_symbol_file.GetOptionValue().GetCurrentValue()); if (symfile) { - if (!symfile.Exists()) + if (symfile.Exists()) + { + if (!symfile.Readable()) + { + result.AppendErrorWithFormat("symbol file '%s' is not readable", core_file.GetPath().c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + else { char symfile_path[PATH_MAX]; symfile.GetPath(symfile_path, sizeof(symfile_path)); diff --git a/lldb/source/Host/common/FileSpec.cpp b/lldb/source/Host/common/FileSpec.cpp index 9ce4e99d7693..56179a38f365 100644 --- a/lldb/source/Host/common/FileSpec.cpp +++ b/lldb/source/Host/common/FileSpec.cpp @@ -482,6 +482,15 @@ FileSpec::Exists () const return GetFileStats (this, &file_stats); } +bool +FileSpec::Readable () const +{ + const uint32_t permissions = GetPermissions(); + if (permissions & eFilePermissionsEveryoneR) + return true; + return false; +} + bool FileSpec::ResolveExecutableLocation () { diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index 135aa5e40dab..02854d541d56 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -139,7 +139,11 @@ PlatformDarwin::ResolveExecutable (const FileSpec &exe_file, { // If we have "ls" as the exe_file, resolve the executable loation based on // the current path variables - if (!resolved_exe_file.Exists()) + if (resolved_exe_file.Exists()) + { + + } + else { exe_file.GetPath (exe_path, sizeof(exe_path)); resolved_exe_file.SetFile(exe_path, true); @@ -155,8 +159,11 @@ PlatformDarwin::ResolveExecutable (const FileSpec &exe_file, error.Clear(); else { - exe_file.GetPath (exe_path, sizeof(exe_path)); - error.SetErrorStringWithFormat ("unable to find executable for '%s'", exe_path); + const uint32_t permissions = resolved_exe_file.GetPermissions(); + if (permissions && (permissions & eFilePermissionsEveryoneR) == 0) + error.SetErrorStringWithFormat ("executable '%s' is not readable", resolved_exe_file.GetPath().c_str()); + else + error.SetErrorStringWithFormat ("unable to find executable for '%s'", resolved_exe_file.GetPath().c_str()); } } else @@ -231,10 +238,17 @@ PlatformDarwin::ResolveExecutable (const FileSpec &exe_file, if (error.Fail() || !exe_module_sp) { - error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", - exe_file.GetPath().c_str(), - GetPluginName().GetCString(), - arch_names.GetString().c_str()); + if (exe_file.Readable()) + { + error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", + exe_file.GetPath().c_str(), + GetPluginName().GetCString(), + arch_names.GetString().c_str()); + } + else + { + error.SetErrorStringWithFormat("'%s' is not readable", exe_file.GetPath().c_str()); + } } } } diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index ca99175ce9f7..8c44838471aa 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -69,7 +69,7 @@ ProcessMachCore::CreateInstance (Target &target, Listener &listener, const FileS { const size_t header_size = sizeof(llvm::MachO::mach_header); lldb::DataBufferSP data_sp (crash_file->ReadFileContents(0, header_size)); - if (data_sp->GetByteSize() == header_size) + if (data_sp && data_sp->GetByteSize() == header_size) { DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);