[Lldb-commits] [lldb] 18c25cd - [LLDB][GUI] Add Create Target form
Greg Clayton via lldb-commits
lldb-commits at lists.llvm.org
Thu Jul 29 13:28:03 PDT 2021
Author: Omar Emara
Date: 2021-07-29T13:27:53-07:00
New Revision: 18c25cd376b6ea38971abb407751cdf08e1e5622
URL: https://github.com/llvm/llvm-project/commit/18c25cd376b6ea38971abb407751cdf08e1e5622
DIFF: https://github.com/llvm/llvm-project/commit/18c25cd376b6ea38971abb407751cdf08e1e5622.diff
LOG: [LLDB][GUI] Add Create Target form
This patch adds a Create Target form for the LLDB GUI. Additionally, an
Arch Field was introduced to input an arch and the file and directory
fields now have a required property.
Reviewed By: clayborg
Differential Revision: https://reviews.llvm.org/D106192
Added:
Modified:
lldb/source/Core/IOHandlerCursesGUI.cpp
Removed:
################################################################################
diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp b/lldb/source/Core/IOHandlerCursesGUI.cpp
index 4bed788d48630..aab5dc9cd8017 100644
--- a/lldb/source/Core/IOHandlerCursesGUI.cpp
+++ b/lldb/source/Core/IOHandlerCursesGUI.cpp
@@ -36,6 +36,7 @@
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionGroupPlatform.h"
#if LLDB_ENABLE_CURSES
#include "lldb/Breakpoint/BreakpointLocation.h"
@@ -2651,6 +2652,185 @@ class ProcessAttachFormDelegate : public FormDelegate {
ProcessPluginFieldDelegate *m_plugin_field;
};
+class TargetCreateFormDelegate : public FormDelegate {
+public:
+ TargetCreateFormDelegate(Debugger &debugger) : m_debugger(debugger) {
+ m_executable_field = AddFileField("Executable", "", /*need_to_exist=*/true,
+ /*required=*/true);
+ m_core_file_field = AddFileField("Core File", "", /*need_to_exist=*/true,
+ /*required=*/false);
+ m_symbol_file_field = AddFileField(
+ "Symbol File", "", /*need_to_exist=*/true, /*required=*/false);
+ m_show_advanced_field = AddBooleanField("Show advanced settings.", false);
+ m_remote_file_field = AddFileField(
+ "Remote File", "", /*need_to_exist=*/false, /*required=*/false);
+ m_arch_field = AddArchField("Architecture", "", /*required=*/false);
+ m_platform_field = AddPlatformPluginField(debugger);
+ m_load_dependent_files_field =
+ AddChoicesField("Load Dependents", 3, GetLoadDependentFilesChoices());
+
+ AddAction("Create", [this](Window &window) { CreateTarget(window); });
+ }
+
+ std::string GetName() override { return "Create Target"; }
+
+ void UpdateFieldsVisibility() override {
+ if (m_show_advanced_field->GetBoolean()) {
+ m_remote_file_field->FieldDelegateShow();
+ m_arch_field->FieldDelegateShow();
+ m_platform_field->FieldDelegateShow();
+ m_load_dependent_files_field->FieldDelegateShow();
+ } else {
+ m_remote_file_field->FieldDelegateHide();
+ m_arch_field->FieldDelegateHide();
+ m_platform_field->FieldDelegateHide();
+ m_load_dependent_files_field->FieldDelegateHide();
+ }
+ }
+
+ static constexpr const char *kLoadDependentFilesNo = "No";
+ static constexpr const char *kLoadDependentFilesYes = "Yes";
+ static constexpr const char *kLoadDependentFilesExecOnly = "Executable only";
+
+ std::vector<std::string> GetLoadDependentFilesChoices() {
+ std::vector<std::string> load_depentents_options;
+ load_depentents_options.push_back(kLoadDependentFilesExecOnly);
+ load_depentents_options.push_back(kLoadDependentFilesYes);
+ load_depentents_options.push_back(kLoadDependentFilesNo);
+ return load_depentents_options;
+ }
+
+ LoadDependentFiles GetLoadDependentFiles() {
+ std::string choice = m_load_dependent_files_field->GetChoiceContent();
+ if (choice == kLoadDependentFilesNo)
+ return eLoadDependentsNo;
+ if (choice == kLoadDependentFilesYes)
+ return eLoadDependentsYes;
+ return eLoadDependentsDefault;
+ }
+
+ OptionGroupPlatform GetPlatformOptions() {
+ OptionGroupPlatform platform_options(false);
+ platform_options.SetPlatformName(m_platform_field->GetPluginName().c_str());
+ return platform_options;
+ }
+
+ TargetSP GetTarget() {
+ OptionGroupPlatform platform_options = GetPlatformOptions();
+ TargetSP target_sp;
+ Status status = m_debugger.GetTargetList().CreateTarget(
+ m_debugger, m_executable_field->GetPath(),
+ m_arch_field->GetArchString(), GetLoadDependentFiles(),
+ &platform_options, target_sp);
+
+ if (status.Fail()) {
+ SetError(status.AsCString());
+ return nullptr;
+ }
+
+ m_debugger.GetTargetList().SetSelectedTarget(target_sp);
+
+ return target_sp;
+ }
+
+ void SetSymbolFile(TargetSP target_sp) {
+ if (!m_symbol_file_field->IsSpecified())
+ return;
+
+ ModuleSP module_sp(target_sp->GetExecutableModule());
+ if (!module_sp)
+ return;
+
+ module_sp->SetSymbolFileFileSpec(
+ m_symbol_file_field->GetResolvedFileSpec());
+ }
+
+ void SetCoreFile(TargetSP target_sp) {
+ if (!m_core_file_field->IsSpecified())
+ return;
+
+ FileSpec core_file_spec = m_core_file_field->GetResolvedFileSpec();
+
+ FileSpec core_file_directory_spec;
+ core_file_directory_spec.GetDirectory() = core_file_spec.GetDirectory();
+ target_sp->AppendExecutableSearchPaths(core_file_directory_spec);
+
+ ProcessSP process_sp(target_sp->CreateProcess(
+ m_debugger.GetListener(), llvm::StringRef(), &core_file_spec, false));
+
+ if (!process_sp) {
+ SetError("Unable to find process plug-in for core file!");
+ return;
+ }
+
+ Status status = process_sp->LoadCore();
+ if (status.Fail()) {
+ SetError("Can't find plug-in for core file!");
+ return;
+ }
+ }
+
+ void SetRemoteFile(TargetSP target_sp) {
+ if (!m_remote_file_field->IsSpecified())
+ return;
+
+ ModuleSP module_sp(target_sp->GetExecutableModule());
+ if (!module_sp)
+ return;
+
+ FileSpec remote_file_spec = m_remote_file_field->GetFileSpec();
+ module_sp->SetPlatformFileSpec(remote_file_spec);
+ }
+
+ void RemoveTarget(TargetSP target_sp) {
+ m_debugger.GetTargetList().DeleteTarget(target_sp);
+ }
+
+ void CreateTarget(Window &window) {
+ ClearError();
+
+ bool all_fields_are_valid = CheckFieldsValidity();
+ if (!all_fields_are_valid)
+ return;
+
+ TargetSP target_sp = GetTarget();
+ if (HasError())
+ return;
+
+ SetSymbolFile(target_sp);
+ if (HasError()) {
+ RemoveTarget(target_sp);
+ return;
+ }
+
+ SetCoreFile(target_sp);
+ if (HasError()) {
+ RemoveTarget(target_sp);
+ return;
+ }
+
+ SetRemoteFile(target_sp);
+ if (HasError()) {
+ RemoveTarget(target_sp);
+ return;
+ }
+
+ window.GetParent()->RemoveSubWindow(&window);
+ }
+
+protected:
+ Debugger &m_debugger;
+
+ FileFieldDelegate *m_executable_field;
+ FileFieldDelegate *m_core_file_field;
+ FileFieldDelegate *m_symbol_file_field;
+ BooleanFieldDelegate *m_show_advanced_field;
+ FileFieldDelegate *m_remote_file_field;
+ ArchFieldDelegate *m_arch_field;
+ PlatformPluginFieldDelegate *m_platform_field;
+ ChoicesFieldDelegate *m_load_dependent_files_field;
+};
+
class MenuDelegate {
public:
virtual ~MenuDelegate() = default;
@@ -3078,15 +3258,15 @@ class Application {
bool done = false;
int delay_in_tenths_of_a_second = 1;
- // Alas the threading model in curses is a bit lame so we need to resort to
- // polling every 0.5 seconds. We could poll for stdin ourselves and then
- // pass the keys down but then we need to translate all of the escape
+ // Alas the threading model in curses is a bit lame so we need to resort
+ // to polling every 0.5 seconds. We could poll for stdin ourselves and
+ // then pass the keys down but then we need to translate all of the escape
// sequences ourselves. So we resort to polling for input because we need
// to receive async process events while in this loop.
- halfdelay(delay_in_tenths_of_a_second); // Poll using some number of tenths
- // of seconds seconds when calling
- // Window::GetChar()
+ halfdelay(delay_in_tenths_of_a_second); // Poll using some number of
+ // tenths of seconds seconds when
+ // calling Window::GetChar()
ListenerSP listener_sp(
Listener::MakeListener("lldb.IOHandler.curses.Application"));
@@ -4908,6 +5088,18 @@ class ApplicationDelegate : public WindowDelegate, public MenuDelegate {
MenuActionResult MenuDelegateAction(Menu &menu) override {
switch (menu.GetIdentifier()) {
+ case eMenuID_TargetCreate: {
+ WindowSP main_window_sp = m_app.GetMainWindow();
+ FormDelegateSP form_delegate_sp =
+ FormDelegateSP(new TargetCreateFormDelegate(m_debugger));
+ Rect bounds = main_window_sp->GetCenteredRect(80, 19);
+ WindowSP form_window_sp = main_window_sp->CreateSubWindow(
+ form_delegate_sp->GetName().c_str(), bounds, true);
+ WindowDelegateSP window_delegate_sp =
+ WindowDelegateSP(new FormWindowDelegate(form_delegate_sp));
+ form_window_sp->SetDelegate(window_delegate_sp);
+ return MenuActionResult::Handled;
+ }
case eMenuID_ThreadStepIn: {
ExecutionContext exe_ctx =
m_debugger.GetCommandInterpreter().GetExecutionContext();
More information about the lldb-commits
mailing list