[Lldb-commits] [lldb] r202154 - Reapply r184270 by Jim Ingham to avoid abort on FreeBSD

Greg Clayton gclayton at apple.com
Wed Feb 26 14:53:10 PST 2014


Ed,

I am about the submit a better long term fix. The IOHandlerProcessSTDIO class already has a pipe that is used to interrupt the IOHandler, so we can just write a different byte to it during interrupt ('i') and then switch off the character that is read from the pipe. This keeps the signal handler clean as it just basically calls "write(fd, &'i', 1)" and then gets out. The other thread that is running the IOHandler will then interrupt the process:


Index: source/Target/Process.cpp
===================================================================
--- source/Target/Process.cpp	(revision 202305)
+++ source/Target/Process.cpp	(working copy)
@@ -4793,7 +4793,16 @@
                             // Consume the interrupt byte
                             n = 1;
                             m_pipe_read.Read (&ch, n);
-                            SetIsDone(true);
+                            switch (ch)
+                            {
+                                case 'q':
+                                    SetIsDone(true);
+                                    break;
+                                case 'i':
+                                    if (StateIsRunningState(m_process->GetState()))
+                                        m_process->Halt();
+                                    break;
+                            }
                         }
                     }
                 }
@@ -4829,15 +4838,28 @@
     Cancel ()
     {
         size_t n = 1;
-        char ch = 'q';
+        char ch = 'q';  // Send 'q' for quit
         m_pipe_write.Write (&ch, n);
     }
 
     virtual void
     Interrupt ()
     {
+#ifdef _MSC_VER
+        // Windows doesn't support pipes, so we will send an async interrupt
+        // event to stop the process
         if (StateIsRunningState(m_process->GetState()))
             m_process->SendAsyncInterrupt();
+#else
+        // Do only things that are safe to do in an interrupt context (like in
+        // a SIGINT handler), like write 1 byte to a file descriptor. This will
+        // interrupt the IOHandlerProcessSTDIO::Run() and we can look at the byte
+        // that was written to the pipe and then call m_process->Halt() from a
+        // much safer location in code.
+        size_t n = 1;
+        char ch = 'i'; // Send 'i' for interrupt
+        m_pipe_write.Write (&ch, n);
+#endif
     }
     
     virtual void

On Feb 25, 2014, at 6:20 AM, Ed Maste <emaste at freebsd.org> wrote:

> Author: emaste
> Date: Tue Feb 25 08:20:14 2014
> New Revision: 202154
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=202154&view=rev
> Log:
> Reapply r184270 by Jim Ingham to avoid abort on FreeBSD
> 
>  Don't actually Halt in the Interrupt handler for the Process, just
>  send an AsyncInterrupt.  That's actually not async-signal-clean, but
>  it is a lot safer than Halt...
> 
> The underlying problem is actually a nested pthread_cond_wait from the
> signal handler.  Note frames 4, 13, 18 in the backtrace of the aborting
> path below.
> 
>    frame #1: 0x000000080715fff9 libc.so.7`abort + 73 at abort.c:65
>    frame #2: 0x0000000805d20fda libthr.so.3`_thread_exit(fname=<unavailable>, lineno=<unavailable>, msg=<unavailable>) + 58 at thr_exit.c:182
>    frame #3: 0x0000000805d1fdc8 libthr.so.3`cond_wait_common [inlined] cond_wait_user(mp=<unavailable>, abstime=<unavailable>, cancel=<unavailable>) + 936 at thr_cond.c:223
>    frame #4: 0x0000000805d1fd5b libthr.so.3`cond_wait_common(cond=<unavailable>, mutex=<unavailable>, abstime=<unavailable>, cancel=<unavailable>) + 827 at thr_cond.c:311
>    frame #5: 0x00000008013450b5 liblldb.so.3.5`lldb_private::Condition::Wait(lldb_private::Mutex&, lldb_private::TimeValue const*, bool*) + 117
>    frame #6: 0x00000008013411e8 liblldb.so.3.5`lldb_private::Predicate<bool>::WaitForValueEqualTo(bool, lldb_private::TimeValue const*, bool*) + 200
>    frame #7: 0x00000008013eb34c liblldb.so.3.5`lldb_private::Listener::WaitForEventsInternal(lldb_private::TimeValue const*, lldb_private::Broadcaster*, lldb_private::ConstString const*, unsigned int, unsigned int, std::__1::shared_ptr<lldb_private::Event>&) + 876
>    frame #8: 0x00000008013eb751 liblldb.so.3.5`lldb_private::Listener::WaitForEvent(lldb_private::TimeValue const*, std::__1::shared_ptr<lldb_private::Event>&) + 81
>    frame #9: 0x00000008017c5bcf liblldb.so.3.5`lldb_private::Process::Halt(bool) + 783
>    frame #10: 0x00000008017def3a liblldb.so.3.5`IOHandlerProcessSTDIO::Interrupt() + 74
>    frame #11: 0x00000008013823d3 liblldb.so.3.5`lldb_private::Debugger::DispatchInputInterrupt() + 115
>    frame #12: 0x00000008011d69c5 liblldb.so.3.5`lldb::SBDebugger::DispatchInputInterrupt() + 69
>    frame #13: 0x000000000040b254 lldb`sigint_handler(int) + 68
>    frame #14: 0x0000000805d1b3da libthr.so.3`handle_signal(actp=<unavailable>, sig=<unavailable>, info=<unavailable>, ucp=<unavailable>) + 234 at thr_sig.c:240
>    frame #15: 0x0000000805d1afc2 libthr.so.3`thr_sighandler(sig=<unavailable>, info=<unavailable>, _ucp=<unavailable>) + 306 at thr_sig.c:183
>    frame #16: 0x00007ffffffff003
>    frame #17: 0x0000000805d1fc7e libthr.so.3`cond_wait_common [inlined] cond_wait_user(mp=<unavailable>, abstime=<unavailable>, cancel=1) + 239 at thr_cond.c:255
>    frame #18: 0x0000000805d1fb8f libthr.so.3`cond_wait_common(cond=<unavailable>, mutex=<unavailable>, abstime=0x0000000000000000, cancel=1) + 367 at thr_cond.c:311
>    frame #19: 0x00000008013450d2 liblldb.so.3.5`lldb_private::Condition::Wait(lldb_private::Mutex&, lldb_private::TimeValue const*, bool*) + 146
> 
> Modified:
>    lldb/trunk/source/Target/Process.cpp
> 
> Modified: lldb/trunk/source/Target/Process.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=202154&r1=202153&r2=202154&view=diff
> ==============================================================================
> --- lldb/trunk/source/Target/Process.cpp (original)
> +++ lldb/trunk/source/Target/Process.cpp Tue Feb 25 08:20:14 2014
> @@ -4837,7 +4837,7 @@ public:
>     Interrupt ()
>     {
>         if (StateIsRunningState(m_process->GetState()))
> -            m_process->Halt();
> +            m_process->SendAsyncInterrupt();
>     }
> 
>     virtual void
> 
> 
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits




More information about the lldb-commits mailing list