diff options
Diffstat (limited to 'lldb/source/Target/Target.cpp')
| -rw-r--r-- | lldb/source/Target/Target.cpp | 380 |
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 §ion_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( |
