diff options
| -rw-r--r-- | lldb/include/lldb/Target/Thread.h | 111 | ||||
| -rw-r--r-- | lldb/source/Target/Thread.cpp | 219 | ||||
| -rw-r--r-- | lldb/source/Target/ThreadPlanStepInRange.cpp | 10 | ||||
| -rw-r--r-- | lldb/source/lldb.cpp | 5 |
4 files changed, 340 insertions, 5 deletions
diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index 6bd4ee69a65..7a28e1ae8b1 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -13,6 +13,7 @@ #include "lldb/lldb-private.h" #include "lldb/Host/Mutex.h" #include "lldb/Core/UserID.h" +#include "lldb/Core/UserSettingsController.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/StackFrameList.h" #include "libunwind/include/libunwind.h" @@ -24,12 +25,102 @@ namespace lldb_private { +class ThreadInstanceSettings : public InstanceSettings +{ +public: + + ThreadInstanceSettings (UserSettingsController &owner, const char *name = NULL); + + ThreadInstanceSettings (const ThreadInstanceSettings &rhs); + + virtual + ~ThreadInstanceSettings (); + + ThreadInstanceSettings& + operator= (const ThreadInstanceSettings &rhs); + + + void + UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending); + + void + GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value); + + RegularExpression * + GetSymbolsToAvoidRegexp() + { + return m_avoid_regexp_ap.get(); + } + + static const ConstString & + StepAvoidRegexpVarName (); + +protected: + + void + CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending); + + const ConstString + CreateInstanceName (); + +private: + + std::auto_ptr<RegularExpression> m_avoid_regexp_ap; +}; + class Thread : public UserID, - public ExecutionContextScope + public ExecutionContextScope, + public ThreadInstanceSettings { public: + class ThreadSettingsController : public UserSettingsController + { + public: + + ThreadSettingsController (); + + virtual + ~ThreadSettingsController (); + + void + UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error&err); + + void + GetGlobalSettingsValue (const ConstString &var_name, + StringList &value); + + static SettingEntry global_settings_table[]; + static SettingEntry instance_settings_table[]; + + protected: + + lldb::InstanceSettingsSP + CreateNewInstanceSettings (); + + private: + + // Class-wide settings. + + DISALLOW_COPY_AND_ASSIGN (ThreadSettingsController); + }; + class RegisterCheckpoint { public: @@ -79,6 +170,9 @@ public: lldb::DataBufferSP m_data_sp; }; + static lldb::UserSettingsControllerSP + GetSettingsController (bool finish = false); + Thread (Process &process, lldb::tid_t tid); virtual ~Thread(); @@ -488,6 +582,21 @@ public: //------------------------------------------------------------------ void DumpThreadPlans (Stream *s) const; + + //------------------------------------------------------------------ + /// The regular expression returned determines symbols that this + /// thread won't stop in during "step-in" operations. + /// + /// @return + /// A pointer to a regular expression to compare against symbols, + /// or NULL if all symbols are allowed. + /// + //------------------------------------------------------------------ + RegularExpression * + GetSymbolsToAvoidRegexp() + { + return ThreadInstanceSettings::GetSymbolsToAvoidRegexp(); + } // Get the thread index ID. The index ID that is guaranteed to not be // re-used by a process. They start at 1 and increase with each new thread. diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 050c103b2ca..44b6f12d96c 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -12,6 +12,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/RegularExpression.h" #include "lldb/Host/Host.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ExecutionContext.h" @@ -39,6 +40,7 @@ using namespace lldb_private; Thread::Thread (Process &process, lldb::tid_t tid) : UserID (tid), + ThreadInstanceSettings (*(Thread::GetSettingsController().get())), m_process (process), m_public_stop_info_sp (), m_actual_stop_info_sp (), @@ -912,3 +914,220 @@ Thread::GetSP () { return m_process.GetThreadList().GetThreadSPForThreadPtr(this); } + +lldb::UserSettingsControllerSP +Thread::GetSettingsController (bool finish) +{ + static UserSettingsControllerSP g_settings_controller (new ThreadSettingsController); + static bool initialized = false; + + if (!initialized) + { + initialized = UserSettingsController::InitializeSettingsController (g_settings_controller, + Thread::ThreadSettingsController::global_settings_table, + Thread::ThreadSettingsController::instance_settings_table); + } + + if (finish) + { + UserSettingsController::FinalizeSettingsController (g_settings_controller); + g_settings_controller.reset(); + initialized = false; + } + + return g_settings_controller; +} + +//-------------------------------------------------------------- +// class Thread::ThreadSettingsController +//-------------------------------------------------------------- + +Thread::ThreadSettingsController::ThreadSettingsController () : + UserSettingsController ("thread", Process::GetSettingsController()) +{ + m_default_settings.reset (new ThreadInstanceSettings (*this, InstanceSettings::GetDefaultName().AsCString())); +} + +Thread::ThreadSettingsController::~ThreadSettingsController () +{ +} + +lldb::InstanceSettingsSP +Thread::ThreadSettingsController::CreateNewInstanceSettings () +{ + ThreadInstanceSettings *new_settings = new ThreadInstanceSettings (*(Thread::GetSettingsController().get())); + lldb::InstanceSettingsSP new_settings_sp (new_settings); + return new_settings_sp; +} + +//-------------------------------------------------------------- +// class ThreadInstanceSettings +//-------------------------------------------------------------- + +ThreadInstanceSettings::ThreadInstanceSettings (UserSettingsController &owner, const char *name) : + InstanceSettings (owner, (name == NULL ? CreateInstanceName().AsCString() : name)), + m_avoid_regexp_ap () +{ + // FIXME: This seems like generic code, why was it duplicated (with the slight difference that + // DebuggerInstanceSettings checks name, not m_instance_name below) in Process & Debugger? + if (m_instance_name != InstanceSettings::GetDefaultName()) + { + const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); + CopyInstanceSettings (pending_settings,false); + m_owner.RemovePendingSettings (m_instance_name); + } +} + +ThreadInstanceSettings::ThreadInstanceSettings (const ThreadInstanceSettings &rhs) : + InstanceSettings (*(Thread::GetSettingsController().get()), CreateInstanceName().AsCString()), + m_avoid_regexp_ap () +{ + if (m_instance_name != InstanceSettings::GetDefaultName()) + { + const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); + CopyInstanceSettings (pending_settings,false); + m_owner.RemovePendingSettings (m_instance_name); + } + if (rhs.m_avoid_regexp_ap.get() != NULL) + m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText())); +} + +ThreadInstanceSettings::~ThreadInstanceSettings () +{ +} + +ThreadInstanceSettings& +ThreadInstanceSettings::operator= (const ThreadInstanceSettings &rhs) +{ + if (this != &rhs) + { + if (rhs.m_avoid_regexp_ap.get() != NULL) + m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText())); + else + m_avoid_regexp_ap.reset(NULL); + } + + return *this; +} + + +void +ThreadInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending) +{ + if (var_name == StepAvoidRegexpVarName()) + { + std::string regexp_text; + if (m_avoid_regexp_ap.get() != NULL) + regexp_text.append (m_avoid_regexp_ap->GetText()); + UserSettingsController::UpdateStringVariable (op, regexp_text, value, err); + if (regexp_text.empty()) + m_avoid_regexp_ap.reset(); + else + { + m_avoid_regexp_ap.reset(new RegularExpression(regexp_text.c_str())); + + } + } +} + +void +ThreadInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending) +{ + if (new_settings.get() == NULL) + return; + + ThreadInstanceSettings *new_process_settings = (ThreadInstanceSettings *) new_settings.get(); + if (new_process_settings->GetSymbolsToAvoidRegexp() != NULL) + m_avoid_regexp_ap.reset (new RegularExpression (new_process_settings->GetSymbolsToAvoidRegexp()->GetText())); + else + m_avoid_regexp_ap.reset (); +} + +void +Thread::ThreadSettingsController::UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error&err) +{ + // Currently 'thread' does not have any global settings. +} + + +void +ThreadInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value) +{ + if (var_name == StepAvoidRegexpVarName()) + { + if (m_avoid_regexp_ap.get() != NULL) + { + std::string regexp_text("\""); + regexp_text.append(m_avoid_regexp_ap->GetText()); + regexp_text.append ("\""); + value.AppendString (regexp_text.c_str()); + } + + } + else + value.AppendString ("unrecognized variable name"); +} + +void +Thread::ThreadSettingsController::GetGlobalSettingsValue (const ConstString &var_name, + StringList &value) +{ + // Currently 'thread' does not have any global settings. +} + +const ConstString +ThreadInstanceSettings::CreateInstanceName () +{ + static int instance_count = 1; + StreamString sstr; + + sstr.Printf ("thread_%d", instance_count); + ++instance_count; + + const ConstString ret_val (sstr.GetData()); + return ret_val; +} + +const ConstString & +ThreadInstanceSettings::StepAvoidRegexpVarName () +{ + static ConstString run_args_var_name ("step-avoid-regexp"); + + return run_args_var_name; +} + +//-------------------------------------------------- +// ThreadSettingsController Variable Tables +//-------------------------------------------------- + +SettingEntry +Thread::ThreadSettingsController::global_settings_table[] = +{ + //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"}, + { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } +}; + + +SettingEntry +Thread::ThreadSettingsController::instance_settings_table[] = +{ + //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, + { "step-avoid-regexp", eSetVarTypeString, "", NULL, false, false, "A regular expression defining functions step-in won't stop in." }, + { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } +}; + diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp b/lldb/source/Target/ThreadPlanStepInRange.cpp index b95b35e5924..ecdb6fa471d 100644 --- a/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -156,7 +156,13 @@ ThreadPlanStepInRange::FrameMatchesAvoidRegexp () { StackFrame *frame = GetThread().GetStackFrameAtIndex(0).get(); - if (m_avoid_regexp_ap.get() != NULL) + RegularExpression *avoid_regexp_to_use; + + avoid_regexp_to_use = m_avoid_regexp_ap.get(); + if (avoid_regexp_to_use == NULL) + avoid_regexp_to_use = GetThread().GetSymbolsToAvoidRegexp(); + + if (avoid_regexp_to_use != NULL) { SymbolContext sc = frame->GetSymbolContext(eSymbolContextSymbol); if (sc.symbol != NULL) @@ -164,7 +170,7 @@ ThreadPlanStepInRange::FrameMatchesAvoidRegexp () const char *unnamed_symbol = "<UNKNOWN>"; const char *sym_name = sc.symbol->GetMangled().GetName().AsCString(unnamed_symbol); if (strcmp (sym_name, unnamed_symbol) != 0) - return m_avoid_regexp_ap->Execute(sym_name); + return avoid_regexp_to_use->Execute(sym_name); } } return false; diff --git a/lldb/source/lldb.cpp b/lldb/source/lldb.cpp index 30892d64623..025b949c9c0 100644 --- a/lldb/source/lldb.cpp +++ b/lldb/source/lldb.cpp @@ -76,7 +76,7 @@ lldb_private::Initialize () #endif Debugger::GetSettingsController (false); Process::GetSettingsController (false); - + Thread::GetSettingsController (false); #ifdef __linux__ ProcessLinux::Initialize(); #endif @@ -111,7 +111,8 @@ lldb_private::Terminate () Process::GetSettingsController (true); Debugger::GetSettingsController (true); - + Thread::GetSettingsController (true); + #ifdef __linux__ ProcessLinux::Terminate(); #endif |

