summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/Debugger.cpp
diff options
context:
space:
mode:
authorCaroline Tice <ctice@apple.com>2010-09-04 00:03:46 +0000
committerCaroline Tice <ctice@apple.com>2010-09-04 00:03:46 +0000
commit3df9a8dfd7714dd6d03d5e1a93dbbfee736946bc (patch)
tree5855b97cff85c66d8e0236d43ed974c031a5bf3b /lldb/source/Core/Debugger.cpp
parent070ebd93d2765e5f88e9739edb673a1fee5cbe9c (diff)
downloadbcm5719-llvm-3df9a8dfd7714dd6d03d5e1a93dbbfee736946bc.tar.gz
bcm5719-llvm-3df9a8dfd7714dd6d03d5e1a93dbbfee736946bc.zip
This is a very large commit that completely re-does the way lldb
handles user settable internal variables (the equivalent of set/show variables in gdb). In addition to the basic infrastructure (most of which is defined in UserSettingsController.{h,cpp}, there are examples of two classes that have been set up to contain user settable variables (the Debugger and Process classes). The 'settings' command has been modified to be a command-subcommand structure, and the 'set', 'show' and 'append' commands have been moved into this sub-commabnd structure. The old StateVariable class has been completely replaced by this, and the state variable dictionary has been removed from the Command Interpreter. Places that formerly accessed the state variable mechanism have been modified to access the variables in this new structure instead (checking the term-width; getting/checking the prompt; etc.) Variables are attached to classes; there are two basic "flavors" of variables that can be set: "global" variables (static/class-wide), and "instance" variables (one per instance of the class). The whole thing has been set up so that any global or instance variable can be set at any time (e.g. on start up, in your .lldbinit file), whether or not any instances actually exist (there's a whole pending and default values mechanism to help deal with that). llvm-svn: 113041
Diffstat (limited to 'lldb/source/Core/Debugger.cpp')
-rw-r--r--lldb/source/Core/Debugger.cpp341
1 files changed, 341 insertions, 0 deletions
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 1cdd7ad4d87..9ccd2c16612 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -98,6 +98,25 @@ Debugger::GetSP ()
return debugger_sp;
}
+lldb::DebuggerSP
+Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
+{
+ lldb::DebuggerSP debugger_sp;
+
+ Mutex::Locker locker (GetDebuggerListMutex ());
+ DebuggerList &debugger_list = GetDebuggerList();
+ DebuggerList::iterator pos, end = debugger_list.end();
+
+ for (pos = debugger_list.begin(); pos != end; ++pos)
+ {
+ if ((*pos).get()->m_instance_name == instance_name)
+ {
+ debugger_sp = *pos;
+ break;
+ }
+ }
+ return debugger_sp;
+}
TargetSP
Debugger::FindTargetWithProcessID (lldb::pid_t pid)
@@ -118,6 +137,7 @@ Debugger::FindTargetWithProcessID (lldb::pid_t pid)
Debugger::Debugger () :
UserID (g_unique_id++),
+ DebuggerInstanceSettings (*(Debugger::GetSettingsController().get())),
m_input_comm("debugger.input"),
m_input_file (),
m_output_file (),
@@ -513,3 +533,324 @@ Debugger::FindDebuggerWithID (lldb::user_id_t id)
}
return debugger_sp;
}
+
+lldb::UserSettingsControllerSP &
+Debugger::GetSettingsController (bool finish)
+{
+ static lldb::UserSettingsControllerSP g_settings_controller (new DebuggerSettingsController);
+ static bool initialized = false;
+
+ if (!initialized)
+ {
+ UserSettingsControllerSP parent = g_settings_controller->GetParent();
+ if (parent)
+ parent->RegisterChild (g_settings_controller);
+
+ g_settings_controller->CreateSettingsVector (Debugger::DebuggerSettingsController::global_settings_table,
+ true);
+ g_settings_controller->CreateSettingsVector (Debugger::DebuggerSettingsController::instance_settings_table,
+ false);
+
+ g_settings_controller->InitializeGlobalVariables ();
+ g_settings_controller->CreateDefaultInstanceSettings ();
+ initialized = true;
+ }
+
+ if (finish)
+ {
+ UserSettingsControllerSP parent = g_settings_controller->GetParent();
+ if (parent)
+ parent->RemoveChild (g_settings_controller);
+ g_settings_controller.reset();
+ }
+ return g_settings_controller;
+}
+
+//--------------------------------------------------
+// class Debugger::DebuggerSettingsController
+//--------------------------------------------------
+
+Debugger::DebuggerSettingsController::DebuggerSettingsController () :
+ UserSettingsController ("", lldb::UserSettingsControllerSP()),
+ m_term_width (80)
+{
+ m_default_settings.reset (new DebuggerInstanceSettings (*this, InstanceSettings::GetDefaultName().AsCString()));
+}
+
+Debugger::DebuggerSettingsController::~DebuggerSettingsController ()
+{
+}
+
+
+lldb::InstanceSettingsSP
+Debugger::DebuggerSettingsController::CreateNewInstanceSettings ()
+{
+ DebuggerInstanceSettings *new_settings = new DebuggerInstanceSettings (*(Debugger::GetSettingsController().get()));
+ lldb::InstanceSettingsSP new_settings_sp (new_settings);
+ return new_settings_sp;
+}
+
+bool
+Debugger::DebuggerSettingsController::ValidTermWidthValue (const char *value, Error err)
+{
+ bool valid = true;
+
+ // Verify we have a value string.
+ if (value == NULL
+ || strlen (value) == 0)
+ {
+ valid = false;
+ err.SetErrorString ("Missing value. Can't set terminal width without a value.\n");
+ }
+
+ // Verify the string consists entirely of digits.
+ if (valid)
+ {
+ int len = strlen (value);
+ for (int i = 0; i < len; ++i)
+ if (! isdigit (value[i]))
+ {
+ valid = false;
+ err.SetErrorStringWithFormat ("'%s' is not a valid representation of an integer.\n", value);
+ }
+ }
+
+ // Verify the term-width is 'reasonable' (e.g. 10 <= width <= 250).
+ if (valid)
+ {
+ int width = atoi (value);
+ if (width < 10
+ || width > 250)
+ {
+ valid = false;
+ err.SetErrorString ("Invalid term-width value; value must be between 10 and 250.\n");
+ }
+ }
+
+ return valid;
+}
+
+
+//--------------------------------------------------
+// class DebuggerInstanceSettings
+//--------------------------------------------------
+
+DebuggerInstanceSettings::DebuggerInstanceSettings (UserSettingsController &owner, const char *name) :
+ InstanceSettings (owner, (name == NULL ? CreateInstanceName ().AsCString() : name)),
+ m_prompt (),
+ m_script_lang ()
+{
+ if (name == NULL)
+ {
+ const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
+ CopyInstanceSettings (pending_settings, false);
+ m_owner.RemovePendingSettings (m_instance_name);
+ }
+}
+
+DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) :
+ InstanceSettings (*(Debugger::GetSettingsController().get()), CreateInstanceName ().AsCString()),
+ m_prompt (rhs.m_prompt),
+ m_script_lang (rhs.m_script_lang)
+{
+ const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
+ CopyInstanceSettings (pending_settings, false);
+ m_owner.RemovePendingSettings (m_instance_name);
+}
+
+DebuggerInstanceSettings::~DebuggerInstanceSettings ()
+{
+}
+
+DebuggerInstanceSettings&
+DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs)
+{
+ if (this != &rhs)
+ {
+ m_prompt = rhs.m_prompt;
+ m_script_lang = rhs.m_script_lang;
+ }
+
+ return *this;
+}
+
+void
+DebuggerInstanceSettings::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 == PromptVarName())
+ {
+ UserSettingsController::UpdateStringVariable (op, m_prompt, value, err);
+ if (!pending)
+ {
+ BroadcastPromptChange (instance_name, m_prompt.c_str());
+ }
+ }
+ else if (var_name == ScriptLangVarName())
+ {
+ bool success;
+ m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault,
+ &success);
+ }
+}
+
+void
+Debugger::DebuggerSettingsController::UpdateGlobalVariable (const ConstString &var_name,
+ const char *index_value,
+ const char *value,
+ const SettingEntry &entry,
+ lldb::VarSetOperationType op,
+ Error &err)
+{
+ static ConstString term_width_name ("term-width");
+
+ if (var_name == term_width_name)
+ {
+ if (ValidTermWidthValue (value, err))
+ {
+ m_term_width = atoi (value);
+ }
+ }
+}
+
+void
+DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
+ const ConstString &var_name,
+ StringList &value)
+{
+ if (var_name == PromptVarName())
+ {
+ value.AppendString (m_prompt.c_str());
+
+ }
+ else if (var_name == ScriptLangVarName())
+ {
+ value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str());
+ }
+}
+
+void
+DebuggerInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
+ bool pending)
+{
+ if (new_settings.get() == NULL)
+ return;
+
+ DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get();
+
+ m_prompt = new_debugger_settings->m_prompt;
+ if (!pending)
+ BroadcastPromptChange (m_instance_name, m_prompt.c_str());
+
+ m_script_lang = new_debugger_settings->m_script_lang;
+}
+
+void
+Debugger::DebuggerSettingsController::GetGlobalSettingsValue (const ConstString &var_name,
+ StringList &value)
+{
+ static ConstString term_width_name ("term-width");
+
+ if (var_name == term_width_name)
+ {
+ StreamString width_str;
+ width_str.Printf ("%d", m_term_width);
+ value.AppendString (width_str.GetData());
+ }
+}
+
+bool
+DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt)
+{
+ std::string tmp_prompt;
+
+ if (new_prompt != NULL)
+ {
+ tmp_prompt = new_prompt ;
+ int len = tmp_prompt.size();
+ if (len > 1
+ && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"')
+ && (tmp_prompt[len-1] == tmp_prompt[0]))
+ {
+ tmp_prompt = tmp_prompt.substr(1,len-2);
+ }
+ len = tmp_prompt.size();
+ if (tmp_prompt[len-1] != ' ')
+ tmp_prompt.append(" ");
+ }
+ EventSP new_event_sp;
+ new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt,
+ new EventDataBytes (tmp_prompt.c_str())));
+
+ if (instance_name.GetLength() != 0)
+ {
+ // Set prompt for a particular instance.
+ Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get();
+ if (dbg != NULL)
+ {
+ dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp);
+ }
+ }
+
+ return true;
+}
+
+const ConstString
+DebuggerInstanceSettings::CreateInstanceName ()
+{
+ static int instance_count = 1;
+ StreamString sstr;
+
+ sstr.Printf ("debugger_%d", instance_count);
+ ++instance_count;
+
+ const ConstString ret_val (sstr.GetData());
+
+ return ret_val;
+}
+
+const ConstString &
+DebuggerInstanceSettings::PromptVarName ()
+{
+ static ConstString prompt_var_name ("prompt");
+
+ return prompt_var_name;
+}
+
+const ConstString &
+DebuggerInstanceSettings::ScriptLangVarName ()
+{
+ static ConstString script_lang_var_name ("script-lang");
+
+ return script_lang_var_name;
+}
+
+//--------------------------------------------------
+// DebuggerSettingsController Variable Tables
+//--------------------------------------------------
+
+
+SettingEntry
+Debugger::DebuggerSettingsController::global_settings_table[] =
+{
+ //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"},
+ { "term-width" , eSetVarTypeInt, "80" , NULL, false , false , "The maximum number of columns to use for displaying text." },
+ { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
+};
+
+
+
+SettingEntry
+Debugger::DebuggerSettingsController::instance_settings_table[] =
+{
+ //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"},
+ { "script-lang" , eSetVarTypeString, "python", NULL, false, false, "The script language to be used for evaluating user-written scripts." },
+ { "prompt" , eSetVarTypeString, "(lldb)", NULL, false, false, "The debugger command line prompt displayed for the user." },
+ { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
+};
OpenPOWER on IntegriCloud