diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -58,7 +58,11 @@ template struct Range; -// ProcessProperties +class ProcessExperimentalProperties : public Properties { +public: + ProcessExperimentalProperties(); +}; + class ProcessProperties : public Properties { public: // Pass nullptr for "process" if the ProcessProperties are to be the global @@ -84,9 +88,12 @@ bool GetWarningsOptimization() const; bool GetStopOnExec() const; std::chrono::seconds GetUtilityExpressionTimeout() const; + bool GetOSPluginReportsAllThreads() const; + void SetOSPluginReportsAllThreads(bool does_report); protected: Process *m_process; // Can be nullptr for global ProcessProperties + std::unique_ptr m_experimental_properties_up; }; typedef std::shared_ptr ProcessPropertiesSP; diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -64,7 +64,6 @@ eLoadDependentsNo, }; -// TargetProperties class TargetExperimentalProperties : public Properties { public: TargetExperimentalProperties(); @@ -207,10 +206,6 @@ void SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b); - bool GetOSPluginReportsAllThreads() const; - - void SetOSPluginReportsAllThreads(bool does_report); - void SetRequireHardwareBreakpoints(bool b); bool GetRequireHardwareBreakpoints() const; diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -120,8 +120,30 @@ enum { #define LLDB_PROPERTIES_process #include "TargetPropertiesEnum.inc" + ePropertyExperimental, }; +#define LLDB_PROPERTIES_process_experimental +#include "TargetProperties.inc" + +enum { +#define LLDB_PROPERTIES_process_experimental +#include "TargetPropertiesEnum.inc" +}; + +class ProcessExperimentalOptionValueProperties : public OptionValueProperties { +public: + ProcessExperimentalOptionValueProperties() + : OptionValueProperties( + ConstString(Properties::GetExperimentalSettingsName())) {} +}; + +ProcessExperimentalProperties::ProcessExperimentalProperties() + : Properties(OptionValuePropertiesSP( + new ProcessExperimentalOptionValueProperties())) { + m_collection_sp->Initialize(g_process_experimental_properties); +} + ProcessProperties::ProcessProperties(lldb_private::Process *process) : Properties(), m_process(process) // Can be nullptr for global ProcessProperties @@ -141,6 +163,13 @@ ePropertyPythonOSPluginPath, [this] { m_process->LoadOperatingSystemPlugin(true); }); } + + m_experimental_properties_up.reset(new ProcessExperimentalProperties()); + m_collection_sp->AppendProperty( + ConstString(Properties::GetExperimentalSettingsName()), + ConstString("Experimental settings - setting these won't produce " + "errors if the setting is not present."), + true, m_experimental_properties_up->GetValueProperties()); } ProcessProperties::~ProcessProperties() = default; @@ -242,6 +271,29 @@ return std::chrono::seconds(value); } +bool ProcessProperties::GetOSPluginReportsAllThreads() const { + const bool fail_value = true; + const Property *exp_property = + m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyExperimental); + OptionValueProperties *exp_values = + exp_property->GetValue()->GetAsProperties(); + if (!exp_values) + return fail_value; + + return exp_values->GetPropertyAtIndexAsBoolean( + nullptr, ePropertyOSPluginReportsAllThreads, fail_value); +} + +void ProcessProperties::SetOSPluginReportsAllThreads(bool does_report) { + const Property *exp_property = + m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyExperimental); + OptionValueProperties *exp_values = + exp_property->GetValue()->GetAsProperties(); + if (exp_values) + exp_values->SetPropertyAtIndexAsBoolean( + nullptr, ePropertyOSPluginReportsAllThreads, does_report); +} + Status ProcessLaunchCommandOptions::SetOptionValue( uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { @@ -1213,7 +1265,7 @@ // See if the OS plugin reports all threads. If it does, then // it is safe to clear unseen thread's plans here. Otherwise we // should preserve them in case they show up again: - clear_unused_threads = GetTarget().GetOSPluginReportsAllThreads(); + clear_unused_threads = GetOSPluginReportsAllThreads(); // Turn off dynamic types to ensure we don't run any expressions. // Objective-C can run an expression to determine if a SBValue is a diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -3373,11 +3373,11 @@ }; // TargetProperties -#define LLDB_PROPERTIES_experimental +#define LLDB_PROPERTIES_target_experimental #include "TargetProperties.inc" enum { -#define LLDB_PROPERTIES_experimental +#define LLDB_PROPERTIES_target_experimental #include "TargetPropertiesEnum.inc" }; @@ -3391,7 +3391,7 @@ TargetExperimentalProperties::TargetExperimentalProperties() : Properties(OptionValuePropertiesSP( new TargetExperimentalOptionValueProperties())) { - m_collection_sp->Initialize(g_experimental_properties); + m_collection_sp->Initialize(g_target_experimental_properties); } // TargetProperties @@ -3487,34 +3487,6 @@ true); } -bool TargetProperties::GetOSPluginReportsAllThreads() const { - const bool fail_value = true; - const Property *exp_property = - m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyExperimental); - OptionValueProperties *exp_values = - exp_property->GetValue()->GetAsProperties(); - if (!exp_values) - return fail_value; - - return - exp_values->GetPropertyAtIndexAsBoolean(nullptr, - ePropertyOSPluginReportsAllThreads, - fail_value); -} - -void TargetProperties::SetOSPluginReportsAllThreads(bool does_report) { - const Property *exp_property = - m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyExperimental); - OptionValueProperties *exp_values = - exp_property->GetValue()->GetAsProperties(); - if (exp_values) - exp_values->SetPropertyAtIndexAsBoolean(nullptr, - ePropertyOSPluginReportsAllThreads, - does_report); -} - - - ArchSpec TargetProperties::GetDefaultArchitecture() const { OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch( nullptr, ePropertyDefaultArch); @@ -4084,7 +4056,7 @@ return module_list; } -std::recursive_mutex &Target::GetAPIMutex() { +std::recursive_mutex &Target::GetAPIMutex() { if (GetProcessSP() && GetProcessSP()->CurrentThreadIsPrivateStateThread()) return m_private_mutex; else diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td --- a/lldb/source/Target/TargetProperties.td +++ b/lldb/source/Target/TargetProperties.td @@ -1,13 +1,9 @@ include "../../include/lldb/Core/PropertiesBase.td" -let Definition = "experimental" in { +let Definition = "target_experimental" in { def InjectLocalVars : Property<"inject-local-vars", "Boolean">, Global, DefaultTrue, Desc<"If true, inject local variables explicitly into the expression text. This will fix symbol resolution when there are name collisions between ivars and local variables. But it can make expressions run much more slowly.">; - def OSPluginReportsAllThreads: Property<"os-plugin-reports-all-threads", "Boolean">, - Global, - DefaultTrue, - Desc<"Set to False if your OS Plugins doesn't report all threads on each stop.">; } let Definition = "target" in { @@ -169,6 +165,13 @@ Desc<"Always install the main executable when connected to a remote platform.">; } +let Definition = "process_experimental" in { + def OSPluginReportsAllThreads: Property<"os-plugin-reports-all-threads", "Boolean">, + Global, + DefaultTrue, + Desc<"Set to False if your OS Plugins doesn't report all threads on each stop.">; +} + let Definition = "process" in { def DisableMemCache: Property<"disable-memory-cache", "Boolean">, DefaultFalse, diff --git a/lldb/test/API/functionalities/plugins/python_os_plugin/stepping_plugin_threads/TestOSPluginStepping.py b/lldb/test/API/functionalities/plugins/python_os_plugin/stepping_plugin_threads/TestOSPluginStepping.py --- a/lldb/test/API/functionalities/plugins/python_os_plugin/stepping_plugin_threads/TestOSPluginStepping.py +++ b/lldb/test/API/functionalities/plugins/python_os_plugin/stepping_plugin_threads/TestOSPluginStepping.py @@ -44,7 +44,7 @@ """Test that the Python operating system plugin works correctly""" # Our OS plugin does NOT report all threads: - result = self.dbg.HandleCommand("settings set target.experimental.os-plugin-reports-all-threads false") + result = self.dbg.HandleCommand("settings set process.experimental.os-plugin-reports-all-threads false") python_os_plugin_path = os.path.join(self.getSourceDir(), "operating_system.py")