aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Target/Target.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target/Target.cpp')
-rw-r--r--lldb/source/Target/Target.cpp380
1 files changed, 302 insertions, 78 deletions
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 6d33db6554d2..65064ecf75b1 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -51,9 +51,11 @@
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
@@ -105,13 +107,13 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch,
SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded");
SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed");
SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded");
-
+
CheckInWithManager();
- LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT),
- "{0} Target::Target()", static_cast<void *>(this));
+ LLDB_LOG(GetLog(LLDBLog::Object), "{0} Target::Target()",
+ static_cast<void *>(this));
if (target_arch.IsValid()) {
- LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET),
+ LLDB_LOG(GetLog(LLDBLog::Target),
"Target::Target created with architecture {0} ({1})",
target_arch.GetArchitectureName(),
target_arch.GetTriple().getTriple().c_str());
@@ -121,7 +123,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch,
}
Target::~Target() {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ Log *log = GetLog(LLDBLog::Object);
LLDB_LOG(log, "{0} Target::~Target()", static_cast<void *>(this));
DeleteCurrentProcess();
}
@@ -146,6 +148,8 @@ void Target::PrimeFromDummyTarget(Target &target) {
m_frame_recognizer_manager_up = std::make_unique<StackFrameRecognizerManager>(
*target.m_frame_recognizer_manager_up);
+
+ m_dummy_signals = target.m_dummy_signals;
}
void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) {
@@ -184,6 +188,8 @@ void Target::CleanupProcess() {
void Target::DeleteCurrentProcess() {
if (m_process_sp) {
+ // We dispose any active tracing sessions on the current process
+ m_trace_sp.reset();
m_section_load_history.Clear();
if (m_process_sp->IsAlive())
m_process_sp->Destroy(false);
@@ -284,6 +290,19 @@ void Target::Destroy() {
m_stop_hooks.clear();
m_stop_hook_next_id = 0;
m_suppress_stop_hooks = false;
+ Args signal_args;
+ ClearDummySignals(signal_args);
+}
+
+llvm::StringRef Target::GetABIName() const {
+ lldb::ABISP abi_sp;
+ if (m_process_sp)
+ abi_sp = m_process_sp->GetABI();
+ if (!abi_sp)
+ abi_sp = ABI::FindPlugin(ProcessSP(), GetArchitecture());
+ if (abi_sp)
+ return abi_sp->GetPluginName();
+ return {};
}
BreakpointList &Target::GetBreakpointList(bool internal) {
@@ -647,7 +666,7 @@ void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) {
else
m_breakpoint_list.Add(bp_sp, true);
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
if (log) {
StreamString s;
bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
@@ -743,8 +762,7 @@ void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) {
m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString());
if (!expected_vector) {
- LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS),
- "invalid breakpoint name: {}",
+ LLDB_LOG(GetLog(LLDBLog::Breakpoints), "invalid breakpoint name: {}",
llvm::toString(expected_vector.takeError()));
return;
}
@@ -789,7 +807,7 @@ static bool CheckIfWatchpointsSupported(Target *target, Status &error) {
WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
const CompilerType *type, uint32_t kind,
Status &error) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOGF(log,
"Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64
" type = %u)\n",
@@ -873,7 +891,7 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
}
void Target::RemoveAllowedBreakpoints() {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOGF(log, "Target::%s \n", __FUNCTION__);
m_breakpoint_list.RemoveAllowed(true);
@@ -882,7 +900,7 @@ void Target::RemoveAllowedBreakpoints() {
}
void Target::RemoveAllBreakpoints(bool internal_also) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,
internal_also ? "yes" : "no");
@@ -894,7 +912,7 @@ void Target::RemoveAllBreakpoints(bool internal_also) {
}
void Target::DisableAllBreakpoints(bool internal_also) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,
internal_also ? "yes" : "no");
@@ -904,14 +922,14 @@ void Target::DisableAllBreakpoints(bool internal_also) {
}
void Target::DisableAllowedBreakpoints() {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOGF(log, "Target::%s", __FUNCTION__);
m_breakpoint_list.SetEnabledAllowed(false);
}
void Target::EnableAllBreakpoints(bool internal_also) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,
internal_also ? "yes" : "no");
@@ -921,14 +939,14 @@ void Target::EnableAllBreakpoints(bool internal_also) {
}
void Target::EnableAllowedBreakpoints() {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOGF(log, "Target::%s", __FUNCTION__);
m_breakpoint_list.SetEnabledAllowed(true);
}
bool Target::RemoveBreakpointByID(break_id_t break_id) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
@@ -948,7 +966,7 @@ bool Target::RemoveBreakpointByID(break_id_t break_id) {
}
bool Target::DisableBreakpointByID(break_id_t break_id) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
@@ -966,7 +984,7 @@ bool Target::DisableBreakpointByID(break_id_t break_id) {
}
bool Target::EnableBreakpointByID(break_id_t break_id) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ Log *log = GetLog(LLDBLog::Breakpoints);
LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
@@ -1144,7 +1162,7 @@ Status Target::CreateBreakpointsFromFile(const FileSpec &file,
// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
// to end operations.
bool Target::RemoveAllWatchpoints(bool end_to_end) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
if (!end_to_end) {
@@ -1173,7 +1191,7 @@ bool Target::RemoveAllWatchpoints(bool end_to_end) {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
// to end operations.
bool Target::DisableAllWatchpoints(bool end_to_end) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
if (!end_to_end) {
@@ -1200,7 +1218,7 @@ bool Target::DisableAllWatchpoints(bool end_to_end) {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
// to end operations.
bool Target::EnableAllWatchpoints(bool end_to_end) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
if (!end_to_end) {
@@ -1226,7 +1244,7 @@ bool Target::EnableAllWatchpoints(bool end_to_end) {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool Target::ClearAllWatchpointHitCounts() {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {
@@ -1240,7 +1258,7 @@ bool Target::ClearAllWatchpointHitCounts() {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool Target::ClearAllWatchpointHistoricValues() {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {
@@ -1255,7 +1273,7 @@ bool Target::ClearAllWatchpointHistoricValues() {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list during
// these operations.
bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
if (!ProcessIsValid())
@@ -1272,7 +1290,7 @@ bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
if (!ProcessIsValid())
@@ -1291,7 +1309,7 @@ bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
if (!ProcessIsValid())
@@ -1310,7 +1328,7 @@ bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
WatchpointSP watch_to_remove_sp = m_watchpoint_list.FindByID(watch_id);
@@ -1327,7 +1345,7 @@ bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool Target::IgnoreWatchpointByID(lldb::watch_id_t watch_id,
uint32_t ignore_count) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ Log *log = GetLog(LLDBLog::Watchpoints);
LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
if (!ProcessIsValid())
@@ -1392,7 +1410,7 @@ void Target::DidExec() {
void Target::SetExecutableModule(ModuleSP &executable_sp,
LoadDependentFiles load_dependent_files) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
+ Log *log = GetLog(LLDBLog::Target);
ClearModules(false);
if (executable_sp) {
@@ -1457,7 +1475,7 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
}
bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
+ Log *log = GetLog(LLDBLog::Target);
bool missing_local_arch = !m_arch.GetSpec().IsValid();
bool replace_local_arch = true;
bool compatible_local_arch = false;
@@ -1470,11 +1488,11 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) {
if (other.IsValid()) {
auto platform_sp = GetPlatform();
if (!platform_sp ||
- !platform_sp->IsCompatibleArchitecture(other, false, nullptr)) {
+ !platform_sp->IsCompatibleArchitecture(other, {}, false, nullptr)) {
ArchSpec platform_arch;
- auto arch_platform_sp =
- Platform::GetPlatformForArchitecture(other, &platform_arch);
- if (arch_platform_sp) {
+ if (PlatformSP arch_platform_sp =
+ GetDebugger().GetPlatformList().GetOrCreate(other, {},
+ &platform_arch)) {
SetPlatform(arch_platform_sp);
if (platform_arch.IsValid())
other = platform_arch;
@@ -1545,7 +1563,7 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) {
}
bool Target::MergeArchitecture(const ArchSpec &arch_spec) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
+ Log *log = GetLog(LLDBLog::Target);
if (arch_spec.IsValid()) {
if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {
// The current target arch is compatible with "arch_spec", see if we can
@@ -1642,11 +1660,11 @@ void Target::SymbolsDidLoad(ModuleList &module_list) {
void Target::ModulesDidUnload(ModuleList &module_list, bool delete_locations) {
if (m_valid && module_list.GetSize()) {
UnloadModuleSections(module_list);
+ BroadcastEvent(eBroadcastBitModulesUnloaded,
+ new TargetEventData(this->shared_from_this(), module_list));
m_breakpoint_list.UpdateBreakpoints(module_list, false, delete_locations);
m_internal_breakpoint_list.UpdateBreakpoints(module_list, false,
delete_locations);
- BroadcastEvent(eBroadcastBitModulesUnloaded,
- new TargetEventData(this->shared_from_this(), module_list));
}
}
@@ -1684,7 +1702,6 @@ bool Target::ModuleIsExcludedForUnconstrainedSearches(
size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst,
size_t dst_len, Status &error) {
- LLDB_SCOPED_TIMER();
SectionSP section_sp(addr.GetSection());
if (section_sp) {
// If the contents of this section are encrypted, the on-disk file is
@@ -1720,6 +1737,12 @@ size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len,
lldb::addr_t *load_addr_ptr) {
error.Clear();
+ Address fixed_addr = addr;
+ if (ProcessIsValid())
+ if (const ABISP &abi = m_process_sp->GetABI())
+ fixed_addr.SetLoadAddress(abi->FixAnyAddress(addr.GetLoadAddress(this)),
+ this);
+
// if we end up reading this from process memory, we will fill this with the
// actual load address
if (load_addr_ptr)
@@ -1730,26 +1753,28 @@ size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len,
addr_t load_addr = LLDB_INVALID_ADDRESS;
addr_t file_addr = LLDB_INVALID_ADDRESS;
Address resolved_addr;
- if (!addr.IsSectionOffset()) {
+ if (!fixed_addr.IsSectionOffset()) {
SectionLoadList &section_load_list = GetSectionLoadList();
if (section_load_list.IsEmpty()) {
// No sections are loaded, so we must assume we are not running yet and
// anything we are given is a file address.
- file_addr = addr.GetOffset(); // "addr" doesn't have a section, so its
- // offset is the file address
+ file_addr =
+ fixed_addr.GetOffset(); // "fixed_addr" doesn't have a section, so
+ // its offset is the file address
m_images.ResolveFileAddress(file_addr, resolved_addr);
} else {
// 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
- load_addr = addr.GetOffset(); // "addr" doesn't have a section, so its
- // offset is the load address
+ load_addr =
+ fixed_addr.GetOffset(); // "fixed_addr" doesn't have a section, so
+ // its offset is the load address
section_load_list.ResolveLoadAddress(load_addr, resolved_addr);
}
}
if (!resolved_addr.IsValid())
- resolved_addr = addr;
+ resolved_addr = fixed_addr;
// If we read from the file cache but can't get as many bytes as requested,
// we keep the result around in this buffer, in case this result is the
@@ -2187,8 +2212,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify,
// In the meantime, just log that this has happened; just
// above we called ReplaceModule on the first one, and Remove
// on the rest.
- if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET |
- LIBLLDB_LOG_MODULES)) {
+ if (Log *log = GetLog(LLDBLog::Target | LLDBLog::Modules)) {
StreamString message;
auto dump = [&message](Module &dump_module) -> void {
UUID dump_uuid = dump_module.GetUUID();
@@ -2305,8 +2329,7 @@ std::vector<TypeSystem *> Target::GetScratchTypeSystems(bool create_on_demand) {
auto type_system_or_err =
GetScratchTypeSystemForLanguage(language, create_on_demand);
if (!type_system_or_err)
- LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET),
- type_system_or_err.takeError(),
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Target), type_system_or_err.takeError(),
"Language '{}' has expression support but no scratch type "
"system available",
Language::GetNameForLanguageType(language));
@@ -2322,8 +2345,7 @@ Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) {
auto type_system_or_err = GetScratchTypeSystemForLanguage(language, true);
if (auto err = type_system_or_err.takeError()) {
- LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET),
- std::move(err),
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),
"Unable to get persistent expression state for language {}",
Language::GetNameForLanguageType(language));
return nullptr;
@@ -2421,7 +2443,7 @@ ArchSpec Target::GetDefaultArchitecture() {
}
void Target::SetDefaultArchitecture(const ArchSpec &arch) {
- LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET),
+ LLDB_LOG(GetLog(LLDBLog::Target),
"setting target's default architecture to {0} ({1})",
arch.GetArchitectureName(), arch.GetTriple().getTriple());
Target::GetGlobalProperties().SetDefaultArchitecture(arch);
@@ -2480,8 +2502,8 @@ ExpressionResults Target::EvaluateExpression(
auto type_system_or_err =
GetScratchTypeSystemForLanguage(eLanguageTypeC);
if (auto err = type_system_or_err.takeError()) {
- LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET),
- std::move(err), "Unable to get scratch type system");
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),
+ "Unable to get scratch type system");
} else {
persistent_var_sp =
type_system_or_err->GetPersistentExpressionState()->GetVariable(expr);
@@ -2811,7 +2833,7 @@ bool Target::RunStopHooks() {
// We only compute should_stop against the hook results if a hook got to run
// which is why we have to do this conjoint test.
if ((hooks_ran && !should_stop) || auto_continue) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
Status error = m_process_sp->PrivateResume();
if (error.Success()) {
LLDB_LOG(log, "Resuming from RunStopHooks");
@@ -2967,7 +2989,7 @@ void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); }
Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
m_stats.SetLaunchOrAttachTime();
Status error;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
+ Log *log = GetLog(LLDBLog::Target);
LLDB_LOGF(log, "Target::%s() called for %s", __FUNCTION__,
launch_info.GetExecutableFile().GetPath().c_str());
@@ -3029,6 +3051,14 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
if (!launch_info.GetArchitecture().IsValid())
launch_info.GetArchitecture() = GetArchitecture();
+ // Hijacking events of the process to be created to be sure that all events
+ // until the first stop are intercepted (in case if platform doesn't define
+ // its own hijacking listener or if the process is created by the target
+ // manually, without the platform).
+ if (!launch_info.GetHijackListener())
+ launch_info.SetHijackListener(
+ Listener::MakeListener("lldb.Target.Launch.hijack"));
+
// 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 &&
@@ -3060,8 +3090,10 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
}
// Since we didn't have a platform launch the process, launch it here.
- if (m_process_sp)
+ if (m_process_sp) {
+ m_process_sp->HijackProcessEvents(launch_info.GetHijackListener());
error = m_process_sp->Launch(launch_info);
+ }
}
if (!m_process_sp && error.Success())
@@ -3070,35 +3102,35 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
if (!error.Success())
return error;
- auto at_exit =
- llvm::make_scope_exit([&]() { m_process_sp->RestoreProcessEvents(); });
+ bool rebroadcast_first_stop =
+ !synchronous_execution &&
+ launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
- if (!synchronous_execution &&
- launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
- return error;
+ assert(launch_info.GetHijackListener());
- ListenerSP hijack_listener_sp(launch_info.GetHijackListener());
- if (!hijack_listener_sp) {
- hijack_listener_sp = Listener::MakeListener("lldb.Target.Launch.hijack");
- launch_info.SetHijackListener(hijack_listener_sp);
- m_process_sp->HijackProcessEvents(hijack_listener_sp);
+ EventSP first_stop_event_sp;
+ state = m_process_sp->WaitForProcessToStop(llvm::None, &first_stop_event_sp,
+ rebroadcast_first_stop,
+ launch_info.GetHijackListener());
+ m_process_sp->RestoreProcessEvents();
+
+ if (rebroadcast_first_stop) {
+ assert(first_stop_event_sp);
+ m_process_sp->BroadcastEvent(first_stop_event_sp);
+ return error;
}
- switch (m_process_sp->WaitForProcessToStop(llvm::None, nullptr, false,
- hijack_listener_sp, nullptr)) {
+ switch (state) {
case eStateStopped: {
if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
break;
- if (synchronous_execution) {
+ if (synchronous_execution)
// Now we have handled the stop-from-attach, and we are just
// switching to a synchronous resume. So we should switch to the
// SyncResume hijacker.
- m_process_sp->RestoreProcessEvents();
m_process_sp->ResumeSynchronous(stream);
- } else {
- m_process_sp->RestoreProcessEvents();
+ else
error = m_process_sp->PrivateResume();
- }
if (!error.Success()) {
Status error2;
error2.SetErrorStringWithFormat(
@@ -3252,7 +3284,7 @@ Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) {
}
void Target::FinalizeFileActions(ProcessLaunchInfo &info) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log = GetLog(LLDBLog::Process);
// Finalize the file actions, and if none were given, default to opening up a
// pseudo terminal
@@ -3330,6 +3362,130 @@ void Target::FinalizeFileActions(ProcessLaunchInfo &info) {
}
}
+void Target::AddDummySignal(llvm::StringRef name, LazyBool pass, LazyBool notify,
+ LazyBool stop) {
+ if (name.empty())
+ return;
+ // Don't add a signal if all the actions are trivial:
+ if (pass == eLazyBoolCalculate && notify == eLazyBoolCalculate
+ && stop == eLazyBoolCalculate)
+ return;
+
+ auto& elem = m_dummy_signals[name];
+ elem.pass = pass;
+ elem.notify = notify;
+ elem.stop = stop;
+}
+
+bool Target::UpdateSignalFromDummy(UnixSignalsSP signals_sp,
+ const DummySignalElement &elem) {
+ if (!signals_sp)
+ return false;
+
+ int32_t signo
+ = signals_sp->GetSignalNumberFromName(elem.first().str().c_str());
+ if (signo == LLDB_INVALID_SIGNAL_NUMBER)
+ return false;
+
+ if (elem.second.pass == eLazyBoolYes)
+ signals_sp->SetShouldSuppress(signo, false);
+ else if (elem.second.pass == eLazyBoolNo)
+ signals_sp->SetShouldSuppress(signo, true);
+
+ if (elem.second.notify == eLazyBoolYes)
+ signals_sp->SetShouldNotify(signo, true);
+ else if (elem.second.notify == eLazyBoolNo)
+ signals_sp->SetShouldNotify(signo, false);
+
+ if (elem.second.stop == eLazyBoolYes)
+ signals_sp->SetShouldStop(signo, true);
+ else if (elem.second.stop == eLazyBoolNo)
+ signals_sp->SetShouldStop(signo, false);
+ return true;
+}
+
+bool Target::ResetSignalFromDummy(UnixSignalsSP signals_sp,
+ const DummySignalElement &elem) {
+ if (!signals_sp)
+ return false;
+ int32_t signo
+ = signals_sp->GetSignalNumberFromName(elem.first().str().c_str());
+ if (signo == LLDB_INVALID_SIGNAL_NUMBER)
+ return false;
+ bool do_pass = elem.second.pass != eLazyBoolCalculate;
+ bool do_stop = elem.second.stop != eLazyBoolCalculate;
+ bool do_notify = elem.second.notify != eLazyBoolCalculate;
+ signals_sp->ResetSignal(signo, do_stop, do_notify, do_pass);
+ return true;
+}
+
+void Target::UpdateSignalsFromDummy(UnixSignalsSP signals_sp,
+ StreamSP warning_stream_sp) {
+ if (!signals_sp)
+ return;
+
+ for (const auto &elem : m_dummy_signals) {
+ if (!UpdateSignalFromDummy(signals_sp, elem))
+ warning_stream_sp->Printf("Target signal '%s' not found in process\n",
+ elem.first().str().c_str());
+ }
+}
+
+void Target::ClearDummySignals(Args &signal_names) {
+ ProcessSP process_sp = GetProcessSP();
+ // The simplest case, delete them all with no process to update.
+ if (signal_names.GetArgumentCount() == 0 && !process_sp) {
+ m_dummy_signals.clear();
+ return;
+ }
+ UnixSignalsSP signals_sp;
+ if (process_sp)
+ signals_sp = process_sp->GetUnixSignals();
+
+ for (const Args::ArgEntry &entry : signal_names) {
+ const char *signal_name = entry.c_str();
+ auto elem = m_dummy_signals.find(signal_name);
+ // If we didn't find it go on.
+ // FIXME: Should I pipe error handling through here?
+ if (elem == m_dummy_signals.end()) {
+ continue;
+ }
+ if (signals_sp)
+ ResetSignalFromDummy(signals_sp, *elem);
+ m_dummy_signals.erase(elem);
+ }
+}
+
+void Target::PrintDummySignals(Stream &strm, Args &signal_args) {
+ strm.Printf("NAME PASS STOP NOTIFY\n");
+ strm.Printf("=========== ======= ======= =======\n");
+
+ auto str_for_lazy = [] (LazyBool lazy) -> const char * {
+ switch (lazy) {
+ case eLazyBoolCalculate: return "not set";
+ case eLazyBoolYes: return "true ";
+ case eLazyBoolNo: return "false ";
+ }
+ llvm_unreachable("Fully covered switch above!");
+ };
+ size_t num_args = signal_args.GetArgumentCount();
+ for (const auto &elem : m_dummy_signals) {
+ bool print_it = false;
+ for (size_t idx = 0; idx < num_args; idx++) {
+ if (elem.first() == signal_args.GetArgumentAtIndex(idx)) {
+ print_it = true;
+ break;
+ }
+ }
+ if (print_it) {
+ strm.Printf("%-11s ", elem.first().str().c_str());
+ strm.Printf("%s %s %s\n", str_for_lazy(elem.second.pass),
+ str_for_lazy(elem.second.stop),
+ str_for_lazy(elem.second.notify));
+ }
+ }
+}
+
// Target::StopHook
Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid)
: UserID(uid), m_target_sp(target_sp), m_specifier_sp(),
@@ -3645,6 +3801,22 @@ static constexpr OptionEnumValueElement g_import_std_module_value_types[] = {
},
};
+static constexpr OptionEnumValueElement
+ g_dynamic_class_info_helper_value_types[] = {
+ {
+ eDynamicClassInfoHelperAuto,
+ "auto",
+ "Automatically determine the most appropriate method for the "
+ "target OS.",
+ },
+ {eDynamicClassInfoHelperRealizedClassesStruct, "RealizedClassesStruct",
+ "Prefer using the realized classes struct."},
+ {eDynamicClassInfoHelperCopyRealizedClassList, "CopyRealizedClassList",
+ "Prefer using the CopyRealizedClassList API."},
+ {eDynamicClassInfoHelperGetRealizedClassList, "GetRealizedClassList",
+ "Prefer using the GetRealizedClassList API."},
+};
+
static constexpr OptionEnumValueElement g_hex_immediate_style_values[] = {
{
Disassembler::eHexStyleC,
@@ -3807,6 +3979,8 @@ TargetProperties::TargetProperties(Target *target)
m_collection_sp->SetValueChangedCallback(
ePropertyDisableSTDIO, [this] { DisableSTDIOValueChangedCallback(); });
+ m_collection_sp->SetValueChangedCallback(
+ ePropertySaveObjectsDir, [this] { CheckJITObjectsDir(); });
m_experimental_properties_up =
std::make_unique<TargetExperimentalProperties>();
m_collection_sp->AppendProperty(
@@ -3828,6 +4002,8 @@ TargetProperties::TargetProperties(Target *target)
m_collection_sp->AppendProperty(
ConstString("process"), ConstString("Settings specific to processes."),
true, Process::GetGlobalProperties().GetValueProperties());
+ m_collection_sp->SetValueChangedCallback(
+ ePropertySaveObjectsDir, [this] { CheckJITObjectsDir(); });
}
}
@@ -4139,6 +4315,13 @@ ImportStdModule TargetProperties::GetImportStdModule() const {
nullptr, idx, g_target_properties[idx].default_uint_value);
}
+DynamicClassInfoHelper TargetProperties::GetDynamicClassInfoHelper() const {
+ const uint32_t idx = ePropertyDynamicClassInfoHelper;
+ return (DynamicClassInfoHelper)
+ m_collection_sp->GetPropertyAtIndexAsEnumeration(
+ nullptr, idx, g_target_properties[idx].default_uint_value);
+}
+
bool TargetProperties::GetEnableAutoApplyFixIts() const {
const uint32_t idx = ePropertyAutoApplyFixIts;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
@@ -4157,10 +4340,42 @@ bool TargetProperties::GetEnableNotifyAboutFixIts() const {
nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
-bool TargetProperties::GetEnableSaveObjects() const {
- const uint32_t idx = ePropertySaveObjects;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_target_properties[idx].default_uint_value != 0);
+FileSpec TargetProperties::GetSaveJITObjectsDir() const {
+ const uint32_t idx = ePropertySaveObjectsDir;
+ return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
+}
+
+void TargetProperties::CheckJITObjectsDir() {
+ FileSpec new_dir = GetSaveJITObjectsDir();
+ if (!new_dir)
+ return;
+
+ const FileSystem &instance = FileSystem::Instance();
+ bool exists = instance.Exists(new_dir);
+ bool is_directory = instance.IsDirectory(new_dir);
+ std::string path = new_dir.GetPath(true);
+ bool writable = llvm::sys::fs::can_write(path);
+ if (exists && is_directory && writable)
+ return;
+
+ m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertySaveObjectsDir)
+ ->GetValue()
+ ->Clear();
+
+ std::string buffer;
+ llvm::raw_string_ostream os(buffer);
+ os << "JIT object dir '" << path << "' ";
+ if (!exists)
+ os << "does not exist";
+ else if (!is_directory)
+ os << "is not a directory";
+ else if (!writable)
+ os << "is not writable";
+
+ llvm::Optional<lldb::user_id_t> debugger_id = llvm::None;
+ if (m_target)
+ debugger_id = m_target->GetDebugger().GetID();
+ Debugger::ReportError(os.str(), debugger_id);
}
bool TargetProperties::GetEnableSyntheticValue() const {
@@ -4181,6 +4396,15 @@ uint32_t TargetProperties::GetMaximumNumberOfChildrenToDisplay() const {
nullptr, idx, g_target_properties[idx].default_uint_value);
}
+std::pair<uint32_t, bool>
+TargetProperties::GetMaximumDepthOfChildrenToDisplay() const {
+ const uint32_t idx = ePropertyMaxChildrenDepth;
+ auto *option_value =
+ m_collection_sp->GetPropertyAtIndexAsOptionValueUInt64(nullptr, idx);
+ bool is_default = !option_value->OptionWasSet();
+ return {option_value->GetCurrentValue(), is_default};
+}
+
uint32_t TargetProperties::GetMaximumSizeOfStringSummary() const {
const uint32_t idx = ePropertyMaxSummaryLength;
return m_collection_sp->GetPropertyAtIndexAsSInt64(