summaryrefslogtreecommitdiff
path: root/source/Target/Process.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Target/Process.cpp')
-rw-r--r--source/Target/Process.cpp850
1 files changed, 352 insertions, 498 deletions
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index fb3b758912eb..6c634dba00c7 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -1,13 +1,13 @@
//===-- Process.cpp ---------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <atomic>
+#include <memory>
#include <mutex>
#include "llvm/Support/ScopedPrinter.h"
@@ -22,7 +22,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Expression/DiagnosticManager.h"
-#include "lldb/Expression/IRDynamicChecks.h"
+#include "lldb/Expression/DynamicCheckerFunctions.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
@@ -39,15 +39,14 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ABI.h"
-#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/InstrumentationRuntime.h"
#include "lldb/Target/JITLoader.h"
#include "lldb/Target/JITLoaderList.h"
+#include "lldb/Target/Language.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/MemoryHistory.h"
#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/OperatingSystem.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
@@ -64,6 +63,7 @@
#include "lldb/Utility/Event.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/NameMatches.h"
+#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/SelectHelper.h"
#include "lldb/Utility/State.h"
@@ -83,7 +83,7 @@ using namespace std::chrono;
class ProcessOptionValueProperties : public OptionValueProperties {
public:
- ProcessOptionValueProperties(const ConstString &name)
+ ProcessOptionValueProperties(ConstString name)
: OptionValueProperties(name) {}
// This constructor is used when creating ProcessOptionValueProperties when
@@ -143,7 +143,11 @@ static constexpr PropertyDefinition g_properties[] = {
"stepping and variable availability may not behave as expected."},
{"stop-on-exec", OptionValue::eTypeBoolean, true, true,
nullptr, {},
- "If true, stop when a shared library is loaded or unloaded."}};
+ "If true, stop when a shared library is loaded or unloaded."},
+ {"utility-expression-timeout", OptionValue::eTypeUInt64, false, 15,
+ nullptr, {},
+ "The time in seconds to wait for LLDB-internal utility expressions."}
+};
enum {
ePropertyDisableMemCache,
@@ -155,7 +159,8 @@ enum {
ePropertyDetachKeepsStopped,
ePropertyMemCacheLineSize,
ePropertyWarningOptimization,
- ePropertyStopOnExec
+ ePropertyStopOnExec,
+ ePropertyUtilityExpressionTimeout,
};
ProcessProperties::ProcessProperties(lldb_private::Process *process)
@@ -164,15 +169,15 @@ ProcessProperties::ProcessProperties(lldb_private::Process *process)
{
if (process == nullptr) {
// Global process properties, set them up one time
- m_collection_sp.reset(
- new ProcessOptionValueProperties(ConstString("process")));
+ m_collection_sp =
+ std::make_shared<ProcessOptionValueProperties>(ConstString("process"));
m_collection_sp->Initialize(g_properties);
m_collection_sp->AppendProperty(
ConstString("thread"), ConstString("Settings specific to threads."),
true, Thread::GetGlobalProperties()->GetValueProperties());
} else {
- m_collection_sp.reset(
- new ProcessOptionValueProperties(Process::GetGlobalProperties().get()));
+ m_collection_sp = std::make_shared<ProcessOptionValueProperties>(
+ Process::GetGlobalProperties().get());
m_collection_sp->SetValueChangedCallback(
ePropertyPythonOSPluginPath,
ProcessProperties::OptionValueChangedCallback, this);
@@ -278,138 +283,11 @@ bool ProcessProperties::GetStopOnExec() const {
nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-void ProcessInstanceInfo::Dump(Stream &s, Platform *platform) const {
- const char *cstr;
- if (m_pid != LLDB_INVALID_PROCESS_ID)
- s.Printf(" pid = %" PRIu64 "\n", m_pid);
-
- if (m_parent_pid != LLDB_INVALID_PROCESS_ID)
- s.Printf(" parent = %" PRIu64 "\n", m_parent_pid);
-
- if (m_executable) {
- s.Printf(" name = %s\n", m_executable.GetFilename().GetCString());
- s.PutCString(" file = ");
- m_executable.Dump(&s);
- s.EOL();
- }
- const uint32_t argc = m_arguments.GetArgumentCount();
- if (argc > 0) {
- for (uint32_t i = 0; i < argc; i++) {
- const char *arg = m_arguments.GetArgumentAtIndex(i);
- if (i < 10)
- s.Printf(" arg[%u] = %s\n", i, arg);
- else
- s.Printf("arg[%u] = %s\n", i, arg);
- }
- }
-
- s.Format("{0}", m_environment);
-
- if (m_arch.IsValid()) {
- s.Printf(" arch = ");
- m_arch.DumpTriple(s);
- s.EOL();
- }
-
- if (m_uid != UINT32_MAX) {
- cstr = platform->GetUserName(m_uid);
- s.Printf(" uid = %-5u (%s)\n", m_uid, cstr ? cstr : "");
- }
- if (m_gid != UINT32_MAX) {
- cstr = platform->GetGroupName(m_gid);
- s.Printf(" gid = %-5u (%s)\n", m_gid, cstr ? cstr : "");
- }
- if (m_euid != UINT32_MAX) {
- cstr = platform->GetUserName(m_euid);
- s.Printf(" euid = %-5u (%s)\n", m_euid, cstr ? cstr : "");
- }
- if (m_egid != UINT32_MAX) {
- cstr = platform->GetGroupName(m_egid);
- s.Printf(" egid = %-5u (%s)\n", m_egid, cstr ? cstr : "");
- }
-}
-
-void ProcessInstanceInfo::DumpTableHeader(Stream &s, Platform *platform,
- bool show_args, bool verbose) {
- const char *label;
- if (show_args || verbose)
- label = "ARGUMENTS";
- else
- label = "NAME";
-
- if (verbose) {
- s.Printf("PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE "
- " %s\n",
- label);
- s.PutCString("====== ====== ========== ========== ========== ========== "
- "======================== ============================\n");
- } else {
- s.Printf("PID PARENT USER TRIPLE %s\n", label);
- s.PutCString("====== ====== ========== ======================== "
- "============================\n");
- }
-}
-
-void ProcessInstanceInfo::DumpAsTableRow(Stream &s, Platform *platform,
- bool show_args, bool verbose) const {
- if (m_pid != LLDB_INVALID_PROCESS_ID) {
- const char *cstr;
- s.Printf("%-6" PRIu64 " %-6" PRIu64 " ", m_pid, m_parent_pid);
-
- StreamString arch_strm;
- if (m_arch.IsValid())
- m_arch.DumpTriple(arch_strm);
-
- if (verbose) {
- cstr = platform->GetUserName(m_uid);
- if (cstr &&
- cstr[0]) // Watch for empty string that indicates lookup failed
- s.Printf("%-10s ", cstr);
- else
- s.Printf("%-10u ", m_uid);
-
- cstr = platform->GetGroupName(m_gid);
- if (cstr &&
- cstr[0]) // Watch for empty string that indicates lookup failed
- s.Printf("%-10s ", cstr);
- else
- s.Printf("%-10u ", m_gid);
-
- cstr = platform->GetUserName(m_euid);
- if (cstr &&
- cstr[0]) // Watch for empty string that indicates lookup failed
- s.Printf("%-10s ", cstr);
- else
- s.Printf("%-10u ", m_euid);
-
- cstr = platform->GetGroupName(m_egid);
- if (cstr &&
- cstr[0]) // Watch for empty string that indicates lookup failed
- s.Printf("%-10s ", cstr);
- else
- s.Printf("%-10u ", m_egid);
-
- s.Printf("%-24s ", arch_strm.GetData());
- } else {
- s.Printf("%-10s %-24s ", platform->GetUserName(m_euid),
- arch_strm.GetData());
- }
-
- if (verbose || show_args) {
- const uint32_t argc = m_arguments.GetArgumentCount();
- if (argc > 0) {
- for (uint32_t i = 0; i < argc; i++) {
- if (i > 0)
- s.PutChar(' ');
- s.PutCString(m_arguments.GetArgumentAtIndex(i));
- }
- }
- } else {
- s.PutCString(GetName());
- }
-
- s.EOL();
- }
+std::chrono::seconds ProcessProperties::GetUtilityExpressionTimeout() const {
+ const uint32_t idx = ePropertyUtilityExpressionTimeout;
+ uint64_t value = m_collection_sp->GetPropertyAtIndexAsUInt64(
+ nullptr, idx, g_properties[idx].default_uint_value);
+ return std::chrono::seconds(value);
}
Status ProcessLaunchCommandOptions::SetOptionValue(
@@ -581,89 +459,6 @@ llvm::ArrayRef<OptionDefinition> ProcessLaunchCommandOptions::GetDefinitions() {
return llvm::makeArrayRef(g_process_launch_options);
}
-bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const {
- if (m_name_match_type == NameMatch::Ignore || process_name == nullptr)
- return true;
- const char *match_name = m_match_info.GetName();
- if (!match_name)
- return true;
-
- return lldb_private::NameMatches(process_name, m_name_match_type, match_name);
-}
-
-bool ProcessInstanceInfoMatch::Matches(
- const ProcessInstanceInfo &proc_info) const {
- if (!NameMatches(proc_info.GetName()))
- return false;
-
- if (m_match_info.ProcessIDIsValid() &&
- m_match_info.GetProcessID() != proc_info.GetProcessID())
- return false;
-
- if (m_match_info.ParentProcessIDIsValid() &&
- m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())
- return false;
-
- if (m_match_info.UserIDIsValid() &&
- m_match_info.GetUserID() != proc_info.GetUserID())
- return false;
-
- if (m_match_info.GroupIDIsValid() &&
- m_match_info.GetGroupID() != proc_info.GetGroupID())
- return false;
-
- if (m_match_info.EffectiveUserIDIsValid() &&
- m_match_info.GetEffectiveUserID() != proc_info.GetEffectiveUserID())
- return false;
-
- if (m_match_info.EffectiveGroupIDIsValid() &&
- m_match_info.GetEffectiveGroupID() != proc_info.GetEffectiveGroupID())
- return false;
-
- if (m_match_info.GetArchitecture().IsValid() &&
- !m_match_info.GetArchitecture().IsCompatibleMatch(
- proc_info.GetArchitecture()))
- return false;
- return true;
-}
-
-bool ProcessInstanceInfoMatch::MatchAllProcesses() const {
- if (m_name_match_type != NameMatch::Ignore)
- return false;
-
- if (m_match_info.ProcessIDIsValid())
- return false;
-
- if (m_match_info.ParentProcessIDIsValid())
- return false;
-
- if (m_match_info.UserIDIsValid())
- return false;
-
- if (m_match_info.GroupIDIsValid())
- return false;
-
- if (m_match_info.EffectiveUserIDIsValid())
- return false;
-
- if (m_match_info.EffectiveGroupIDIsValid())
- return false;
-
- if (m_match_info.GetArchitecture().IsValid())
- return false;
-
- if (m_match_all_users)
- return false;
-
- return true;
-}
-
-void ProcessInstanceInfoMatch::Clear() {
- m_match_info.Clear();
- m_name_match_type = NameMatch::Ignore;
- m_match_all_users = false;
-}
-
ProcessSP Process::FindPlugin(lldb::TargetSP target_sp,
llvm::StringRef plugin_name,
ListenerSP listener_sp,
@@ -734,13 +529,13 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
m_thread_list(this), m_extended_thread_list(this),
m_extended_thread_stop_id(0), m_queue_list(this), m_queue_list_stop_id(0),
m_notifications(), m_image_tokens(), m_listener_sp(listener_sp),
- m_breakpoint_site_list(), m_dynamic_checkers_ap(),
+ m_breakpoint_site_list(), m_dynamic_checkers_up(),
m_unix_signals_sp(unix_signals_sp), m_abi_sp(), m_process_input_reader(),
m_stdio_communication("process.stdio"), m_stdio_communication_mutex(),
m_stdin_forward(false), m_stdout_data(), m_stderr_data(),
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_ap(), m_public_run_lock(),
+ 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_clear_thread_plans_on_stop(false), m_force_next_event_delivery(false),
m_last_broadcast_state(eStateInvalid), m_destroy_in_process(false),
@@ -848,12 +643,12 @@ void Process::Finalize() {
// We need to destroy the loader before the derived Process class gets
// destroyed since it is very likely that undoing the loader will require
// access to the real process.
- m_dynamic_checkers_ap.reset();
+ m_dynamic_checkers_up.reset();
m_abi_sp.reset();
- m_os_ap.reset();
- m_system_runtime_ap.reset();
- m_dyld_ap.reset();
- m_jit_loaders_ap.reset();
+ m_os_up.reset();
+ m_system_runtime_up.reset();
+ m_dyld_up.reset();
+ m_jit_loaders_up.reset();
m_thread_list_real.Destroy();
m_thread_list.Destroy();
m_extended_thread_list.Destroy();
@@ -864,9 +659,12 @@ void Process::Finalize() {
m_image_tokens.clear();
m_memory_cache.Clear();
m_allocated_memory_cache.Clear();
- m_language_runtimes.clear();
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex);
+ m_language_runtimes.clear();
+ }
m_instrumentation_runtimes.clear();
- m_next_event_action_ap.reset();
+ m_next_event_action_up.reset();
// Clear the last natural stop ID since it has a strong reference to this
// process
m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
@@ -1506,12 +1304,12 @@ void Process::UpdateThreadListIfNeeded() {
}
void Process::UpdateQueueListIfNeeded() {
- if (m_system_runtime_ap) {
+ if (m_system_runtime_up) {
if (m_queue_list.GetSize() == 0 ||
m_queue_list_stop_id != GetLastNaturalStopID()) {
const StateType state = GetPrivateState();
if (StateIsStoppedState(state, true)) {
- m_system_runtime_ap->PopulateQueueList(m_queue_list);
+ m_system_runtime_up->PopulateQueueList(m_queue_list);
m_queue_list_stop_id = GetLastNaturalStopID();
}
}
@@ -1552,16 +1350,6 @@ StateType Process::GetState() {
return m_public_state.GetValue();
}
-bool Process::StateChangedIsExternallyHijacked() {
- if (IsHijackedForEvent(eBroadcastBitStateChanged)) {
- const char *hijacking_name = GetHijackingListenerName();
- if (hijacking_name &&
- strcmp(hijacking_name, "lldb.Process.ResumeSynchronous.hijack"))
- return true;
- }
- return false;
-}
-
void Process::SetPublicState(StateType new_state, bool restarted) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
LIBLLDB_LOG_PROCESS));
@@ -1615,6 +1403,8 @@ Status Process::Resume() {
return error;
}
+static const char *g_resume_sync_name = "lldb.Process.ResumeSynchronous.hijack";
+
Status Process::ResumeSynchronous(Stream *stream) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
LIBLLDB_LOG_PROCESS));
@@ -1628,13 +1418,13 @@ Status Process::ResumeSynchronous(Stream *stream) {
}
ListenerSP listener_sp(
- Listener::MakeListener("lldb.Process.ResumeSynchronous.hijack"));
+ Listener::MakeListener(g_resume_sync_name));
HijackProcessEvents(listener_sp);
Status error = PrivateResume();
if (error.Success()) {
StateType state =
- WaitForProcessToStop(llvm::None, NULL, true, listener_sp, stream);
+ WaitForProcessToStop(llvm::None, nullptr, true, listener_sp, stream);
const bool must_be_alive =
false; // eStateExited is ok, so this must be false
if (!StateIsStoppedState(state, must_be_alive))
@@ -1652,6 +1442,26 @@ Status Process::ResumeSynchronous(Stream *stream) {
return error;
}
+bool Process::StateChangedIsExternallyHijacked() {
+ if (IsHijackedForEvent(eBroadcastBitStateChanged)) {
+ const char *hijacking_name = GetHijackingListenerName();
+ if (hijacking_name &&
+ strcmp(hijacking_name, g_resume_sync_name))
+ return true;
+ }
+ return false;
+}
+
+bool Process::StateChangedIsHijackedForSynchronousResume() {
+ if (IsHijackedForEvent(eBroadcastBitStateChanged)) {
+ const char *hijacking_name = GetHijackingListenerName();
+ if (hijacking_name &&
+ strcmp(hijacking_name, g_resume_sync_name) == 0)
+ return true;
+ }
+ return false;
+}
+
StateType Process::GetPrivateState() { return m_private_state.GetValue(); }
void Process::SetPrivateState(StateType new_state) {
@@ -1736,38 +1546,54 @@ const lldb::ABISP &Process::GetABI() {
return m_abi_sp;
}
+std::vector<LanguageRuntime *>
+Process::GetLanguageRuntimes(bool retry_if_null) {
+ std::vector<LanguageRuntime *> language_runtimes;
+
+ if (m_finalizing)
+ return language_runtimes;
+
+ std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex);
+ // Before we pass off a copy of the language runtimes, we must make sure that
+ // our collection is properly populated. It's possible that some of the
+ // language runtimes were not loaded yet, either because nobody requested it
+ // yet or the proper condition for loading wasn't yet met (e.g. libc++.so
+ // hadn't been loaded).
+ for (const lldb::LanguageType lang_type : Language::GetSupportedLanguages()) {
+ if (LanguageRuntime *runtime = GetLanguageRuntime(lang_type, retry_if_null))
+ language_runtimes.emplace_back(runtime);
+ }
+
+ return language_runtimes;
+}
+
LanguageRuntime *Process::GetLanguageRuntime(lldb::LanguageType language,
bool retry_if_null) {
if (m_finalizing)
return nullptr;
+ LanguageRuntime *runtime = nullptr;
+
+ std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex);
LanguageRuntimeCollection::iterator pos;
pos = m_language_runtimes.find(language);
- if (pos == m_language_runtimes.end() || (retry_if_null && !(*pos).second)) {
+ if (pos == m_language_runtimes.end() || (retry_if_null && !pos->second)) {
lldb::LanguageRuntimeSP runtime_sp(
LanguageRuntime::FindPlugin(this, language));
m_language_runtimes[language] = runtime_sp;
- return runtime_sp.get();
+ runtime = runtime_sp.get();
} else
- return (*pos).second.get();
-}
+ runtime = pos->second.get();
-CPPLanguageRuntime *Process::GetCPPLanguageRuntime(bool retry_if_null) {
- LanguageRuntime *runtime =
- GetLanguageRuntime(eLanguageTypeC_plus_plus, retry_if_null);
- if (runtime != nullptr &&
- runtime->GetLanguageType() == eLanguageTypeC_plus_plus)
- return static_cast<CPPLanguageRuntime *>(runtime);
- return nullptr;
-}
+ if (runtime)
+ // It's possible that a language runtime can support multiple LanguageTypes,
+ // for example, CPPLanguageRuntime will support eLanguageTypeC_plus_plus,
+ // eLanguageTypeC_plus_plus_03, etc. Because of this, we should get the
+ // primary language type and make sure that our runtime supports it.
+ assert(runtime->GetLanguageType() == Language::GetPrimaryLanguage(language));
-ObjCLanguageRuntime *Process::GetObjCLanguageRuntime(bool retry_if_null) {
- LanguageRuntime *runtime =
- GetLanguageRuntime(eLanguageTypeObjC, retry_if_null);
- if (runtime != nullptr && runtime->GetLanguageType() == eLanguageTypeObjC)
- return static_cast<ObjCLanguageRuntime *>(runtime);
- return nullptr;
+ return runtime;
}
bool Process::IsPossibleDynamicValue(ValueObject &in_value) {
@@ -1783,16 +1609,16 @@ bool Process::IsPossibleDynamicValue(ValueObject &in_value) {
return runtime ? runtime->CouldHaveDynamicValue(in_value) : false;
}
- LanguageRuntime *cpp_runtime = GetLanguageRuntime(eLanguageTypeC_plus_plus);
- if (cpp_runtime && cpp_runtime->CouldHaveDynamicValue(in_value))
- return true;
+ for (LanguageRuntime *runtime : GetLanguageRuntimes()) {
+ if (runtime->CouldHaveDynamicValue(in_value))
+ return true;
+ }
- LanguageRuntime *objc_runtime = GetLanguageRuntime(eLanguageTypeObjC);
- return objc_runtime ? objc_runtime->CouldHaveDynamicValue(in_value) : false;
+ return false;
}
void Process::SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers) {
- m_dynamic_checkers_ap.reset(dynamic_checkers);
+ m_dynamic_checkers_up.reset(dynamic_checkers);
}
BreakpointSiteList &Process::GetBreakpointSiteList() {
@@ -2413,67 +2239,64 @@ size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size,
// may have placed in our tasks memory.
BreakpointSiteList bp_sites_in_range;
+ if (!m_breakpoint_site_list.FindInRange(addr, addr + size, bp_sites_in_range))
+ return WriteMemoryPrivate(addr, buf, size, error);
- if (m_breakpoint_site_list.FindInRange(addr, addr + size,
- bp_sites_in_range)) {
- // No breakpoint sites overlap
- if (bp_sites_in_range.IsEmpty())
- return WriteMemoryPrivate(addr, buf, size, error);
- else {
- const uint8_t *ubuf = (const uint8_t *)buf;
- uint64_t bytes_written = 0;
+ // No breakpoint sites overlap
+ if (bp_sites_in_range.IsEmpty())
+ return WriteMemoryPrivate(addr, buf, size, error);
- bp_sites_in_range.ForEach([this, addr, size, &bytes_written, &ubuf,
- &error](BreakpointSite *bp) -> void {
+ const uint8_t *ubuf = (const uint8_t *)buf;
+ uint64_t bytes_written = 0;
- if (error.Success()) {
- addr_t intersect_addr;
- size_t intersect_size;
- size_t opcode_offset;
- const bool intersects = bp->IntersectsRange(
- addr, size, &intersect_addr, &intersect_size, &opcode_offset);
- UNUSED_IF_ASSERT_DISABLED(intersects);
- assert(intersects);
- assert(addr <= intersect_addr && intersect_addr < addr + size);
- assert(addr < intersect_addr + intersect_size &&
- intersect_addr + intersect_size <= addr + size);
- assert(opcode_offset + intersect_size <= bp->GetByteSize());
-
- // Check for bytes before this breakpoint
- const addr_t curr_addr = addr + bytes_written;
- if (intersect_addr > curr_addr) {
- // There are some bytes before this breakpoint that we need to just
- // write to memory
- size_t curr_size = intersect_addr - curr_addr;
- size_t curr_bytes_written = WriteMemoryPrivate(
- curr_addr, ubuf + bytes_written, curr_size, error);
- bytes_written += curr_bytes_written;
- if (curr_bytes_written != curr_size) {
- // We weren't able to write all of the requested bytes, we are
- // done looping and will return the number of bytes that we have
- // written so far.
- if (error.Success())
- error.SetErrorToGenericError();
- }
- }
- // Now write any bytes that would cover up any software breakpoints
- // directly into the breakpoint opcode buffer
- ::memcpy(bp->GetSavedOpcodeBytes() + opcode_offset,
- ubuf + bytes_written, intersect_size);
- bytes_written += intersect_size;
- }
- });
+ bp_sites_in_range.ForEach([this, addr, size, &bytes_written, &ubuf,
+ &error](BreakpointSite *bp) -> void {
+ if (error.Fail())
+ return;
- if (bytes_written < size)
- WriteMemoryPrivate(addr + bytes_written, ubuf + bytes_written,
- size - bytes_written, error);
+ addr_t intersect_addr;
+ size_t intersect_size;
+ size_t opcode_offset;
+ const bool intersects = bp->IntersectsRange(
+ addr, size, &intersect_addr, &intersect_size, &opcode_offset);
+ UNUSED_IF_ASSERT_DISABLED(intersects);
+ assert(intersects);
+ assert(addr <= intersect_addr && intersect_addr < addr + size);
+ assert(addr < intersect_addr + intersect_size &&
+ intersect_addr + intersect_size <= addr + size);
+ assert(opcode_offset + intersect_size <= bp->GetByteSize());
+
+ // Check for bytes before this breakpoint
+ const addr_t curr_addr = addr + bytes_written;
+ if (intersect_addr > curr_addr) {
+ // There are some bytes before this breakpoint that we need to just
+ // write to memory
+ size_t curr_size = intersect_addr - curr_addr;
+ size_t curr_bytes_written =
+ WriteMemoryPrivate(curr_addr, ubuf + bytes_written, curr_size, error);
+ bytes_written += curr_bytes_written;
+ if (curr_bytes_written != curr_size) {
+ // We weren't able to write all of the requested bytes, we are
+ // done looping and will return the number of bytes that we have
+ // written so far.
+ if (error.Success())
+ error.SetErrorToGenericError();
+ }
}
- } else {
- return WriteMemoryPrivate(addr, buf, size, error);
- }
+ // Now write any bytes that would cover up any software breakpoints
+ // directly into the breakpoint opcode buffer
+ ::memcpy(bp->GetSavedOpcodeBytes() + opcode_offset, ubuf + bytes_written,
+ intersect_size);
+ bytes_written += intersect_size;
+ });
// Write any remaining bytes after the last breakpoint if we have any left
- return 0; // bytes_written;
+ if (bytes_written < size)
+ bytes_written +=
+ WriteMemoryPrivate(addr + bytes_written, ubuf + bytes_written,
+ size - bytes_written, error);
+
+ return bytes_written;
}
size_t Process::WriteScalarToMemory(addr_t addr, const Scalar &scalar,
@@ -2708,7 +2531,7 @@ Process::WaitForProcessStopPrivate(EventSP &event_sp,
void Process::LoadOperatingSystemPlugin(bool flush) {
if (flush)
m_thread_list.Clear();
- m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr));
+ m_os_up.reset(OperatingSystem::FindPlugin(this, nullptr));
if (flush)
Flush();
}
@@ -2716,115 +2539,119 @@ void Process::LoadOperatingSystemPlugin(bool flush) {
Status Process::Launch(ProcessLaunchInfo &launch_info) {
Status error;
m_abi_sp.reset();
- m_dyld_ap.reset();
- m_jit_loaders_ap.reset();
- m_system_runtime_ap.reset();
- m_os_ap.reset();
+ m_dyld_up.reset();
+ m_jit_loaders_up.reset();
+ m_system_runtime_up.reset();
+ m_os_up.reset();
m_process_input_reader.reset();
Module *exe_module = GetTarget().GetExecutableModulePointer();
- if (exe_module) {
- char local_exec_file_path[PATH_MAX];
- char platform_exec_file_path[PATH_MAX];
- exe_module->GetFileSpec().GetPath(local_exec_file_path,
- sizeof(local_exec_file_path));
- exe_module->GetPlatformFileSpec().GetPath(platform_exec_file_path,
- sizeof(platform_exec_file_path));
- if (FileSystem::Instance().Exists(exe_module->GetFileSpec())) {
- // Install anything that might need to be installed prior to launching.
- // For host systems, this will do nothing, but if we are connected to a
- // remote platform it will install any needed binaries
- error = GetTarget().Install(&launch_info);
- if (error.Fail())
- return error;
+ if (!exe_module) {
+ error.SetErrorString("executable module does not exist");
+ return error;
+ }
- if (PrivateStateThreadIsValid())
- PausePrivateStateThread();
+ char local_exec_file_path[PATH_MAX];
+ char platform_exec_file_path[PATH_MAX];
+ exe_module->GetFileSpec().GetPath(local_exec_file_path,
+ sizeof(local_exec_file_path));
+ exe_module->GetPlatformFileSpec().GetPath(platform_exec_file_path,
+ sizeof(platform_exec_file_path));
+ if (FileSystem::Instance().Exists(exe_module->GetFileSpec())) {
+ // Install anything that might need to be installed prior to launching.
+ // For host systems, this will do nothing, but if we are connected to a
+ // remote platform it will install any needed binaries
+ error = GetTarget().Install(&launch_info);
+ if (error.Fail())
+ return error;
- error = WillLaunch(exe_module);
- if (error.Success()) {
- const bool restarted = false;
- SetPublicState(eStateLaunching, restarted);
- m_should_detach = false;
+ if (PrivateStateThreadIsValid())
+ PausePrivateStateThread();
- if (m_public_run_lock.TrySetRunning()) {
- // Now launch using these arguments.
- error = DoLaunch(exe_module, launch_info);
- } else {
- // This shouldn't happen
- error.SetErrorString("failed to acquire process run lock");
+ error = WillLaunch(exe_module);
+ if (error.Success()) {
+ const bool restarted = false;
+ SetPublicState(eStateLaunching, restarted);
+ m_should_detach = false;
+
+ if (m_public_run_lock.TrySetRunning()) {
+ // Now launch using these arguments.
+ error = DoLaunch(exe_module, launch_info);
+ } else {
+ // This shouldn't happen
+ error.SetErrorString("failed to acquire process run lock");
+ }
+
+ if (error.Fail()) {
+ if (GetID() != LLDB_INVALID_PROCESS_ID) {
+ SetID(LLDB_INVALID_PROCESS_ID);
+ const char *error_string = error.AsCString();
+ if (error_string == nullptr)
+ error_string = "launch failed";
+ SetExitStatus(-1, error_string);
}
+ } else {
+ EventSP event_sp;
+
+ // Now wait for the process to launch and return control to us, and then
+ // call DidLaunch:
+ StateType state = WaitForProcessStopPrivate(event_sp, seconds(10));
+
+ if (state == eStateInvalid || !event_sp) {
+ // We were able to launch the process, but we failed to catch the
+ // initial stop.
+ error.SetErrorString("failed to catch stop after launch");
+ SetExitStatus(0, "failed to catch stop after launch");
+ Destroy(false);
+ } else if (state == eStateStopped || state == eStateCrashed) {
+ DidLaunch();
+
+ DynamicLoader *dyld = GetDynamicLoader();
+ if (dyld)
+ dyld->DidLaunch();
+
+ GetJITLoaders().DidLaunch();
+
+ SystemRuntime *system_runtime = GetSystemRuntime();
+ if (system_runtime)
+ system_runtime->DidLaunch();
+
+ if (!m_os_up)
+ LoadOperatingSystemPlugin(false);
+
+ // We successfully launched the process and stopped, now it the
+ // right time to set up signal filters before resuming.
+ UpdateAutomaticSignalFiltering();
+
+ // Note, the stop event was consumed above, but not handled. This
+ // was done to give DidLaunch a chance to run. The target is either
+ // stopped or crashed. Directly set the state. This is done to
+ // prevent a stop message with a bunch of spurious output on thread
+ // status, as well as not pop a ProcessIOHandler.
+ SetPublicState(state, false);
+
+ if (PrivateStateThreadIsValid())
+ ResumePrivateStateThread();
+ else
+ StartPrivateStateThread();
- if (error.Fail()) {
- if (GetID() != LLDB_INVALID_PROCESS_ID) {
- SetID(LLDB_INVALID_PROCESS_ID);
- const char *error_string = error.AsCString();
- if (error_string == nullptr)
- error_string = "launch failed";
- SetExitStatus(-1, error_string);
- }
- } else {
- EventSP event_sp;
-
- // Now wait for the process to launch and return control to us, and then call
- // DidLaunch:
- StateType state = WaitForProcessStopPrivate(event_sp, seconds(10));
-
- if (state == eStateInvalid || !event_sp) {
- // We were able to launch the process, but we failed to catch the
- // initial stop.
- error.SetErrorString("failed to catch stop after launch");
- SetExitStatus(0, "failed to catch stop after launch");
- Destroy(false);
- } else if (state == eStateStopped || state == eStateCrashed) {
- DidLaunch();
-
- DynamicLoader *dyld = GetDynamicLoader();
- if (dyld)
- dyld->DidLaunch();
-
- GetJITLoaders().DidLaunch();
-
- SystemRuntime *system_runtime = GetSystemRuntime();
- if (system_runtime)
- system_runtime->DidLaunch();
-
- if (!m_os_ap)
- LoadOperatingSystemPlugin(false);
-
- // We successfully launched the process and stopped, now it the
- // right time to set up signal filters before resuming.
- UpdateAutomaticSignalFiltering();
-
- // Note, the stop event was consumed above, but not handled. This
- // was done to give DidLaunch a chance to run. The target is either
- // stopped or crashed. Directly set the state. This is done to
- // prevent a stop message with a bunch of spurious output on thread
- // status, as well as not pop a ProcessIOHandler.
- SetPublicState(state, false);
-
- if (PrivateStateThreadIsValid())
- ResumePrivateStateThread();
- else
- StartPrivateStateThread();
-
- // Target was stopped at entry as was intended. Need to notify the
- // listeners about it.
- if (state == eStateStopped &&
- launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
- HandlePrivateEvent(event_sp);
- } else if (state == eStateExited) {
- // We exited while trying to launch somehow. Don't call DidLaunch
- // as that's not likely to work, and return an invalid pid.
+ // Target was stopped at entry as was intended. Need to notify the
+ // listeners about it.
+ if (state == eStateStopped &&
+ launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
HandlePrivateEvent(event_sp);
- }
+ } else if (state == eStateExited) {
+ // We exited while trying to launch somehow. Don't call DidLaunch
+ // as that's not likely to work, and return an invalid pid.
+ HandlePrivateEvent(event_sp);
}
}
- } else {
- error.SetErrorStringWithFormat("file doesn't exist: '%s'",
- local_exec_file_path);
}
+ } else {
+ error.SetErrorStringWithFormat("file doesn't exist: '%s'",
+ local_exec_file_path);
}
+
return error;
}
@@ -2850,7 +2677,7 @@ Status Process::LoadCore() {
if (system_runtime)
system_runtime->DidAttach();
- if (!m_os_ap)
+ if (!m_os_up)
LoadOperatingSystemPlugin(false);
// We successfully loaded a core file, now pretend we stopped so we can
@@ -2860,7 +2687,7 @@ Status Process::LoadCore() {
// Wait for a stopped event since we just posted one above...
lldb::EventSP event_sp;
StateType state =
- WaitForProcessToStop(seconds(10), &event_sp, true, listener_sp);
+ WaitForProcessToStop(llvm::None, &event_sp, true, listener_sp);
if (!StateIsStoppedState(state, false)) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
@@ -2876,25 +2703,25 @@ Status Process::LoadCore() {
}
DynamicLoader *Process::GetDynamicLoader() {
- if (!m_dyld_ap)
- m_dyld_ap.reset(DynamicLoader::FindPlugin(this, nullptr));
- return m_dyld_ap.get();
+ if (!m_dyld_up)
+ m_dyld_up.reset(DynamicLoader::FindPlugin(this, nullptr));
+ return m_dyld_up.get();
}
-const lldb::DataBufferSP Process::GetAuxvData() { return DataBufferSP(); }
+DataExtractor Process::GetAuxvData() { return DataExtractor(); }
JITLoaderList &Process::GetJITLoaders() {
- if (!m_jit_loaders_ap) {
- m_jit_loaders_ap.reset(new JITLoaderList());
- JITLoader::LoadPlugins(this, *m_jit_loaders_ap);
+ if (!m_jit_loaders_up) {
+ m_jit_loaders_up.reset(new JITLoaderList());
+ JITLoader::LoadPlugins(this, *m_jit_loaders_up);
}
- return *m_jit_loaders_ap;
+ return *m_jit_loaders_up;
}
SystemRuntime *Process::GetSystemRuntime() {
- if (!m_system_runtime_ap)
- m_system_runtime_ap.reset(SystemRuntime::FindPlugin(this));
- return m_system_runtime_ap.get();
+ if (!m_system_runtime_up)
+ m_system_runtime_up.reset(SystemRuntime::FindPlugin(this));
+ return m_system_runtime_up.get();
}
Process::AttachCompletionHandler::AttachCompletionHandler(Process *process,
@@ -2984,10 +2811,10 @@ ListenerSP ProcessAttachInfo::GetListenerForProcess(Debugger &debugger) {
Status Process::Attach(ProcessAttachInfo &attach_info) {
m_abi_sp.reset();
m_process_input_reader.reset();
- m_dyld_ap.reset();
- m_jit_loaders_ap.reset();
- m_system_runtime_ap.reset();
- m_os_ap.reset();
+ m_dyld_up.reset();
+ m_jit_loaders_up.reset();
+ m_system_runtime_up.reset();
+ m_os_up.reset();
lldb::pid_t attach_pid = attach_info.GetProcessID();
Status error;
@@ -3045,11 +2872,10 @@ Status Process::Attach(ProcessAttachInfo &attach_info) {
process_name, sizeof(process_name));
if (num_matches > 1) {
StreamString s;
- ProcessInstanceInfo::DumpTableHeader(s, platform_sp.get(), true,
- false);
+ ProcessInstanceInfo::DumpTableHeader(s, true, false);
for (size_t i = 0; i < num_matches; i++) {
process_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(
- s, platform_sp.get(), true, false);
+ s, platform_sp->GetUserIDResolver(), true, false);
}
error.SetErrorStringWithFormat(
"more than one process named %s:\n%s", process_name,
@@ -3193,8 +3019,16 @@ void Process::CompleteAttach() {
}
}
- if (!m_os_ap)
+ if (!m_os_up) {
LoadOperatingSystemPlugin(false);
+ if (m_os_up) {
+ // Somebody might have gotten threads before now, but we need to force the
+ // update after we've loaded the OperatingSystem plugin or it won't get a
+ // chance to process the threads.
+ m_thread_list.Clear();
+ UpdateThreadListIfNeeded();
+ }
+ }
// 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());
@@ -3754,14 +3588,20 @@ bool Process::StartPrivateStateThread(bool is_secondary_thread) {
// Create the private state thread, and start it running.
PrivateStateThreadArgs *args_ptr =
new PrivateStateThreadArgs(this, is_secondary_thread);
- m_private_state_thread =
+ llvm::Expected<HostThread> private_state_thread =
ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread,
- (void *)args_ptr, nullptr, 8 * 1024 * 1024);
- if (m_private_state_thread.IsJoinable()) {
- ResumePrivateStateThread();
- return true;
- } else
+ (void *)args_ptr, 8 * 1024 * 1024);
+ if (!private_state_thread) {
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
+ "failed to launch host thread: {}",
+ llvm::toString(private_state_thread.takeError()));
return false;
+ }
+
+ assert(private_state_thread->IsJoinable());
+ m_private_state_thread = *private_state_thread;
+ ResumePrivateStateThread();
+ return true;
}
void Process::PausePrivateStateThread() {
@@ -3810,10 +3650,10 @@ void Process::ControlPrivateStateThread(uint32_t signal) {
bool receipt_received = false;
if (PrivateStateThreadIsValid()) {
while (!receipt_received) {
- // Check for a receipt for 2 seconds and then check if the private
+ // Check for a receipt for n seconds and then check if the private
// state thread is still around.
receipt_received =
- event_receipt_sp->WaitForEventReceived(std::chrono::seconds(2));
+ event_receipt_sp->WaitForEventReceived(GetUtilityExpressionTimeout());
if (!receipt_received) {
// Check if the private state thread is still around. If it isn't
// then we are done waiting
@@ -3824,7 +3664,7 @@ void Process::ControlPrivateStateThread(uint32_t signal) {
}
if (signal == eBroadcastInternalStateControlStop) {
- thread_result_t result = NULL;
+ thread_result_t result = {};
m_private_state_thread.Join(&result);
m_private_state_thread.Reset();
}
@@ -3851,9 +3691,9 @@ void Process::HandlePrivateEvent(EventSP &event_sp) {
Process::ProcessEventData::GetStateFromEvent(event_sp.get());
// First check to see if anybody wants a shot at this event:
- if (m_next_event_action_ap) {
+ if (m_next_event_action_up) {
NextEventAction::EventActionResult action_result =
- m_next_event_action_ap->PerformAction(event_sp);
+ m_next_event_action_up->PerformAction(event_sp);
if (log)
log->Printf("Ran next event action, result was %d.", action_result);
@@ -3871,7 +3711,7 @@ void Process::HandlePrivateEvent(EventSP &event_sp) {
// to exit so the next event will kill us.
if (new_state != eStateExited) {
// FIXME: should cons up an exited event, and discard this one.
- SetExitStatus(0, m_next_event_action_ap->GetExitString());
+ SetExitStatus(0, m_next_event_action_up->GetExitString());
SetNextEventAction(nullptr);
return;
}
@@ -4099,12 +3939,10 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
// it was doing yet, so don't try to change it on the way out.
if (!is_secondary_thread)
m_public_run_lock.SetStopped();
- return NULL;
+ return {};
}
-//------------------------------------------------------------------
// Process Event Data
-//------------------------------------------------------------------
Process::ProcessEventData::ProcessEventData()
: EventData(), m_process_wp(), m_state(eStateInvalid), m_restarted(false),
@@ -4120,12 +3958,12 @@ Process::ProcessEventData::ProcessEventData(const ProcessSP &process_sp,
Process::ProcessEventData::~ProcessEventData() = default;
-const ConstString &Process::ProcessEventData::GetFlavorString() {
+ConstString Process::ProcessEventData::GetFlavorString() {
static ConstString g_flavor("Process::ProcessEventData");
return g_flavor;
}
-const ConstString &Process::ProcessEventData::GetFlavor() const {
+ConstString Process::ProcessEventData::GetFlavor() const {
return ProcessEventData::GetFlavorString();
}
@@ -4260,15 +4098,24 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
// public resume.
process_sp->PrivateResume();
} else {
- // If we didn't restart, run the Stop Hooks here: They might also
- // restart the target, so watch for that.
- process_sp->GetTarget().RunStopHooks();
- if (process_sp->GetPrivateState() == eStateRunning)
- SetRestarted(true);
+ bool hijacked =
+ process_sp->IsHijackedForEvent(eBroadcastBitStateChanged) &&
+ !process_sp->StateChangedIsHijackedForSynchronousResume();
+
+ if (!hijacked) {
+ // If we didn't restart, run the Stop Hooks here.
+ // Don't do that if state changed events aren't hooked up to the
+ // 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)
+ SetRestarted(true);
}
}
}
}
+}
void Process::ProcessEventData::Dump(Stream *s) const {
ProcessSP process_sp(m_process_wp.lock());
@@ -4439,7 +4286,7 @@ void Process::BroadcastStructuredData(const StructuredData::ObjectSP &object_sp,
}
StructuredDataPluginSP
-Process::GetStructuredDataPlugin(const ConstString &type_name) const {
+Process::GetStructuredDataPlugin(ConstString type_name) const {
auto find_it = m_structured_data_plugin_map.find(type_name);
if (find_it != m_structured_data_plugin_map.end())
return find_it->second;
@@ -4471,9 +4318,7 @@ size_t Process::GetAsyncProfileData(char *buf, size_t buf_size, Status &error) {
return bytes_available;
}
-//------------------------------------------------------------------
// Process STDIO
-//------------------------------------------------------------------
size_t Process::GetSTDOUT(char *buf, size_t buf_size, Status &error) {
std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex);
@@ -4658,11 +4503,11 @@ protected:
void Process::SetSTDIOFileDescriptor(int fd) {
// First set up the Read Thread for reading/handling process I/O
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(
+ std::unique_ptr<ConnectionFileDescriptor> conn_up(
new ConnectionFileDescriptor(fd, true));
- if (conn_ap) {
- m_stdio_communication.SetConnection(conn_ap.release());
+ if (conn_up) {
+ m_stdio_communication.SetConnection(conn_up.release());
if (m_stdio_communication.IsConnected()) {
m_stdio_communication.SetReadThreadBytesReceivedCallback(
STDIOReadThreadBytesReceived, this);
@@ -4671,7 +4516,8 @@ void Process::SetSTDIOFileDescriptor(int fd) {
// Now read thread is set up, set up input reader.
if (!m_process_input_reader)
- m_process_input_reader.reset(new IOHandlerProcessSTDIO(this, fd));
+ m_process_input_reader =
+ std::make_shared<IOHandlerProcessSTDIO>(this, fd);
}
}
}
@@ -5096,7 +4942,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
}
got_event =
- listener_sp->GetEvent(event_sp, std::chrono::milliseconds(500));
+ listener_sp->GetEvent(event_sp, GetUtilityExpressionTimeout());
if (!got_event) {
if (log)
log->Printf("Process::RunThreadPlan(): didn't get any event after "
@@ -5327,7 +5173,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
log->PutCString("Process::RunThreadPlan(): Halt succeeded.");
got_event =
- listener_sp->GetEvent(event_sp, std::chrono::milliseconds(500));
+ listener_sp->GetEvent(event_sp, GetUtilityExpressionTimeout());
if (got_event) {
stop_state =
@@ -5530,7 +5376,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
event_explanation = ts.GetData();
}
- } while (0);
+ } while (false);
if (event_explanation)
log->Printf("Process::RunThreadPlan(): execution interrupted: %s %s",
@@ -5782,15 +5628,18 @@ void Process::DidExec() {
Target &target = GetTarget();
target.CleanupProcess();
target.ClearModules(false);
- m_dynamic_checkers_ap.reset();
+ m_dynamic_checkers_up.reset();
m_abi_sp.reset();
- m_system_runtime_ap.reset();
- m_os_ap.reset();
- m_dyld_ap.reset();
- m_jit_loaders_ap.reset();
+ m_system_runtime_up.reset();
+ m_os_up.reset();
+ m_dyld_up.reset();
+ m_jit_loaders_up.reset();
m_image_tokens.clear();
m_allocated_memory_cache.Clear();
- m_language_runtimes.clear();
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex);
+ m_language_runtimes.clear();
+ }
m_instrumentation_runtimes.clear();
m_thread_list.DiscardThreadPlans();
m_memory_cache.Clear(true);
@@ -5859,19 +5708,22 @@ void Process::ModulesDidLoad(ModuleList &module_list) {
// Iterate over a copy of this language runtime list in case the language
// runtime ModulesDidLoad somehow causes the language runtime to be
// unloaded.
- 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);
+ {
+ 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);
+ }
}
// If we don't have an operating system plug-in, try to load one since
// loading shared libraries might cause a new one to try and load
- if (!m_os_ap)
+ if (!m_os_up)
LoadOperatingSystemPlugin(false);
// Give structured-data plugins a chance to see the modified modules.
@@ -5945,7 +5797,8 @@ ThreadCollectionSP Process::GetHistoryThreads(lldb::addr_t addr) {
return threads;
}
- threads.reset(new ThreadCollection(memory_history->GetHistoryThreads(addr)));
+ threads = std::make_shared<ThreadCollection>(
+ memory_history->GetHistoryThreads(addr));
return threads;
}
@@ -6017,7 +5870,8 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr,
}
uint32_t branch_index =
- insn_list->GetIndexOfNextBranchInstruction(insn_offset, target);
+ insn_list->GetIndexOfNextBranchInstruction(insn_offset, target,
+ false /* ignore_calls*/);
if (branch_index == UINT32_MAX) {
return retval;
}
@@ -6061,7 +5915,7 @@ Process::GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) {
}
Status
-Process::ConfigureStructuredData(const ConstString &type_name,
+Process::ConfigureStructuredData(ConstString type_name,
const StructuredData::ObjectSP &config_sp) {
// If you get this, the Process-derived class needs to implement a method to
// enable an already-reported asynchronous structured data feature. See