return m_event_handler_thread.IsJoinable();
}
+ // This is for use in the command interpreter, when you either want the selected target, or if no target
+ // is present you want to prime the dummy target with entities that will be copied over to new targets.
+ Target *GetSelectedOrDummyTarget();
+ Target *GetDummyTarget();
+
protected:
friend class CommandInterpreter;
lldb::StreamFileSP m_error_file_sp;
TerminalState m_terminal_state;
TargetList m_target_list;
+
PlatformList m_platform_list;
Listener m_listener;
std::unique_ptr<SourceManager> m_source_manager_ap; // This is a scratch source manager that we return if we have no targets.
static lldb::DataBufferSP
GetAuxvData (lldb::pid_t pid);
- static lldb::TargetSP
- GetDummyTarget (Debugger &debugger);
-
static bool
OpenFileInExternalEditor (const FileSpec &file_spec,
uint32_t line_no);
return "invalid frame, no registers";
}
+ // This is for use in the command interpreter, when you either want the selected target, or if no target
+ // is present you want to prime the dummy target with entities that will be copied over to new targets.
+ Target *GetSelectedOrDummyTarget();
+ Target *GetDummyTarget();
+
//------------------------------------------------------------------
/// Check the command to make sure anything required by this
/// command is available.
//------------------------------------------------------------------
Target (Debugger &debugger,
const ArchSpec &target_arch,
- const lldb::PlatformSP &platform_sp);
+ const lldb::PlatformSP &platform_sp,
+ bool is_dummy_target);
// Helper function.
bool
ProcessIsValid ();
+ // Copy breakpoints, stop hooks and so forth from the dummy target:
+ void
+ PrimeFromDummyTarget(Target *dummy_target);
+
public:
~Target();
lldb::user_id_t m_stop_hook_next_id;
bool m_valid;
bool m_suppress_stop_hooks;
+ bool m_is_dummy_target;
static void
ImageSearchPathsChanged (const PathMappingList &path_list,
lldb::TargetSP
GetSelectedTarget ();
-
protected:
typedef std::vector<lldb::TargetSP> collection;
//------------------------------------------------------------------
// Member variables.
//------------------------------------------------------------------
collection m_target_list;
+ lldb::TargetSP m_dummy_target_sp;
mutable Mutex m_target_list_mutex;
uint32_t m_selected_target_idx;
private:
+ lldb::TargetSP
+ GetDummyTarget (lldb_private::Debugger &debugger);
+
+ Error
+ CreateDummyTarget (Debugger &debugger,
+ const char *specified_arch_name,
+ lldb::TargetSP &target_sp);
+
+ Error
+ CreateTargetInternal (Debugger &debugger,
+ const char *user_exe_path,
+ const char *triple_cstr,
+ bool get_dependent_files,
+ const OptionGroupPlatform *platform_options,
+ lldb::TargetSP &target_sp,
+ bool is_dummy_target);
+
+ Error
+ CreateTargetInternal (Debugger &debugger,
+ const char *user_exe_path,
+ const ArchSpec& arch,
+ bool get_dependent_modules,
+ lldb::PlatformSP &platform_sp,
+ lldb::TargetSP &target_sp,
+ bool is_dummy_target);
+
DISALLOW_COPY_AND_ASSIGN (TargetList);
};
DoExecute (Args& command,
CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ Target *target = GetSelectedOrDummyTarget();
+ if (target == nullptr)
{
result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
result.SetStatus (eReturnStatusFailed);
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target == NULL)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target == NULL)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target == NULL)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target == NULL)
{
result.AppendError ("Invalid target. No current target or breakpoints.");
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target == NULL)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target == NULL)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
Target *target = exe_ctx.GetTargetPtr();
if (!target)
- target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
+ target = GetDummyTarget();
if (target)
{
{
m_stop_hook_sp.reset();
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target)
{
Target::StopHookSP new_hook_sp = target->CreateStopHook();
bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target)
{
// FIXME: see if we can use the breakpoint id style parser?
bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target)
{
// FIXME: see if we can use the breakpoint id style parser?
bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (!target)
{
result.AppendError ("invalid target\n");
}
}
+Target *
+Debugger::GetDummyTarget()
+{
+ return m_target_list.GetDummyTarget (*this).get();
+}
+
+Target *
+Debugger::GetSelectedOrDummyTarget()
+{
+ Target *return_target = m_target_list.GetSelectedTarget().get();
+ if (return_target)
+ return return_target;
+
+ return GetDummyTarget();
+}
}
#endif
-lldb::TargetSP
-Host::GetDummyTarget (lldb_private::Debugger &debugger)
-{
- static TargetSP g_dummy_target_sp;
-
- // FIXME: Maybe the dummy target should be per-Debugger
- if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid())
- {
- ArchSpec arch(Target::GetDefaultArchitecture());
- if (!arch.IsValid())
- arch = HostInfo::GetArchitecture();
- Error err = debugger.GetTargetList().CreateTarget(debugger,
- NULL,
- arch.GetTriple().getTriple().c_str(),
- false,
- NULL,
- g_dummy_target_sp);
- }
-
- return g_dummy_target_sp;
-}
-
struct ShellInfo
{
ShellInfo () :
// Get a dummy target to allow for calculator mode while processing backticks.
// This also helps break the infinite loop caused when target is null.
if (!target)
- target = Host::GetDummyTarget(GetDebugger()).get();
+ target = m_debugger.GetDummyTarget();
if (target)
{
ValueObjectSP expr_result_valobj_sp;
return nullptr;
}
+Target *
+CommandObject::GetDummyTarget()
+{
+ return m_interpreter.GetDebugger().GetDummyTarget();
+}
+
+Target *
+CommandObject::GetSelectedOrDummyTarget()
+{
+ return m_interpreter.GetDebugger().GetSelectedOrDummyTarget();
+}
+
bool
CommandObjectParsed::Execute (const char *args_string, CommandReturnObject &result)
{
//----------------------------------------------------------------------
// Target constructor
//----------------------------------------------------------------------
-Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp) :
+Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp, bool is_dummy_target) :
TargetProperties (this),
Broadcaster (&debugger, Target::GetStaticBroadcasterClass().AsCString()),
ExecutionContextScope (),
m_stop_hooks (),
m_stop_hook_next_id (0),
m_valid (true),
- m_suppress_stop_hooks (false)
+ m_suppress_stop_hooks (false),
+ m_is_dummy_target(is_dummy_target)
+
{
SetEventName (eBroadcastBitBreakpointChanged, "breakpoint-changed");
SetEventName (eBroadcastBitModulesLoaded, "modules-loaded");
CheckInWithManager();
+ if (!m_is_dummy_target)
+ PrimeFromDummyTarget(m_debugger.GetDummyTarget());
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
log->Printf ("%p Target::Target()", static_cast<void*>(this));
}
}
+void
+Target::PrimeFromDummyTarget(Target *target)
+{
+ if (!target)
+ return;
+
+ m_stop_hooks = target->m_stop_hooks;
+
+}
+
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
#include "lldb/Core/State.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Symbol/ObjectFile.h"
const OptionGroupPlatform *platform_options,
TargetSP &target_sp)
{
+ return CreateTargetInternal (debugger,
+ user_exe_path,
+ triple_cstr,
+ get_dependent_files,
+ platform_options,
+ target_sp,
+ false);
+}
+
+Error
+TargetList::CreateTarget (Debugger &debugger,
+ const char *user_exe_path,
+ const ArchSpec& specified_arch,
+ bool get_dependent_files,
+ PlatformSP &platform_sp,
+ TargetSP &target_sp)
+{
+ return CreateTargetInternal (debugger,
+ user_exe_path,
+ specified_arch,
+ get_dependent_files,
+ platform_sp,
+ target_sp,
+ false);
+}
+
+Error
+TargetList::CreateTargetInternal (Debugger &debugger,
+ const char *user_exe_path,
+ const char *triple_cstr,
+ bool get_dependent_files,
+ const OptionGroupPlatform *platform_options,
+ TargetSP &target_sp,
+ bool is_dummy_target)
+{
Error error;
PlatformSP platform_sp;
if (!platform_arch.IsValid())
platform_arch = arch;
- error = TargetList::CreateTarget (debugger,
- user_exe_path,
- platform_arch,
- get_dependent_files,
- platform_sp,
- target_sp);
+ error = TargetList::CreateTargetInternal (debugger,
+ user_exe_path,
+ platform_arch,
+ get_dependent_files,
+ platform_sp,
+ target_sp,
+ is_dummy_target);
return error;
}
+lldb::TargetSP
+TargetList::GetDummyTarget (lldb_private::Debugger &debugger)
+{
+ // FIXME: Maybe the dummy target should be per-Debugger
+ if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid())
+ {
+ ArchSpec arch(Target::GetDefaultArchitecture());
+ if (!arch.IsValid())
+ arch = HostInfo::GetArchitecture();
+ Error err = CreateDummyTarget(debugger,
+ arch.GetTriple().getTriple().c_str(),
+ m_dummy_target_sp);
+ }
+
+ return m_dummy_target_sp;
+}
+
Error
-TargetList::CreateTarget (Debugger &debugger,
- const char *user_exe_path,
- const ArchSpec& specified_arch,
- bool get_dependent_files,
- PlatformSP &platform_sp,
- TargetSP &target_sp)
+TargetList::CreateDummyTarget (Debugger &debugger,
+ const char *specified_arch_name,
+ lldb::TargetSP &target_sp)
{
+ PlatformSP host_platform_sp(Platform::GetHostPlatform());
+ return CreateTargetInternal (debugger,
+ (const char *) nullptr,
+ specified_arch_name,
+ false,
+ (const OptionGroupPlatform *) nullptr,
+ target_sp,
+ true);
+}
+
+Error
+TargetList::CreateTargetInternal (Debugger &debugger,
+ const char *user_exe_path,
+ const ArchSpec& specified_arch,
+ bool get_dependent_files,
+ lldb::PlatformSP &platform_sp,
+ lldb::TargetSP &target_sp,
+ bool is_dummy_target)
+{
+
Timer scoped_timer (__PRETTY_FUNCTION__,
"TargetList::CreateTarget (file = '%s', arch = '%s')",
user_exe_path,
}
return error;
}
- target_sp.reset(new Target(debugger, arch, platform_sp));
+ target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target));
target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
if (user_exe_path_is_bundle)
exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path));
{
// No file was specified, just create an empty target with any arch
// if a valid arch was specified
- target_sp.reset(new Target(debugger, arch, platform_sp));
+ target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target));
}
if (target_sp)
file_dir.GetDirectory() = file.GetDirectory();
target_sp->GetExecutableSearchPaths ().Append (file_dir);
}
- Mutex::Locker locker(m_target_list_mutex);
- m_selected_target_idx = m_target_list.size();
- m_target_list.push_back(target_sp);
-
-
+
+ // Don't put the dummy target in the target list, it's held separately.
+ if (!is_dummy_target)
+ {
+ Mutex::Locker locker(m_target_list_mutex);
+ m_selected_target_idx = m_target_list.size();
+ m_target_list.push_back(target_sp);
+ }
+ else
+ {
+ m_dummy_target_sp = target_sp;
+ }
}
return error;