aboutsummaryrefslogtreecommitdiff
path: root/source/Target/Target.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Target/Target.cpp')
-rw-r--r--source/Target/Target.cpp127
1 files changed, 90 insertions, 37 deletions
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index e7816266b415..d2d0b5098555 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -94,12 +94,12 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::Plat
SetEventName (eBroadcastBitModulesUnloaded, "modules-unloaded");
SetEventName (eBroadcastBitWatchpointChanged, "watchpoint-changed");
SetEventName (eBroadcastBitSymbolsLoaded, "symbols-loaded");
-
+
CheckInWithManager();
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf ("%p Target::Target()", this);
+ log->Printf ("%p Target::Target()", static_cast<void*>(this));
if (m_arch.IsValid())
{
LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET, "Target::Target created with architecture %s (%s)", m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
@@ -113,7 +113,7 @@ Target::~Target()
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf ("%p Target::~Target()", this);
+ log->Printf ("%p Target::~Target()", static_cast<void*>(this));
DeleteCurrentProcess ();
}
@@ -486,9 +486,12 @@ Target::CreateFuncRegexBreakpoint (const FileSpecList *containingModules,
bool hardware)
{
SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
+ bool skip =
+ (skip_prologue == eLazyBoolCalculate) ? GetSkipPrologue()
+ : static_cast<bool>(skip_prologue);
BreakpointResolverSP resolver_sp(new BreakpointResolverName (NULL,
func_regex,
- skip_prologue == eLazyBoolCalculate ? GetSkipPrologue() : skip_prologue));
+ skip));
return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
}
@@ -635,7 +638,7 @@ Target::CreateWatchpoint(lldb::addr_t addr, size_t size, const ClangASTType *typ
if (!CheckIfWatchpointsExhausted(this, error))
{
if (!OptionGroupWatchpoint::IsWatchSizeSupported(size))
- error.SetErrorStringWithFormat("watch size of %zu is not supported", size);
+ error.SetErrorStringWithFormat("watch size of %" PRIu64 " is not supported", (uint64_t)size);
}
wp_sp.reset();
}
@@ -1010,10 +1013,10 @@ LoadScriptingResourceForModule (const ModuleSP &module_sp, Target *target)
target->GetDebugger().GetErrorFile()->Printf("unable to load scripting data for module %s - error reported was %s\n",
module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
error.AsCString());
- if (feedback_stream.GetSize())
- target->GetDebugger().GetErrorFile()->Printf("%s\n",
- feedback_stream.GetData());
}
+ if (feedback_stream.GetSize())
+ target->GetDebugger().GetErrorFile()->Printf("%s\n",
+ feedback_stream.GetData());
}
void
@@ -1047,7 +1050,7 @@ Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
"Target::SetExecutableModule (executable = '%s')",
executable_sp->GetFileSpec().GetPath().c_str());
- m_images.Append(executable_sp); // The first image is our exectuable file
+ m_images.Append(executable_sp); // The first image is our executable file
// If we haven't set an architecture yet, reset our architecture based on what we found in the executable module.
if (!m_arch.IsValid())
@@ -1142,41 +1145,44 @@ void
Target::ModuleAdded (const ModuleList& module_list, const ModuleSP &module_sp)
{
// A module is being added to this target for the first time
- ModuleList my_module_list;
- my_module_list.Append(module_sp);
- LoadScriptingResourceForModule(module_sp, this);
- ModulesDidLoad (my_module_list);
+ if (m_valid)
+ {
+ ModuleList my_module_list;
+ my_module_list.Append(module_sp);
+ LoadScriptingResourceForModule(module_sp, this);
+ ModulesDidLoad (my_module_list);
+ }
}
void
Target::ModuleRemoved (const ModuleList& module_list, const ModuleSP &module_sp)
{
// A module is being added to this target for the first time
- ModuleList my_module_list;
- my_module_list.Append(module_sp);
- ModulesDidUnload (my_module_list, false);
+ if (m_valid)
+ {
+ ModuleList my_module_list;
+ my_module_list.Append(module_sp);
+ ModulesDidUnload (my_module_list, false);
+ }
}
void
Target::ModuleUpdated (const ModuleList& module_list, const ModuleSP &old_module_sp, const ModuleSP &new_module_sp)
{
// A module is replacing an already added module
- m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp, new_module_sp);
+ if (m_valid)
+ m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp, new_module_sp);
}
void
Target::ModulesDidLoad (ModuleList &module_list)
{
- if (module_list.GetSize())
+ if (m_valid && module_list.GetSize())
{
m_breakpoint_list.UpdateBreakpoints (module_list, true, false);
if (m_process_sp)
{
- SystemRuntime *sys_runtime = m_process_sp->GetSystemRuntime();
- if (sys_runtime)
- {
- sys_runtime->ModulesDidLoad (module_list);
- }
+ m_process_sp->ModulesDidLoad (module_list);
}
// TODO: make event data that packages up the module_list
BroadcastEvent (eBroadcastBitModulesLoaded, NULL);
@@ -1186,7 +1192,7 @@ Target::ModulesDidLoad (ModuleList &module_list)
void
Target::SymbolsDidLoad (ModuleList &module_list)
{
- if (module_list.GetSize())
+ if (m_valid && module_list.GetSize())
{
if (m_process_sp)
{
@@ -1206,7 +1212,7 @@ Target::SymbolsDidLoad (ModuleList &module_list)
void
Target::ModulesDidUnload (ModuleList &module_list, bool delete_locations)
{
- if (module_list.GetSize())
+ if (m_valid && module_list.GetSize())
{
m_breakpoint_list.UpdateBreakpoints (module_list, false, delete_locations);
// TODO: make event data that packages up the module_list
@@ -1255,7 +1261,7 @@ Target::ReadMemoryFromFileCache (const Address& addr, void *dst, size_t dst_len,
SectionSP section_sp (addr.GetSection());
if (section_sp)
{
- // If the contents of this section are encrypted, the on-disk file is unusuable. Read only from live memory.
+ // If the contents of this section are encrypted, the on-disk file is unusable. Read only from live memory.
if (section_sp->IsEncrypted())
{
error.SetErrorString("section is encrypted");
@@ -1320,7 +1326,7 @@ Target::ReadMemory (const Address& addr,
}
else
{
- // We have at least one section loaded. This can be becuase
+ // We have at least one section loaded. This can be because
// we have manually loaded some sections with "target modules load ..."
// or because we have have a live process that has sections loaded
// through the dynamic loader
@@ -1376,7 +1382,7 @@ Target::ReadMemory (const Address& addr,
}
// If the address is not section offset we have an address that
// doesn't resolve to any address in any currently loaded shared
- // libaries and we failed to read memory so there isn't anything
+ // libraries and we failed to read memory so there isn't anything
// more we can do. If it is section offset, we might be able to
// read cached memory from the object file.
if (!resolved_addr.IsSectionOffset())
@@ -1547,7 +1553,7 @@ Target::ReadPointerFromMemory (const Address& addr,
}
else
{
- // We have at least one section loaded. This can be becuase
+ // We have at least one section loaded. This can be because
// we have manually loaded some sections with "target modules load ..."
// or because we have have a live process that has sections loaded
// through the dynamic loader
@@ -1698,6 +1704,8 @@ Target::GetSharedModule (const ModuleSpec &module_spec, Error *error_ptr)
else
m_images.Append(module_sp);
}
+ else
+ module_sp.reset();
}
}
if (error_ptr)
@@ -1765,7 +1773,7 @@ Target::GetScratchClangASTContext(bool create_on_demand)
m_scratch_ast_context_ap.reset (new ClangASTContext(m_arch.GetTriple().str().c_str()));
m_scratch_ast_source_ap.reset (new ClangASTSource(shared_from_this()));
m_scratch_ast_source_ap->InstallASTContext(m_scratch_ast_context_ap->getASTContext());
- llvm::OwningPtr<clang::ExternalASTSource> proxy_ast_source(m_scratch_ast_source_ap->CreateProxy());
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(m_scratch_ast_source_ap->CreateProxy());
m_scratch_ast_context_ap->SetExternalSource(proxy_ast_source);
}
return m_scratch_ast_context_ap.get();
@@ -1850,7 +1858,7 @@ Target::GetTargetFromContexts (const ExecutionContext *exe_ctx_ptr, const Symbol
return target;
}
-ExecutionResults
+ExpressionResults
Target::EvaluateExpression
(
const char *expr_cstr,
@@ -1861,7 +1869,7 @@ Target::EvaluateExpression
{
result_valobj_sp.reset();
- ExecutionResults execution_results = eExecutionSetupError;
+ ExpressionResults execution_results = eExpressionSetupError;
if (expr_cstr == NULL || expr_cstr[0] == '\0')
return execution_results;
@@ -1896,7 +1904,7 @@ Target::EvaluateExpression
if (persistent_var_sp)
{
result_valobj_sp = persistent_var_sp->GetValueObject ();
- execution_results = eExecutionCompleted;
+ execution_results = eExpressionCompleted;
}
else
{
@@ -2363,7 +2371,8 @@ Target::Launch (Listener &listener, ProcessLaunchInfo &launch_info)
if (!launch_info.GetArchitecture().IsValid())
launch_info.GetArchitecture() = GetArchitecture();
-
+
+ // If we're not already connected to the process, and if we have a platform that can launch a process for debugging, go ahead and do that here.
if (state != eStateConnected && platform_sp && platform_sp->CanDebugProcess ())
{
m_process_sp = GetPlatform()->DebugProcess (launch_info,
@@ -2380,10 +2389,12 @@ Target::Launch (Listener &listener, ProcessLaunchInfo &launch_info)
}
else
{
+ // Use a Process plugin to construct the process.
const char *plugin_name = launch_info.GetProcessPluginName();
CreateProcess (listener, plugin_name, NULL);
}
-
+
+ // Since we didn't have a platform launch the process, launch it here.
if (m_process_sp)
error = m_process_sp->Launch (launch_info);
}
@@ -2409,9 +2420,14 @@ Target::Launch (Listener &listener, ProcessLaunchInfo &launch_info)
m_process_sp->RestoreProcessEvents ();
error = m_process_sp->PrivateResume();
-
+
if (error.Success())
{
+ // there is a race condition where this thread will return up the call stack to the main command
+ // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
+ // a chance to call PushProcessIOHandler()
+ m_process_sp->SyncIOHandler(2000);
+
if (synchronous_execution)
{
state = m_process_sp->WaitForProcessToStop (NULL, NULL, true, hijack_listener_sp.get());
@@ -2429,6 +2445,27 @@ Target::Launch (Listener &listener, ProcessLaunchInfo &launch_info)
error = error2;
}
}
+ else if (state == eStateExited)
+ {
+ bool with_shell = launch_info.GetShell();
+ const int exit_status = m_process_sp->GetExitStatus();
+ const char *exit_desc = m_process_sp->GetExitDescription();
+#define LAUNCH_SHELL_MESSAGE "\n'r' and 'run' are aliases that default to launching through a shell.\nTry launching without going through a shell by using 'process launch'."
+ if (exit_desc && exit_desc[0])
+ {
+ if (with_shell)
+ error.SetErrorStringWithFormat ("process exited with status %i (%s)" LAUNCH_SHELL_MESSAGE, exit_status, exit_desc);
+ else
+ error.SetErrorStringWithFormat ("process exited with status %i (%s)", exit_status, exit_desc);
+ }
+ else
+ {
+ if (with_shell)
+ error.SetErrorStringWithFormat ("process exited with status %i" LAUNCH_SHELL_MESSAGE, exit_status);
+ else
+ error.SetErrorStringWithFormat ("process exited with status %i", exit_status);
+ }
+ }
else
{
error.SetErrorStringWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
@@ -2616,6 +2653,7 @@ g_properties[] =
{ "input-path" , OptionValue::eTypeFileSpec , false, 0 , NULL, NULL, "The file/path to be used by the executable program for reading its standard input." },
{ "output-path" , OptionValue::eTypeFileSpec , false, 0 , NULL, NULL, "The file/path to be used by the executable program for writing its standard output." },
{ "error-path" , OptionValue::eTypeFileSpec , false, 0 , NULL, NULL, "The file/path to be used by the executable program for writing its standard error." },
+ { "detach-on-error" , OptionValue::eTypeBoolean , false, true , NULL, NULL, "debugserver will detach (rather than killing) a process if it loses connection with lldb." },
{ "disable-aslr" , OptionValue::eTypeBoolean , false, true , NULL, NULL, "Disable Address Space Layout Randomization (ASLR)" },
{ "disable-stdio" , OptionValue::eTypeBoolean , false, false , NULL, NULL, "Disable stdin/stdout for process (e.g. for a GUI application)" },
{ "inline-breakpoint-strategy" , OptionValue::eTypeEnum , false, eInlineBreakpointsHeaders , NULL, g_inline_breakpoint_enums, "The strategy to use when settings breakpoints by file and line. "
@@ -2662,6 +2700,7 @@ enum
ePropertyInputPath,
ePropertyOutputPath,
ePropertyErrorPath,
+ ePropertyDetachOnError,
ePropertyDisableASLR,
ePropertyDisableSTDIO,
ePropertyInlineStrategy,
@@ -2699,7 +2738,7 @@ public:
virtual const Property *
GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
{
- // When gettings the value for a key from the target options, we will always
+ // When getting the value for a key from the target options, we will always
// try and grab the setting from the current target if there is one. Else we just
// use the one from this instance.
if (idx == ePropertyEnvVars)
@@ -2845,6 +2884,20 @@ TargetProperties::SetDisableASLR (bool b)
}
bool
+TargetProperties::GetDetachOnError () const
+{
+ const uint32_t idx = ePropertyDetachOnError;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+
+void
+TargetProperties::SetDetachOnError (bool b)
+{
+ const uint32_t idx = ePropertyDetachOnError;
+ m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
+}
+
+bool
TargetProperties::GetDisableSTDIO () const
{
const uint32_t idx = ePropertyDisableSTDIO;