[Lldb-commits] [PATCH] D12968: Fix for lldb-mi crash in Listener code if -exec-abort MI command was invoked without getting process stopped

Kirill Lapshin via lldb-commits lldb-commits at lists.llvm.org
Thu Sep 24 11:34:15 PDT 2015


KLapshin added a comment.

@clayborg, @labath,

After more deep investigation I think setting listener for hijacking also looks like workaround. Setting additional listener just change code flow path and buggy path not executed, thus no crash. At top level - crash appeared in Process::m_listener involved - as no hijacked listener was set in Destroy().

See code below:

  StateType
  Process::WaitForProcessToStop (const TimeValue *timeout,
                                 EventSP *event_sp_ptr,
                                 bool wait_always,
                                 Listener *hijack_listener,
                                 Stream *stream)
  {
      // We can't just wait for a "stopped" event, because the stopped event may have restarted the target.
      // We have to actually check each event, and in the case of a stopped event check the restarted flag
      // on the event.
      if (event_sp_ptr)
          event_sp_ptr->reset();
      StateType state = GetState();
      // If we are exited or detached, we won't ever get back to any
      // other valid state...
      if (state == eStateDetached || state == eStateExited)
          return state;
  
      Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
      if (log)
          log->Printf ("Process::%s (timeout = %p)", __FUNCTION__,
                       static_cast<const void*>(timeout));
  
      if (!wait_always &&
          StateIsStoppedState(state, true) &&
          StateIsStoppedState(GetPrivateState(), true))
      {
          if (log)
              log->Printf("Process::%s returning without waiting for events; process private and public states are already 'stopped'.",
                          __FUNCTION__);
          // We need to toggle the run lock as this won't get done in
          // SetPublicState() if the process is hijacked.
          if (hijack_listener)
              m_public_run_lock.SetStopped();
          return state;
      }
  
      while (state != eStateInvalid)
      {
          EventSP event_sp;
          state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener);  <---
          if (event_sp_ptr && event_sp)
              *event_sp_ptr = event_sp;
  ....



  StateType
  Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, Listener *hijack_listener)
  {
      Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
  
      if (log)
          log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__,
                       static_cast<const void*>(timeout));
  
      Listener *listener = hijack_listener;
      if (listener == NULL)
          listener = &m_listener;  <--- what if m_listener was set as unitialized or deallocated Listener instance, "dummy" listener ?
  
      StateType state = eStateInvalid;
      if (listener->WaitForEventForBroadcasterWithType (timeout,
                                                        this,
                                                        eBroadcastBitStateChanged | eBroadcastBitInterrupt,
                                                        event_sp))
      {
          if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged)
              state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
          else if (log)
              log->Printf ("Process::%s got no event or was interrupted.", __FUNCTION__);
      }
  ...

You can reproduce crash even without lldb-MI driver - just with remote iOS target and "process launch", then "process kill".

Corresponding log ("log enable lldb events"):

  (lldb) process launch
  ...
  Process::ShouldBroadcastEvent (0x7ff1fa4a1260) => new state: running, last broadcast state: running - NO
  0x7ff1fad1b110 Listener::WaitForEventsInternal (timeout = { 0x0 }) for lldb.process.internal_state_listener
  (lldb) process kill
  0x7ff1fad1afa0 Broadcaster("lldb.process.internal_state_broadcaster")::BroadcastEvent (event_sp = {0x7ff1fce160d0 Event: broadcaster = 0x7ff1fad1afa0 (lldb.process.internal_state_broadcaster), type = 0x00000002, data = <NULL>}, unique =0) hijack = 0x0
  0x7ff1fad1b110 Listener('lldb.process.internal_state_listener')::AddEvent (event_sp = {0x7ff1fce160d0})
  0x7ff1fa48e300 Listener::WaitForEventsInternal (timeout = { 0x7fff57d47240 }) for  <-- WHAT ?! Listener without name - Process::m_listener may be ?
  0x7ff1fad1b110 'lldb.process.internal_state_listener' Listener::FindNextEventInternal(broadcaster=0x0, broadcaster_names=0x0[0], event_type_mask=0x00000000, remove=1) event 0x7ff1fce160d0
  0x7ff1fad1ae38 Broadcaster("lldb.process")::HijackBroadcaster (listener("lldb.process.halt_listener")=0x7ff1fe01ca00)
  CRASH !

Will continue investigation.


Repository:
  rL LLVM

http://reviews.llvm.org/D12968





More information about the lldb-commits mailing list