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
    
<rdar://problem/17727734>

llvm-svn: 215741
This commit is contained in:
Greg Clayton 2014-08-15 18:00:45 +00:00
parent d2308ea5fd
commit 5acc12550f
5 changed files with 67 additions and 9 deletions

View File

@ -270,6 +270,15 @@ public:
bool bool
Exists () const; 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. /// Expanded existence test.

View File

@ -230,12 +230,38 @@ protected:
FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue()); FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue());
FileSpec remote_file (m_remote_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) if (argc == 1 || core_file || remote_file)
{ {
FileSpec symfile (m_symbol_file.GetOptionValue().GetCurrentValue()); FileSpec symfile (m_symbol_file.GetOptionValue().GetCurrentValue());
if (symfile) 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]; char symfile_path[PATH_MAX];
symfile.GetPath(symfile_path, sizeof(symfile_path)); symfile.GetPath(symfile_path, sizeof(symfile_path));

View File

@ -482,6 +482,15 @@ FileSpec::Exists () const
return GetFileStats (this, &file_stats); return GetFileStats (this, &file_stats);
} }
bool
FileSpec::Readable () const
{
const uint32_t permissions = GetPermissions();
if (permissions & eFilePermissionsEveryoneR)
return true;
return false;
}
bool bool
FileSpec::ResolveExecutableLocation () FileSpec::ResolveExecutableLocation ()
{ {

View File

@ -139,7 +139,11 @@ PlatformDarwin::ResolveExecutable (const FileSpec &exe_file,
{ {
// If we have "ls" as the exe_file, resolve the executable loation based on // If we have "ls" as the exe_file, resolve the executable loation based on
// the current path variables // the current path variables
if (!resolved_exe_file.Exists()) if (resolved_exe_file.Exists())
{
}
else
{ {
exe_file.GetPath (exe_path, sizeof(exe_path)); exe_file.GetPath (exe_path, sizeof(exe_path));
resolved_exe_file.SetFile(exe_path, true); resolved_exe_file.SetFile(exe_path, true);
@ -155,8 +159,11 @@ PlatformDarwin::ResolveExecutable (const FileSpec &exe_file,
error.Clear(); error.Clear();
else else
{ {
exe_file.GetPath (exe_path, sizeof(exe_path)); const uint32_t permissions = resolved_exe_file.GetPermissions();
error.SetErrorStringWithFormat ("unable to find executable for '%s'", exe_path); 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 else
@ -231,10 +238,17 @@ PlatformDarwin::ResolveExecutable (const FileSpec &exe_file,
if (error.Fail() || !exe_module_sp) if (error.Fail() || !exe_module_sp)
{ {
error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", if (exe_file.Readable())
exe_file.GetPath().c_str(), {
GetPluginName().GetCString(), error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
arch_names.GetString().c_str()); exe_file.GetPath().c_str(),
GetPluginName().GetCString(),
arch_names.GetString().c_str());
}
else
{
error.SetErrorStringWithFormat("'%s' is not readable", exe_file.GetPath().c_str());
}
} }
} }
} }

View File

@ -69,7 +69,7 @@ ProcessMachCore::CreateInstance (Target &target, Listener &listener, const FileS
{ {
const size_t header_size = sizeof(llvm::MachO::mach_header); const size_t header_size = sizeof(llvm::MachO::mach_header);
lldb::DataBufferSP data_sp (crash_file->ReadFileContents(0, header_size)); 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); DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);