+void MyFrame::OnKill(wxCommandEvent& WXUNUSED(event))
+{
+    long pid = wxGetNumberFromUser(_T("Please specify the process to kill"),
+                                   _T("Enter PID:"),
+                                   _T("Exec question"),
+                                   m_pidLast,
+                                   1, INT_MAX,
+                                   this);
+    if ( pid == -1 )
+    {
+        // cancelled
+        return;
+    }
+
+    static const wxString signalNames[] =
+    {
+        _T("Just test (SIGNONE)"),
+        _T("Hangup (SIGHUP)"),
+        _T("Interrupt (SIGINT)"),
+        _T("Quit (SIGQUIT)"),
+        _T("Illegal instruction (SIGILL)"),
+        _T("Trap (SIGTRAP)"),
+        _T("Abort (SIGABRT)"),
+        _T("Emulated trap (SIGEMT)"),
+        _T("FP exception (SIGFPE)"),
+        _T("Kill (SIGKILL)"),
+        _T("Bus (SIGBUS)"),
+        _T("Segment violation (SIGSEGV)"),
+        _T("System (SIGSYS)"),
+        _T("Broken pipe (SIGPIPE)"),
+        _T("Alarm (SIGALRM)"),
+        _T("Terminate (SIGTERM)"),
+    };
+
+    int sig = wxGetSingleChoiceIndex(_T("How to kill the process?"),
+                                     _T("Exec question"),
+                                     WXSIZEOF(signalNames), signalNames,
+                                     this);
+    switch ( sig )
+    {
+        default:
+            wxFAIL_MSG( _T("unexpected return value") );
+            // fall through
+
+        case -1:
+            // cancelled
+            return;
+
+        case wxSIGNONE:
+        case wxSIGHUP:
+        case wxSIGINT:
+        case wxSIGQUIT:
+        case wxSIGILL:
+        case wxSIGTRAP:
+        case wxSIGABRT:
+        case wxSIGEMT:
+        case wxSIGFPE:
+        case wxSIGKILL:
+        case wxSIGBUS:
+        case wxSIGSEGV:
+        case wxSIGSYS:
+        case wxSIGPIPE:
+        case wxSIGALRM:
+        case wxSIGTERM:
+            break;
+    }
+
+    if ( sig == 0 )
+    {
+        if ( wxProcess::Exists(pid) )
+            wxLogStatus(_T("Process %d is running."), pid);
+        else
+            wxLogStatus(_T("No process with pid = %d."), pid);
+    }
+    else // not SIGNONE
+    {
+        wxKillError rc = wxProcess::Kill(pid, (wxSignal)sig);
+        if ( rc == wxKILL_OK )
+        {
+            wxLogStatus(_T("Process %d killed with signal %d."), pid, sig);
+        }
+        else
+        {
+            static const wxChar *errorText[] =
+            {
+                _T(""), // no error
+                _T("signal not supported"),
+                _T("permission denied"),
+                _T("no such process"),
+                _T("unspecified error"),
+            };
+
+            wxLogStatus(_T("Failed to kill process %d with signal %d: %s"),
+                        pid, sig, errorText[rc]);
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+// event handlers: exec menu
+// ----------------------------------------------------------------------------
+