aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Target/Process.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
commitb60736ec1405bb0a8dd40989f67ef4c93da068ab (patch)
tree5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /lldb/source/Target/Process.cpp
parentcfca06d7963fa0909f90483b42a6d7d194d01e08 (diff)
Diffstat (limited to 'lldb/source/Target/Process.cpp')
-rw-r--r--lldb/source/Target/Process.cpp281
1 files changed, 56 insertions, 225 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index d777a2713911..518a6934059e 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -278,6 +278,12 @@ std::chrono::seconds ProcessProperties::GetUtilityExpressionTimeout() const {
return std::chrono::seconds(value);
}
+bool ProcessProperties::GetSteppingRunsAllThreads() const {
+ const uint32_t idx = ePropertySteppingRunsAllThreads;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_process_properties[idx].default_uint_value != 0);
+}
+
bool ProcessProperties::GetOSPluginReportsAllThreads() const {
const bool fail_value = true;
const Property *exp_property =
@@ -301,179 +307,11 @@ void ProcessProperties::SetOSPluginReportsAllThreads(bool does_report) {
nullptr, ePropertyOSPluginReportsAllThreads, does_report);
}
-Status ProcessLaunchCommandOptions::SetOptionValue(
- uint32_t option_idx, llvm::StringRef option_arg,
- ExecutionContext *execution_context) {
- Status error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option) {
- case 's': // Stop at program entry point
- launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
- break;
-
- case 'i': // STDIN for read only
- {
- FileAction action;
- if (action.Open(STDIN_FILENO, FileSpec(option_arg), true, false))
- launch_info.AppendFileAction(action);
- break;
- }
-
- case 'o': // Open STDOUT for write only
- {
- FileAction action;
- if (action.Open(STDOUT_FILENO, FileSpec(option_arg), false, true))
- launch_info.AppendFileAction(action);
- break;
- }
-
- case 'e': // STDERR for write only
- {
- FileAction action;
- if (action.Open(STDERR_FILENO, FileSpec(option_arg), false, true))
- launch_info.AppendFileAction(action);
- break;
- }
-
- case 'p': // Process plug-in name
- launch_info.SetProcessPluginName(option_arg);
- break;
-
- case 'n': // Disable STDIO
- {
- FileAction action;
- const FileSpec dev_null(FileSystem::DEV_NULL);
- if (action.Open(STDIN_FILENO, dev_null, true, false))
- launch_info.AppendFileAction(action);
- if (action.Open(STDOUT_FILENO, dev_null, false, true))
- launch_info.AppendFileAction(action);
- if (action.Open(STDERR_FILENO, dev_null, false, true))
- launch_info.AppendFileAction(action);
- break;
- }
-
- case 'w':
- launch_info.SetWorkingDirectory(FileSpec(option_arg));
- break;
-
- case 't': // Open process in new terminal window
- launch_info.GetFlags().Set(eLaunchFlagLaunchInTTY);
- break;
-
- case 'a': {
- TargetSP target_sp =
- execution_context ? execution_context->GetTargetSP() : TargetSP();
- PlatformSP platform_sp =
- target_sp ? target_sp->GetPlatform() : PlatformSP();
- launch_info.GetArchitecture() =
- Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
- } break;
-
- case 'A': // Disable ASLR.
- {
- bool success;
- const bool disable_aslr_arg =
- OptionArgParser::ToBoolean(option_arg, true, &success);
- if (success)
- disable_aslr = disable_aslr_arg ? eLazyBoolYes : eLazyBoolNo;
- else
- error.SetErrorStringWithFormat(
- "Invalid boolean value for disable-aslr option: '%s'",
- option_arg.empty() ? "<null>" : option_arg.str().c_str());
- break;
- }
-
- case 'X': // shell expand args.
- {
- bool success;
- const bool expand_args =
- OptionArgParser::ToBoolean(option_arg, true, &success);
- if (success)
- launch_info.SetShellExpandArguments(expand_args);
- else
- error.SetErrorStringWithFormat(
- "Invalid boolean value for shell-expand-args option: '%s'",
- option_arg.empty() ? "<null>" : option_arg.str().c_str());
- break;
- }
-
- case 'c':
- if (!option_arg.empty())
- launch_info.SetShell(FileSpec(option_arg));
- else
- launch_info.SetShell(HostInfo::GetDefaultShell());
- break;
-
- case 'v':
- launch_info.GetEnvironment().insert(option_arg);
- break;
-
- default:
- error.SetErrorStringWithFormat("unrecognized short option character '%c'",
- short_option);
- break;
- }
- return error;
-}
-
-static constexpr OptionDefinition g_process_launch_options[] = {
- {LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', OptionParser::eNoArgument,
- nullptr, {}, 0, eArgTypeNone,
- "Stop at the entry point of the program when launching a process."},
- {LLDB_OPT_SET_ALL, false, "disable-aslr", 'A',
- OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
- "Set whether to disable address space layout randomization when launching "
- "a process."},
- {LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument,
- nullptr, {}, 0, eArgTypePlugin,
- "Name of the process plugin you want to use."},
- {LLDB_OPT_SET_ALL, false, "working-dir", 'w',
- OptionParser::eRequiredArgument, nullptr, {}, 0,
- eArgTypeDirectoryName,
- "Set the current working directory to <path> when running the inferior."},
- {LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument,
- nullptr, {}, 0, eArgTypeArchitecture,
- "Set the architecture for the process to launch when ambiguous."},
- {LLDB_OPT_SET_ALL, false, "environment", 'v',
- OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone,
- "Specify an environment variable name/value string (--environment "
- "NAME=VALUE). Can be specified multiple times for subsequent environment "
- "entries."},
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "shell", 'c',
- OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeFilename,
- "Run the process in a shell (not supported on all platforms)."},
-
- {LLDB_OPT_SET_1, false, "stdin", 'i', OptionParser::eRequiredArgument,
- nullptr, {}, 0, eArgTypeFilename,
- "Redirect stdin for the process to <filename>."},
- {LLDB_OPT_SET_1, false, "stdout", 'o', OptionParser::eRequiredArgument,
- nullptr, {}, 0, eArgTypeFilename,
- "Redirect stdout for the process to <filename>."},
- {LLDB_OPT_SET_1, false, "stderr", 'e', OptionParser::eRequiredArgument,
- nullptr, {}, 0, eArgTypeFilename,
- "Redirect stderr for the process to <filename>."},
-
- {LLDB_OPT_SET_2, false, "tty", 't', OptionParser::eNoArgument, nullptr,
- {}, 0, eArgTypeNone,
- "Start the process in a terminal (not supported on all platforms)."},
-
- {LLDB_OPT_SET_3, false, "no-stdio", 'n', OptionParser::eNoArgument, nullptr,
- {}, 0, eArgTypeNone,
- "Do not set up for terminal I/O to go to running process."},
- {LLDB_OPT_SET_4, false, "shell-expand-args", 'X',
- OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
- "Set whether to shell expand arguments to the process when launching."},
-};
-
-llvm::ArrayRef<OptionDefinition> ProcessLaunchCommandOptions::GetDefinitions() {
- return llvm::makeArrayRef(g_process_launch_options);
-}
-
ProcessSP Process::FindPlugin(lldb::TargetSP target_sp,
llvm::StringRef plugin_name,
ListenerSP listener_sp,
- const FileSpec *crash_file_path) {
+ const FileSpec *crash_file_path,
+ bool can_connect) {
static uint32_t g_process_unique_id = 0;
ProcessSP process_sp;
@@ -483,7 +321,8 @@ ProcessSP Process::FindPlugin(lldb::TargetSP target_sp,
create_callback =
PluginManager::GetProcessCreateCallbackForPluginName(const_plugin_name);
if (create_callback) {
- process_sp = create_callback(target_sp, listener_sp, crash_file_path);
+ process_sp = create_callback(target_sp, listener_sp, crash_file_path,
+ can_connect);
if (process_sp) {
if (process_sp->CanDebug(target_sp, true)) {
process_sp->m_process_unique_id = ++g_process_unique_id;
@@ -496,7 +335,8 @@ ProcessSP Process::FindPlugin(lldb::TargetSP target_sp,
(create_callback =
PluginManager::GetProcessCreateCallbackAtIndex(idx)) != nullptr;
++idx) {
- process_sp = create_callback(target_sp, listener_sp, crash_file_path);
+ process_sp = create_callback(target_sp, listener_sp, crash_file_path,
+ can_connect);
if (process_sp) {
if (process_sp->CanDebug(target_sp, false)) {
process_sp->m_process_unique_id = ++g_process_unique_id;
@@ -523,7 +363,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp)
Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
const UnixSignalsSP &unix_signals_sp)
- : ProcessProperties(this), UserID(LLDB_INVALID_PROCESS_ID),
+ : ProcessProperties(this),
Broadcaster((target_sp->GetDebugger().GetBroadcasterManager()),
Process::GetStaticBroadcasterClass().AsCString()),
m_target_wp(target_sp), m_public_state(eStateUnloaded),
@@ -547,7 +387,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
m_profile_data_comm_mutex(), m_profile_data(), m_iohandler_sync(0),
m_memory_cache(*this), m_allocated_memory_cache(*this),
m_should_detach(false), m_next_event_action_up(), m_public_run_lock(),
- m_private_run_lock(), m_finalizing(false), m_finalize_called(false),
+ m_private_run_lock(), m_finalizing(false),
m_clear_thread_plans_on_stop(false), m_force_next_event_delivery(false),
m_last_broadcast_state(eStateInvalid), m_destroy_in_process(false),
m_can_interpret_function_calls(false), m_warnings_issued(),
@@ -623,7 +463,8 @@ const ProcessPropertiesSP &Process::GetGlobalProperties() {
}
void Process::Finalize() {
- m_finalizing = true;
+ if (m_finalizing.exchange(true))
+ return;
// Destroy this process if needed
switch (GetPrivateState()) {
@@ -635,7 +476,7 @@ void Process::Finalize() {
case eStateStepping:
case eStateCrashed:
case eStateSuspended:
- Destroy(false);
+ DestroyImpl(false);
break;
case eStateInvalid:
@@ -698,7 +539,6 @@ void Process::Finalize() {
m_private_run_lock.TrySetRunning(); // This will do nothing if already locked
m_private_run_lock.SetStopped();
m_structured_data_plugin_map.clear();
- m_finalize_called = true;
}
void Process::RegisterNotificationCallbacks(const Notifications &callbacks) {
@@ -1239,6 +1079,12 @@ bool Process::SetProcessExitStatus(
return false;
}
+bool Process::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ m_thread_plans.ClearThreadCache();
+ return DoUpdateThreadList(old_thread_list, new_thread_list);
+}
+
void Process::UpdateThreadListIfNeeded() {
const uint32_t stop_id = GetStopID();
if (m_thread_list.GetSize(false) == 0 ||
@@ -1507,7 +1353,7 @@ bool Process::StateChangedIsHijackedForSynchronousResume() {
StateType Process::GetPrivateState() { return m_private_state.GetValue(); }
void Process::SetPrivateState(StateType new_state) {
- if (m_finalize_called)
+ if (m_finalizing)
return;
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
@@ -1557,11 +1403,7 @@ void Process::SetPrivateState(StateType new_state) {
StateAsCString(new_state), m_mod_id.GetStopID());
}
- // Use our target to get a shared pointer to ourselves...
- if (m_finalize_called && !PrivateStateThreadIsValid())
- BroadcastEvent(event_sp);
- else
- m_private_state_broadcaster.BroadcastEvent(event_sp);
+ m_private_state_broadcaster.BroadcastEvent(event_sp);
} else {
LLDB_LOGF(log,
"Process::SetPrivateState (%s) state didn't change. Ignoring...",
@@ -2291,6 +2133,9 @@ size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size,
if (error.Fail())
return;
+ if (bp->GetType() != BreakpointSite::eSoftware)
+ return;
+
addr_t intersect_addr;
size_t intersect_size;
size_t opcode_offset;
@@ -3068,13 +2913,8 @@ void Process::CompleteAttach() {
}
}
// Figure out which one is the executable, and set that in our target:
- const ModuleList &target_modules = GetTarget().GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- size_t num_modules = target_modules.GetSize();
ModuleSP new_executable_module_sp;
-
- for (size_t i = 0; i < num_modules; i++) {
- ModuleSP module_sp(target_modules.GetModuleAtIndexUnlocked(i));
+ for (ModuleSP module_sp : GetTarget().GetImages().Modules()) {
if (module_sp && module_sp->IsExecutable()) {
if (GetTarget().GetExecutableModulePointer() != module_sp.get())
new_executable_module_sp = module_sp;
@@ -3154,7 +2994,7 @@ Status Process::PrivateResume() {
if (m_thread_list.WillResume()) {
// Last thing, do the PreResumeActions.
if (!RunPreResumeActions()) {
- error.SetErrorStringWithFormat(
+ error.SetErrorString(
"Process::PrivateResume PreResumeActions failed, not resuming.");
} else {
m_mod_id.BumpResumeID();
@@ -3333,9 +3173,12 @@ Status Process::Detach(bool keep_stopped) {
Status Process::Destroy(bool force_kill) {
// If we've already called Process::Finalize then there's nothing useful to
// be done here. Finalize has actually called Destroy already.
- if (m_finalize_called)
+ if (m_finalizing)
return {};
+ return DestroyImpl(force_kill);
+}
+Status Process::DestroyImpl(bool force_kill) {
// Tell ourselves we are in the process of destroying the process, so that we
// don't do any unnecessary work that might hinder the destruction. Remember
// to set this back to false when we are done. That way if the attempt
@@ -4169,8 +4012,7 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
// public (or SyncResume) broadcasters. StopHooks are just for
// real public stops. They might also restart the target,
// so watch for that.
- process_sp->GetTarget().RunStopHooks();
- if (process_sp->GetPrivateState() == eStateRunning)
+ if (process_sp->GetTarget().RunStopHooks())
SetRestarted(true);
}
}
@@ -5757,41 +5599,25 @@ addr_t Process::ResolveIndirectFunction(const Address *address, Status &error) {
}
void Process::ModulesDidLoad(ModuleList &module_list) {
+ // Inform the system runtime of the modified modules.
SystemRuntime *sys_runtime = GetSystemRuntime();
- if (sys_runtime) {
+ if (sys_runtime)
sys_runtime->ModulesDidLoad(module_list);
- }
GetJITLoaders().ModulesDidLoad(module_list);
- // Give runtimes a chance to be created.
+ // Give the instrumentation runtimes a chance to be created before informing
+ // them of the modified modules.
InstrumentationRuntime::ModulesDidLoad(module_list, this,
m_instrumentation_runtimes);
+ for (auto &runtime : m_instrumentation_runtimes)
+ runtime.second->ModulesDidLoad(module_list);
- // Tell runtimes about new modules.
- for (auto pos = m_instrumentation_runtimes.begin();
- pos != m_instrumentation_runtimes.end(); ++pos) {
- InstrumentationRuntimeSP runtime = pos->second;
- runtime->ModulesDidLoad(module_list);
- }
-
- // Let any language runtimes we have already created know about the modules
- // that loaded.
-
- // Iterate over a copy of this language runtime list in case the language
- // runtime ModulesDidLoad somehow causes the language runtime to be
- // unloaded.
- {
- std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex);
- LanguageRuntimeCollection language_runtimes(m_language_runtimes);
- for (const auto &pair : language_runtimes) {
- // We must check language_runtime_sp to make sure it is not nullptr as we
- // might cache the fact that we didn't have a language runtime for a
- // language.
- LanguageRuntimeSP language_runtime_sp = pair.second;
- if (language_runtime_sp)
- language_runtime_sp->ModulesDidLoad(module_list);
- }
+ // Give the language runtimes a chance to be created before informing them of
+ // the modified modules.
+ for (const lldb::LanguageType lang_type : Language::GetSupportedLanguages()) {
+ if (LanguageRuntime *runtime = GetLanguageRuntime(lang_type))
+ runtime->ModulesDidLoad(module_list);
}
// If we don't have an operating system plug-in, try to load one since
@@ -5799,7 +5625,7 @@ void Process::ModulesDidLoad(ModuleList &module_list) {
if (!m_os_up)
LoadOperatingSystemPlugin(false);
- // Give structured-data plugins a chance to see the modified modules.
+ // Inform the structured-data plugins of the modified modules.
for (auto pair : m_structured_data_plugin_map) {
if (pair.second)
pair.second->ModulesDidLoad(*this, module_list);
@@ -5960,10 +5786,8 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr,
return retval;
}
- uint32_t branch_index =
- insn_list->GetIndexOfNextBranchInstruction(insn_offset, target,
- false /* ignore_calls*/,
- nullptr);
+ uint32_t branch_index = insn_list->GetIndexOfNextBranchInstruction(
+ insn_offset, false /* ignore_calls*/, nullptr);
if (branch_index == UINT32_MAX) {
return retval;
}
@@ -6138,6 +5962,13 @@ UtilityFunction *Process::GetLoadImageUtilityFunction(
return m_dlopen_utility_func_up.get();
}
+llvm::Expected<TraceTypeInfo> Process::GetSupportedTraceType() {
+ if (!IsLiveDebugSession())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Can't trace a non-live process.");
+ return llvm::make_error<UnimplementedError>();
+}
+
bool Process::CallVoidArgVoidPtrReturn(const Address *address,
addr_t &returned_func,
bool trap_exceptions) {