diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp b/lldb/source/Core/IOHandlerCursesGUI.cpp
--- a/lldb/source/Core/IOHandlerCursesGUI.cpp
+++ b/lldb/source/Core/IOHandlerCursesGUI.cpp
@@ -40,6 +40,7 @@
 #if LLDB_ENABLE_CURSES
 #include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Core/ValueObjectRegister.h"
 #include "lldb/Symbol/Block.h"
@@ -607,9 +608,19 @@
       m_delete = del;
     }
   }
-  //
+
   // Get the rectangle in our parent window
   Rect GetBounds() const { return Rect(GetParentOrigin(), GetSize()); }
+
+  Rect GetCenteredRect(int width, int height) {
+    Size size = GetSize();
+    width = std::min(size.width, width);
+    height = std::min(size.height, height);
+    int x = (size.width - width) / 2;
+    int y = (size.height - height) / 2;
+    return Rect(Point(x, y), Size(width, height));
+  }
+
   int GetChar() { return ::wgetch(m_window); }
   Point GetParentOrigin() const { return Point(GetParentX(), GetParentY()); }
   int GetParentX() const { return getparx(m_window); }
@@ -1049,9 +1060,18 @@
 
   // Select the last element in the field if multiple elements exists.
   virtual void FieldDelegateSelectLastElement() { return; }
+
+  bool FieldDelegateIsVisible() { return m_is_visible; }
+
+  void FieldDelegateHide() { m_is_visible = false; }
+
+  void FieldDelegateShow() { m_is_visible = true; }
+
+protected:
+  bool m_is_visible = true;
 };
 
-typedef std::shared_ptr<FieldDelegate> FieldDelegateSP;
+typedef std::unique_ptr<FieldDelegate> FieldDelegateUP;
 
 class TextFieldDelegate : public FieldDelegate {
 public:
@@ -1226,7 +1246,6 @@
 
   void SetError(const char *error) { m_error = error; }
 
-  // Returns the text content of the field.
   const std::string &GetText() { return m_content; }
 
 protected:
@@ -1633,7 +1652,7 @@
       m_selection_type = SelectionType::NewButton;
   }
 
-  HandleCharResult SelecteNext(int key) {
+  HandleCharResult SelectNext(int key) {
     if (m_selection_type == SelectionType::NewButton)
       return eKeyNotHandled;
 
@@ -1706,7 +1725,7 @@
       }
       break;
     case '\t':
-      SelecteNext(key);
+      SelectNext(key);
       return eKeyHandled;
     case KEY_SHIFT_TAB:
       SelectPrevious(key);
@@ -1811,7 +1830,15 @@
 
   virtual ~FormDelegate() = default;
 
-  FieldDelegateSP &GetField(int field_index) { return m_fields[field_index]; }
+  virtual std::string GetName() = 0;
+
+  virtual void UpdateFieldsVisibility() { return; }
+
+  FieldDelegate *GetField(uint32_t field_index) {
+    if (field_index < m_fields.size())
+      return m_fields[field_index].get();
+    return nullptr;
+  }
 
   FormAction &GetAction(int action_index) { return m_actions[action_index]; }
 
@@ -1831,8 +1858,7 @@
 
   TextFieldDelegate *AddTextField(const char *label, const char *content) {
     TextFieldDelegate *delegate = new TextFieldDelegate(label, content);
-    FieldDelegateSP delegate_sp = FieldDelegateSP(delegate);
-    m_fields.push_back(delegate_sp);
+    m_fields.push_back(FieldDelegateUP(delegate));
     return delegate;
   }
 
@@ -1840,8 +1866,7 @@
                                   bool need_to_exist = true) {
     FileFieldDelegate *delegate =
         new FileFieldDelegate(label, content, need_to_exist);
-    FieldDelegateSP delegate_sp = FieldDelegateSP(delegate);
-    m_fields.push_back(delegate_sp);
+    m_fields.push_back(FieldDelegateUP(delegate));
     return delegate;
   }
 
@@ -1850,22 +1875,19 @@
                                             bool need_to_exist = true) {
     DirectoryFieldDelegate *delegate =
         new DirectoryFieldDelegate(label, content, need_to_exist);
-    FieldDelegateSP delegate_sp = FieldDelegateSP(delegate);
-    m_fields.push_back(delegate_sp);
+    m_fields.push_back(FieldDelegateUP(delegate));
     return delegate;
   }
 
   IntegerFieldDelegate *AddIntegerField(const char *label, int content) {
     IntegerFieldDelegate *delegate = new IntegerFieldDelegate(label, content);
-    FieldDelegateSP delegate_sp = FieldDelegateSP(delegate);
-    m_fields.push_back(delegate_sp);
+    m_fields.push_back(FieldDelegateUP(delegate));
     return delegate;
   }
 
   BooleanFieldDelegate *AddBooleanField(const char *label, bool content) {
     BooleanFieldDelegate *delegate = new BooleanFieldDelegate(label, content);
-    FieldDelegateSP delegate_sp = FieldDelegateSP(delegate);
-    m_fields.push_back(delegate_sp);
+    m_fields.push_back(FieldDelegateUP(delegate));
     return delegate;
   }
 
@@ -1873,8 +1895,7 @@
                                         std::vector<std::string> choices) {
     ChoicesFieldDelegate *delegate =
         new ChoicesFieldDelegate(label, height, choices);
-    FieldDelegateSP delegate_sp = FieldDelegateSP(delegate);
-    m_fields.push_back(delegate_sp);
+    m_fields.push_back(FieldDelegateUP(delegate));
     return delegate;
   }
 
@@ -1882,8 +1903,7 @@
   ListFieldDelegate<T> *AddListField(const char *label, T default_field) {
     ListFieldDelegate<T> *delegate =
         new ListFieldDelegate<T>(label, default_field);
-    FieldDelegateSP delegate_sp = FieldDelegateSP(delegate);
-    m_fields.push_back(delegate_sp);
+    m_fields.push_back(FieldDelegateUP(delegate));
     return delegate;
   }
 
@@ -1894,7 +1914,7 @@
   }
 
 protected:
-  std::vector<FieldDelegateSP> m_fields;
+  std::vector<FieldDelegateUP> m_fields;
   std::vector<FormAction> m_actions;
   // Optional error message. If empty, form is considered to have no error.
   std::string m_error;
@@ -1906,7 +1926,13 @@
 public:
   FormWindowDelegate(FormDelegateSP &delegate_sp)
       : m_delegate_sp(delegate_sp), m_selection_index(0),
-        m_selection_type(SelectionType::Field), m_first_visible_line(0) {}
+        m_first_visible_line(0) {
+    assert(m_delegate_sp->GetNumberOfActions() > 0);
+    if (m_delegate_sp->GetNumberOfFields() > 0)
+      m_selection_type = SelectionType::Field;
+    else
+      m_selection_type = SelectionType::Action;
+  }
 
   // Signify which element is selected. If a field or an action is selected,
   // then m_selection_index signifies the particular field or action that is
@@ -1947,6 +1973,8 @@
     int height = 0;
     height += GetErrorHeight();
     for (int i = 0; i < m_delegate_sp->GetNumberOfFields(); i++) {
+      if (!m_delegate_sp->GetField(i)->FieldDelegateIsVisible())
+        continue;
       height += m_delegate_sp->GetField(i)->FieldDelegateGetHeight();
     }
     height += GetActionsHeight();
@@ -1957,11 +1985,13 @@
     if (m_selection_type == SelectionType::Action)
       return ScrollContext(GetContentHeight() - 1);
 
-    FieldDelegateSP &field = m_delegate_sp->GetField(m_selection_index);
+    FieldDelegate *field = m_delegate_sp->GetField(m_selection_index);
     ScrollContext context = field->FieldDelegateGetScrollContext();
 
     int offset = GetErrorHeight();
     for (int i = 0; i < m_selection_index; i++) {
+      if (!m_delegate_sp->GetField(i)->FieldDelegateIsVisible())
+        continue;
       offset += m_delegate_sp->GetField(i)->FieldDelegateGetHeight();
     }
     context.Offset(offset);
@@ -2017,8 +2047,10 @@
     int width = surface.GetWidth();
     bool a_field_is_selected = m_selection_type == SelectionType::Field;
     for (int i = 0; i < m_delegate_sp->GetNumberOfFields(); i++) {
+      FieldDelegate *field = m_delegate_sp->GetField(i);
+      if (!field->FieldDelegateIsVisible())
+        continue;
       bool is_field_selected = a_field_is_selected && m_selection_index == i;
-      FieldDelegateSP &field = m_delegate_sp->GetField(i);
       int height = field->FieldDelegateGetHeight();
       Rect bounds = Rect(Point(0, line), Size(width, height));
       SubPad field_surface = SubPad(surface, bounds);
@@ -2079,10 +2111,12 @@
   }
 
   bool WindowDelegateDraw(Window &window, bool force) override {
+    m_delegate_sp->UpdateFieldsVisibility();
 
     window.Erase();
 
-    window.DrawTitleBox(window.GetName(), "Press Esc to cancel");
+    window.DrawTitleBox(m_delegate_sp->GetName().c_str(),
+                        "Press Esc to cancel");
 
     Rect content_bounds = window.GetFrame();
     content_bounds.Inset(2, 2);
@@ -2092,7 +2126,22 @@
     return true;
   }
 
-  HandleCharResult SelecteNext(int key) {
+  void SkipNextHiddenFields() {
+    while (true) {
+      if (m_delegate_sp->GetField(m_selection_index)->FieldDelegateIsVisible())
+        return;
+
+      if (m_selection_index == m_delegate_sp->GetNumberOfFields() - 1) {
+        m_selection_type = SelectionType::Action;
+        m_selection_index = 0;
+        return;
+      }
+
+      m_selection_index++;
+    }
+  }
+
+  HandleCharResult SelectNext(int key) {
     if (m_selection_type == SelectionType::Action) {
       if (m_selection_index < m_delegate_sp->GetNumberOfActions() - 1) {
         m_selection_index++;
@@ -2101,12 +2150,15 @@
 
       m_selection_index = 0;
       m_selection_type = SelectionType::Field;
-      FieldDelegateSP &next_field = m_delegate_sp->GetField(m_selection_index);
-      next_field->FieldDelegateSelectFirstElement();
+      SkipNextHiddenFields();
+      if (m_selection_type == SelectionType::Field) {
+        FieldDelegate *next_field = m_delegate_sp->GetField(m_selection_index);
+        next_field->FieldDelegateSelectFirstElement();
+      }
       return eKeyHandled;
     }
 
-    FieldDelegateSP &field = m_delegate_sp->GetField(m_selection_index);
+    FieldDelegate *field = m_delegate_sp->GetField(m_selection_index);
     if (!field->FieldDelegateOnLastOrOnlyElement()) {
       return field->FieldDelegateHandleChar(key);
     }
@@ -2120,14 +2172,32 @@
     }
 
     m_selection_index++;
+    SkipNextHiddenFields();
 
-    FieldDelegateSP &next_field = m_delegate_sp->GetField(m_selection_index);
-    next_field->FieldDelegateSelectFirstElement();
+    if (m_selection_type == SelectionType::Field) {
+      FieldDelegate *next_field = m_delegate_sp->GetField(m_selection_index);
+      next_field->FieldDelegateSelectFirstElement();
+    }
 
     return eKeyHandled;
   }
 
-  HandleCharResult SelectePrevious(int key) {
+  void SkipPreviousHiddenFields() {
+    while (true) {
+      if (m_delegate_sp->GetField(m_selection_index)->FieldDelegateIsVisible())
+        return;
+
+      if (m_selection_index == 0) {
+        m_selection_type = SelectionType::Action;
+        m_selection_index = 0;
+        return;
+      }
+
+      m_selection_index--;
+    }
+  }
+
+  HandleCharResult SelectPrevious(int key) {
     if (m_selection_type == SelectionType::Action) {
       if (m_selection_index > 0) {
         m_selection_index--;
@@ -2135,13 +2205,16 @@
       }
       m_selection_index = m_delegate_sp->GetNumberOfFields() - 1;
       m_selection_type = SelectionType::Field;
-      FieldDelegateSP &previous_field =
-          m_delegate_sp->GetField(m_selection_index);
-      previous_field->FieldDelegateSelectLastElement();
+      SkipPreviousHiddenFields();
+      if (m_selection_type == SelectionType::Field) {
+        FieldDelegate *previous_field =
+            m_delegate_sp->GetField(m_selection_index);
+        previous_field->FieldDelegateSelectLastElement();
+      }
       return eKeyHandled;
     }
 
-    FieldDelegateSP &field = m_delegate_sp->GetField(m_selection_index);
+    FieldDelegate *field = m_delegate_sp->GetField(m_selection_index);
     if (!field->FieldDelegateOnFirstOrOnlyElement()) {
       return field->FieldDelegateHandleChar(key);
     }
@@ -2155,10 +2228,13 @@
     }
 
     m_selection_index--;
+    SkipPreviousHiddenFields();
 
-    FieldDelegateSP &previous_field =
-        m_delegate_sp->GetField(m_selection_index);
-    previous_field->FieldDelegateSelectLastElement();
+    if (m_selection_type == SelectionType::Field) {
+      FieldDelegate *previous_field =
+          m_delegate_sp->GetField(m_selection_index);
+      previous_field->FieldDelegateSelectLastElement();
+    }
 
     return eKeyHandled;
   }
@@ -2166,9 +2242,11 @@
   void ExecuteAction(Window &window) {
     FormAction &action = m_delegate_sp->GetAction(m_selection_index);
     action.Execute(window);
-    m_first_visible_line = 0;
-    m_selection_index = 0;
-    m_selection_type = SelectionType::Field;
+    if (m_delegate_sp->HasError()) {
+      m_first_visible_line = 0;
+      m_selection_index = 0;
+      m_selection_type = SelectionType::Field;
+    }
   }
 
   HandleCharResult WindowDelegateHandleChar(Window &window, int key) override {
@@ -2182,9 +2260,9 @@
       }
       break;
     case '\t':
-      return SelecteNext(key);
+      return SelectNext(key);
     case KEY_SHIFT_TAB:
-      return SelectePrevious(key);
+      return SelectPrevious(key);
     case KEY_ESCAPE:
       window.GetParent()->RemoveSubWindow(&window);
       return eKeyHandled;
@@ -2195,7 +2273,7 @@
     // If the key wasn't handled and one of the fields is selected, pass the key
     // to that field.
     if (m_selection_type == SelectionType::Field) {
-      FieldDelegateSP &field = m_delegate_sp->GetField(m_selection_index);
+      FieldDelegate *field = m_delegate_sp->GetField(m_selection_index);
       return field->FieldDelegateHandleChar(key);
     }
 
@@ -2212,6 +2290,223 @@
   int m_first_visible_line;
 };
 
+///////////////////////////
+// Form Delegate Instances
+///////////////////////////
+
+class DetachOrKillProcessFormDelegate : public FormDelegate {
+public:
+  DetachOrKillProcessFormDelegate(Process *process) : m_process(process) {
+    SetError("There is a running process, either detach or kill it.");
+
+    m_keep_stopped_field =
+        AddBooleanField("Keep process stopped when detaching.", false);
+
+    AddAction("Detach", [this](Window &window) { Detach(window); });
+    AddAction("Kill", [this](Window &window) { Kill(window); });
+  }
+
+  std::string GetName() override { return "Detach/Kill Process"; }
+
+  void Kill(Window &window) {
+    Status destroy_status(m_process->Destroy(false));
+    if (destroy_status.Fail()) {
+      SetError("Failed to kill process.");
+      return;
+    }
+    window.GetParent()->RemoveSubWindow(&window);
+  }
+
+  void Detach(Window &window) {
+    Status detach_status(m_process->Detach(m_keep_stopped_field->GetBoolean()));
+    if (detach_status.Fail()) {
+      SetError("Failed to detach from process.");
+      return;
+    }
+    window.GetParent()->RemoveSubWindow(&window);
+  }
+
+protected:
+  Process *m_process;
+  BooleanFieldDelegate *m_keep_stopped_field;
+};
+
+class ProcessAttachFormDelegate : public FormDelegate {
+public:
+  ProcessAttachFormDelegate(Debugger &debugger, WindowSP main_window_sp)
+      : m_debugger(debugger), m_main_window_sp(main_window_sp) {
+    std::vector<std::string> types;
+    types.push_back(std::string("Name"));
+    types.push_back(std::string("PID"));
+    m_type_field = AddChoicesField("Attach By", 2, types);
+    m_pid_field = AddIntegerField("PID", 0);
+    m_name_field =
+        AddTextField("Process Name", GetDefaultProcessName().c_str());
+    m_continue_field = AddBooleanField("Continue once attached.", false);
+    m_wait_for_field = AddBooleanField("Wait for process to launch.", false);
+    m_include_existing_field =
+        AddBooleanField("Include existing processes.", false);
+    m_show_advanced_field = AddBooleanField("Show advanced settings.", false);
+    m_plugin_field =
+        AddChoicesField("Plugin Name", 3, GetPossiblePluginNames());
+
+    AddAction("Attach", [this](Window &window) { Attach(window); });
+  }
+
+  std::string GetName() override { return "Attach Process"; }
+
+  void UpdateFieldsVisibility() override {
+    if (m_type_field->GetChoiceContent() == "Name") {
+      m_pid_field->FieldDelegateHide();
+      m_name_field->FieldDelegateShow();
+      m_wait_for_field->FieldDelegateShow();
+      if (m_wait_for_field->GetBoolean())
+        m_include_existing_field->FieldDelegateShow();
+      else
+        m_include_existing_field->FieldDelegateHide();
+    } else {
+      m_pid_field->FieldDelegateShow();
+      m_name_field->FieldDelegateHide();
+      m_wait_for_field->FieldDelegateHide();
+      m_include_existing_field->FieldDelegateHide();
+    }
+    if (m_show_advanced_field->GetBoolean())
+      m_plugin_field->FieldDelegateShow();
+    else
+      m_plugin_field->FieldDelegateHide();
+  }
+
+  // Get the basename of the target's main executable if available, empty string
+  // otherwise.
+  std::string GetDefaultProcessName() {
+    Target *target = m_debugger.GetSelectedTarget().get();
+    if (target == nullptr)
+      return "";
+
+    ModuleSP module_sp = target->GetExecutableModule();
+    if (!module_sp->IsExecutable())
+      return "";
+
+    return module_sp->GetFileSpec().GetFilename().AsCString();
+  }
+
+  std::vector<std::string> GetPossiblePluginNames() {
+    std::vector<std::string> names;
+    names.push_back("<default>");
+
+    size_t i = 0;
+    while (auto name = PluginManager::GetProcessPluginNameAtIndex(i++))
+      names.push_back(name);
+    return names;
+  }
+
+  bool StopRunningProcess() {
+    ExecutionContext exe_ctx =
+        m_debugger.GetCommandInterpreter().GetExecutionContext();
+
+    if (!exe_ctx.HasProcessScope())
+      return false;
+
+    Process *process = exe_ctx.GetProcessPtr();
+    if (!(process && process->IsAlive()))
+      return false;
+
+    FormDelegateSP form_delegate_sp =
+        FormDelegateSP(new DetachOrKillProcessFormDelegate(process));
+    Rect bounds = m_main_window_sp->GetCenteredRect(85, 8);
+    WindowSP form_window_sp = m_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 true;
+  }
+
+  Target *GetTarget() {
+    Target *target = m_debugger.GetSelectedTarget().get();
+
+    if (target != nullptr)
+      return target;
+
+    TargetSP new_target_sp;
+    m_debugger.GetTargetList().CreateTarget(
+        m_debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
+
+    target = new_target_sp.get();
+
+    if (target == nullptr)
+      SetError("Failed to create target.");
+
+    m_debugger.GetTargetList().SetSelectedTarget(new_target_sp);
+
+    return target;
+  }
+
+  ProcessAttachInfo GetAttachInfo() {
+    ProcessAttachInfo attach_info;
+    attach_info.SetContinueOnceAttached(m_continue_field->GetBoolean());
+    if (m_type_field->GetChoiceContent() == "Name") {
+      attach_info.GetExecutableFile().SetFile(m_name_field->GetText(),
+                                              FileSpec::Style::native);
+      attach_info.SetWaitForLaunch(m_wait_for_field->GetBoolean());
+      if (m_wait_for_field->GetBoolean())
+        attach_info.SetIgnoreExisting(!m_include_existing_field->GetBoolean());
+    } else {
+      attach_info.SetProcessID(m_pid_field->GetInteger());
+    }
+    if (m_plugin_field->GetChoiceContent() != "<default>")
+      attach_info.SetProcessPluginName(m_plugin_field->GetChoiceContent());
+
+    return attach_info;
+  }
+
+  void Attach(Window &window) {
+    ClearError();
+
+    bool process_is_running = StopRunningProcess();
+    if (process_is_running)
+      return;
+
+    Target *target = GetTarget();
+    if (HasError())
+      return;
+
+    StreamString stream;
+    ProcessAttachInfo attach_info = GetAttachInfo();
+    Status status = target->Attach(attach_info, &stream);
+
+    if (status.Fail()) {
+      SetError(status.AsCString());
+      return;
+    }
+
+    ProcessSP process_sp(target->GetProcessSP());
+    if (!process_sp) {
+      SetError("Attached sucessfully but target has no process.");
+      return;
+    }
+
+    if (attach_info.GetContinueOnceAttached())
+      process_sp->Resume();
+
+    window.GetParent()->RemoveSubWindow(&window);
+  }
+
+protected:
+  Debugger &m_debugger;
+  WindowSP m_main_window_sp;
+
+  ChoicesFieldDelegate *m_type_field;
+  IntegerFieldDelegate *m_pid_field;
+  TextFieldDelegate *m_name_field;
+  BooleanFieldDelegate *m_continue_field;
+  BooleanFieldDelegate *m_wait_for_field;
+  BooleanFieldDelegate *m_include_existing_field;
+  BooleanFieldDelegate *m_show_advanced_field;
+  ChoicesFieldDelegate *m_plugin_field;
+};
+
 class MenuDelegate {
 public:
   virtual ~MenuDelegate() = default;
@@ -4459,6 +4754,19 @@
     }
       return MenuActionResult::Handled;
 
+    case eMenuID_ProcessAttach: {
+      WindowSP main_window_sp = m_app.GetMainWindow();
+      FormDelegateSP form_delegate_sp = FormDelegateSP(
+          new ProcessAttachFormDelegate(m_debugger, main_window_sp));
+      Rect bounds = main_window_sp->GetCenteredRect(80, 22);
+      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_ProcessContinue: {
       ExecutionContext exe_ctx =
           m_debugger.GetCommandInterpreter().GetExecutionContext();