<rdar://problem/12687087>
Emit an error when using "target modules add PATH" where PATH points to a debug info only (dSYM) file. Also added a "--uuid" option for "target modules add --uuid UUID" to locate and load a module by UUID if the host supports it. llvm-svn: 168949
This commit is contained in:
parent
929a94f026
commit
50a24bd358
|
@ -2442,14 +2442,23 @@ public:
|
|||
CommandObjectParsed (interpreter,
|
||||
"target modules add",
|
||||
"Add a new module to the current target's modules.",
|
||||
"target modules add [<module>]")
|
||||
"target modules add [<module>]"),
|
||||
m_option_group (interpreter)
|
||||
{
|
||||
m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
|
||||
m_option_group.Finalize();
|
||||
}
|
||||
|
||||
virtual
|
||||
~CommandObjectTargetModulesAdd ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual Options *
|
||||
GetOptions ()
|
||||
{
|
||||
return &m_option_group;
|
||||
}
|
||||
|
||||
int
|
||||
HandleArgumentCompletion (Args &input,
|
||||
|
@ -2476,6 +2485,11 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
|
||||
OptionGroupOptions m_option_group;
|
||||
OptionGroupUUID m_uuid_option_group;
|
||||
|
||||
|
||||
virtual bool
|
||||
DoExecute (Args& args,
|
||||
CommandReturnObject &result)
|
||||
|
@ -2492,9 +2506,66 @@ protected:
|
|||
const size_t argc = args.GetArgumentCount();
|
||||
if (argc == 0)
|
||||
{
|
||||
result.AppendError ("one or more executable image paths must be specified");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
|
||||
{
|
||||
// We are given a UUID only, go locate the file
|
||||
ModuleSpec module_spec;
|
||||
module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
|
||||
if (Symbols::DownloadObjectAndSymbolFile (module_spec))
|
||||
{
|
||||
ModuleSP module_sp (target->GetSharedModule (module_spec));
|
||||
if (module_sp)
|
||||
{
|
||||
result.SetStatus (eReturnStatusSuccessFinishResult);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamString strm;
|
||||
module_spec.GetUUID().Dump (&strm);
|
||||
if (module_spec.GetFileSpec())
|
||||
{
|
||||
if (module_spec.GetSymbolFileSpec())
|
||||
{
|
||||
result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s/%s and symbol file %s/%s",
|
||||
strm.GetString().c_str(),
|
||||
module_spec.GetFileSpec().GetDirectory().GetCString(),
|
||||
module_spec.GetFileSpec().GetFilename().GetCString(),
|
||||
module_spec.GetSymbolFileSpec().GetDirectory().GetCString(),
|
||||
module_spec.GetSymbolFileSpec().GetFilename().GetCString());
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s/%s",
|
||||
strm.GetString().c_str(),
|
||||
module_spec.GetFileSpec().GetDirectory().GetCString(),
|
||||
module_spec.GetFileSpec().GetFilename().GetCString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s",
|
||||
strm.GetString().c_str());
|
||||
}
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamString strm;
|
||||
module_spec.GetUUID().Dump (&strm);
|
||||
result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError ("one or more executable image paths must be specified");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2507,10 +2578,18 @@ protected:
|
|||
if (file_spec.Exists())
|
||||
{
|
||||
ModuleSpec module_spec (file_spec);
|
||||
ModuleSP module_sp (target->GetSharedModule (module_spec));
|
||||
if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
|
||||
module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
|
||||
|
||||
Error error;
|
||||
ModuleSP module_sp (target->GetSharedModule (module_spec, &error));
|
||||
if (!module_sp)
|
||||
{
|
||||
result.AppendError ("one or more executable image paths must be specified");
|
||||
const char *error_cstr = error.AsCString();
|
||||
if (error_cstr)
|
||||
result.AppendError (error_cstr);
|
||||
else
|
||||
result.AppendErrorWithFormat ("unsupported module: %s", path);
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1460,38 +1460,63 @@ Target::GetSharedModule (const ModuleSpec &module_spec, Error *error_ptr)
|
|||
// module in the list already, and if there was, let's remove it.
|
||||
if (module_sp)
|
||||
{
|
||||
// GetSharedModule is not guaranteed to find the old shared module, for instance
|
||||
// in the common case where you pass in the UUID, it is only going to find the one
|
||||
// module matching the UUID. In fact, it has no good way to know what the "old module"
|
||||
// relevant to this target is, since there might be many copies of a module with this file spec
|
||||
// in various running debug sessions, but only one of them will belong to this target.
|
||||
// So let's remove the UUID from the module list, and look in the target's module list.
|
||||
// Only do this if there is SOMETHING else in the module spec...
|
||||
if (!old_module_sp)
|
||||
ObjectFile *objfile = module_sp->GetObjectFile();
|
||||
if (objfile)
|
||||
{
|
||||
if (module_spec.GetUUID().IsValid() && !module_spec.GetFileSpec().GetFilename().IsEmpty() && !module_spec.GetFileSpec().GetDirectory().IsEmpty())
|
||||
switch (objfile->GetType())
|
||||
{
|
||||
ModuleSpec module_spec_copy(module_spec.GetFileSpec());
|
||||
module_spec_copy.GetUUID().Clear();
|
||||
|
||||
ModuleList found_modules;
|
||||
size_t num_found = m_images.FindModules (module_spec_copy, found_modules);
|
||||
if (num_found == 1)
|
||||
case ObjectFile::eTypeCoreFile: /// A core file that has a checkpoint of a program's execution state
|
||||
case ObjectFile::eTypeExecutable: /// A normal executable
|
||||
case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker executable
|
||||
case ObjectFile::eTypeObjectFile: /// An intermediate object file
|
||||
case ObjectFile::eTypeSharedLibrary: /// A shared library that can be used during execution
|
||||
break;
|
||||
case ObjectFile::eTypeDebugInfo: /// An object file that contains only debug information
|
||||
if (error_ptr)
|
||||
error_ptr->SetErrorString("debug info files aren't valid target modules, please specify an executable");
|
||||
return ModuleSP();
|
||||
case ObjectFile::eTypeStubLibrary: /// A library that can be linked against but not used for execution
|
||||
if (error_ptr)
|
||||
error_ptr->SetErrorString("stub libraries aren't valid target modules, please specify an executable");
|
||||
return ModuleSP();
|
||||
default:
|
||||
if (error_ptr)
|
||||
error_ptr->SetErrorString("unsupported file type, please specify an executable");
|
||||
return ModuleSP();
|
||||
}
|
||||
// GetSharedModule is not guaranteed to find the old shared module, for instance
|
||||
// in the common case where you pass in the UUID, it is only going to find the one
|
||||
// module matching the UUID. In fact, it has no good way to know what the "old module"
|
||||
// relevant to this target is, since there might be many copies of a module with this file spec
|
||||
// in various running debug sessions, but only one of them will belong to this target.
|
||||
// So let's remove the UUID from the module list, and look in the target's module list.
|
||||
// Only do this if there is SOMETHING else in the module spec...
|
||||
if (!old_module_sp)
|
||||
{
|
||||
if (module_spec.GetUUID().IsValid() && !module_spec.GetFileSpec().GetFilename().IsEmpty() && !module_spec.GetFileSpec().GetDirectory().IsEmpty())
|
||||
{
|
||||
old_module_sp = found_modules.GetModuleAtIndex(0);
|
||||
ModuleSpec module_spec_copy(module_spec.GetFileSpec());
|
||||
module_spec_copy.GetUUID().Clear();
|
||||
|
||||
ModuleList found_modules;
|
||||
size_t num_found = m_images.FindModules (module_spec_copy, found_modules);
|
||||
if (num_found == 1)
|
||||
{
|
||||
old_module_sp = found_modules.GetModuleAtIndex(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (old_module_sp && m_images.GetIndexForModule (old_module_sp.get()) != LLDB_INVALID_INDEX32)
|
||||
{
|
||||
m_images.ReplaceModule(old_module_sp, module_sp);
|
||||
Module *old_module_ptr = old_module_sp.get();
|
||||
old_module_sp.reset();
|
||||
ModuleList::RemoveSharedModuleIfOrphaned (old_module_ptr);
|
||||
}
|
||||
else
|
||||
m_images.Append(module_sp);
|
||||
}
|
||||
|
||||
if (old_module_sp && m_images.GetIndexForModule (old_module_sp.get()) != LLDB_INVALID_INDEX32)
|
||||
{
|
||||
m_images.ReplaceModule(old_module_sp, module_sp);
|
||||
Module *old_module_ptr = old_module_sp.get();
|
||||
old_module_sp.reset();
|
||||
ModuleList::RemoveSharedModuleIfOrphaned (old_module_ptr);
|
||||
}
|
||||
else
|
||||
m_images.Append(module_sp);
|
||||
}
|
||||
}
|
||||
if (error_ptr)
|
||||
|
|
Loading…
Reference in New Issue