Example #1
0
//----------------------------------------------------------------------
// This thread's sole purpose is to watch for any status changes in the
// child process.
//----------------------------------------------------------------------
void*
RNBContext::ThreadFunctionProcessStatus(void *arg)
{
    RNBRemoteSP remoteSP(g_remoteSP);
    RNBRemote* remote = remoteSP.get();
    if (remote == NULL)
        return NULL;
    RNBContext& ctx = remote->Context();

    nub_process_t pid = ctx.ProcessID();
    DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (arg=%p, pid=%4.4x): thread starting...", __FUNCTION__, arg, pid);
    ctx.Events().SetEvents (RNBContext::event_proc_thread_running);
    bool done = false;
    while (!done)
    {
        DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s calling DNBProcessWaitForEvent(pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable, true)...", __FUNCTION__);
        nub_event_t pid_status_event = DNBProcessWaitForEvents (pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable, true, NULL);
        DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s calling DNBProcessWaitForEvent(pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable, true) => 0x%8.8x", __FUNCTION__, pid_status_event);

        if (pid_status_event == 0)
        {
            DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (pid=%4.4x) got ZERO back from DNBProcessWaitForEvent....", __FUNCTION__, pid);
        //    done = true;
        }
        else
        {
            if (pid_status_event & eEventStdioAvailable)
            {
                DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (pid=%4.4x) got stdio available event....", __FUNCTION__, pid);
                ctx.Events().SetEvents (RNBContext::event_proc_stdio_available);
                // Wait for the main thread to consume this notification if it requested we wait for it
                ctx.Events().WaitForResetAck(RNBContext::event_proc_stdio_available);
            }


            if (pid_status_event & (eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged))
            {
                nub_state_t pid_state = DNBProcessGetState(pid);
                DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (pid=%4.4x) got process state change: %s", __FUNCTION__, pid, DNBStateAsString(pid_state));

                // Let the main thread know there is a process state change to see
                ctx.Events().SetEvents (RNBContext::event_proc_state_changed);
                // Wait for the main thread to consume this notification if it requested we wait for it
                ctx.Events().WaitForResetAck(RNBContext::event_proc_state_changed);

                switch (pid_state)
                {
                case eStateStopped:
                    break;

                case eStateInvalid:
                case eStateExited:
                case eStateDetached:
                    done = true;
                    break;
                default:
                    break;
                }
            }

            // Reset any events that we consumed.
            DNBProcessResetEvents(pid, pid_status_event);

        }
    }
    DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (arg=%p, pid=%4.4x): thread exiting...", __FUNCTION__, arg, pid);
    ctx.Events().ResetEvents(event_proc_thread_running);
    ctx.Events().SetEvents(event_proc_thread_exiting);
    return NULL;
}
Example #2
0
void
MachThread::SetState(nub_state_t state)
{
    PTHREAD_MUTEX_LOCKER (locker, m_state_mutex);
    m_state = state;
    DNBLogThreadedIf(LOG_THREAD, "MachThread::SetState ( %s ) for tid = 0x%8.8" PRIx64 "", DNBStateAsString(state), m_unique_id);
}
Example #3
0
//----------------------------------------------------------------------
// This thread's sole purpose is to watch for any status changes in the
// child process.
//----------------------------------------------------------------------
void *RNBContext::ThreadFunctionProcessStatus(void *arg) {
  RNBRemoteSP remoteSP(g_remoteSP);
  RNBRemote *remote = remoteSP.get();
  if (remote == NULL)
    return NULL;
  RNBContext &ctx = remote->Context();

  nub_process_t pid = ctx.ProcessID();
  DNBLogThreadedIf(LOG_RNB_PROC,
                   "RNBContext::%s (arg=%p, pid=%4.4x): thread starting...",
                   __FUNCTION__, arg, pid);
  ctx.Events().SetEvents(RNBContext::event_proc_thread_running);

#if defined(__APPLE__)
  pthread_setname_np("child process status watcher thread");
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
  struct sched_param thread_param;
  int thread_sched_policy;
  if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
                            &thread_param) == 0) {
    thread_param.sched_priority = 47;
    pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
  }
#endif
#endif

  bool done = false;
  while (!done) {
    DNBLogThreadedIf(LOG_RNB_PROC,
                     "RNBContext::%s calling DNBProcessWaitForEvent(pid, "
                     "eEventProcessRunningStateChanged | "
                     "eEventProcessStoppedStateChanged | eEventStdioAvailable "
                     "| eEventProfileDataAvailable, true)...",
                     __FUNCTION__);
    nub_event_t pid_status_event = DNBProcessWaitForEvents(
        pid,
        eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged |
            eEventStdioAvailable | eEventProfileDataAvailable,
        true, NULL);
    DNBLogThreadedIf(LOG_RNB_PROC,
                     "RNBContext::%s calling DNBProcessWaitForEvent(pid, "
                     "eEventProcessRunningStateChanged | "
                     "eEventProcessStoppedStateChanged | eEventStdioAvailable "
                     "| eEventProfileDataAvailable, true) => 0x%8.8x",
                     __FUNCTION__, pid_status_event);

    if (pid_status_event == 0) {
      DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (pid=%4.4x) got ZERO back "
                                     "from DNBProcessWaitForEvent....",
                       __FUNCTION__, pid);
      //    done = true;
    } else {
      if (pid_status_event & eEventStdioAvailable) {
        DNBLogThreadedIf(
            LOG_RNB_PROC,
            "RNBContext::%s (pid=%4.4x) got stdio available event....",
            __FUNCTION__, pid);
        ctx.Events().SetEvents(RNBContext::event_proc_stdio_available);
        // Wait for the main thread to consume this notification if it requested
        // we wait for it
        ctx.Events().WaitForResetAck(RNBContext::event_proc_stdio_available);
      }

      if (pid_status_event & eEventProfileDataAvailable) {
        DNBLogThreadedIf(
            LOG_RNB_PROC,
            "RNBContext::%s (pid=%4.4x) got profile data event....",
            __FUNCTION__, pid);
        ctx.Events().SetEvents(RNBContext::event_proc_profile_data);
        // Wait for the main thread to consume this notification if it requested
        // we wait for it
        ctx.Events().WaitForResetAck(RNBContext::event_proc_profile_data);
      }

      if (pid_status_event & (eEventProcessRunningStateChanged |
                              eEventProcessStoppedStateChanged)) {
        nub_state_t pid_state = DNBProcessGetState(pid);
        DNBLogThreadedIf(
            LOG_RNB_PROC,
            "RNBContext::%s (pid=%4.4x) got process state change: %s",
            __FUNCTION__, pid, DNBStateAsString(pid_state));

        // Let the main thread know there is a process state change to see
        ctx.Events().SetEvents(RNBContext::event_proc_state_changed);
        // Wait for the main thread to consume this notification if it requested
        // we wait for it
        ctx.Events().WaitForResetAck(RNBContext::event_proc_state_changed);

        switch (pid_state) {
        case eStateStopped:
          break;

        case eStateInvalid:
        case eStateExited:
        case eStateDetached:
          done = true;
          break;
        default:
          break;
        }
      }

      // Reset any events that we consumed.
      DNBProcessResetEvents(pid, pid_status_event);
    }
  }
  DNBLogThreadedIf(LOG_RNB_PROC,
                   "RNBContext::%s (arg=%p, pid=%4.4x): thread exiting...",
                   __FUNCTION__, arg, pid);
  ctx.Events().ResetEvents(event_proc_thread_running);
  ctx.Events().SetEvents(event_proc_thread_exiting);
  return NULL;
}
Example #4
0
// Return the new run loop mode based off of the current process state
RNBRunLoopMode
HandleProcessStateChange (RNBRemoteSP &remote, bool initialize)
{
    RNBContext& ctx = remote->Context();
    nub_process_t pid = ctx.ProcessID();
    
    if (pid == INVALID_NUB_PROCESS)
    {   
        DNBLogThreadedIf (LOG_RNB_MINIMAL, "#### %s error: pid invalid, exiting...", __FUNCTION__);
        return eRNBRunLoopModeExit; 
    }
    nub_state_t pid_state = DNBProcessGetState (pid);
	
    DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  pid_state = %s", __FUNCTION__, (int)initialize, DNBStateAsString (pid_state));
	
    switch (pid_state)
    {
		case eStateInvalid:
		case eStateUnloaded:
			// Something bad happened
			return eRNBRunLoopModeExit; 
			break;
			
		case eStateAttaching:
		case eStateLaunching:   
			return eRNBRunLoopModeInferiorExecuting; 
			
		case eStateSuspended:
		case eStateCrashed:
		case eStateStopped:     
			if (initialize == false)
			{
				// Compare the last stop count to our current notion of a stop count
				// to make sure we don't notify more than once for a given stop.
				nub_size_t prev_pid_stop_count = ctx.GetProcessStopCount();
				bool pid_stop_count_changed = ctx.SetProcessStopCount(DNBProcessGetStopCount(pid));
				if (pid_stop_count_changed)
				{
					remote->FlushSTDIO();
					
					if (ctx.GetProcessStopCount() == 1)
					{
						DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  pid_state = %s pid_stop_count %zu (old %zu)) Notify??? no, first stop...", __FUNCTION__, (int)initialize, DNBStateAsString (pid_state), ctx.GetProcessStopCount(), prev_pid_stop_count);
					}
					else
					{
						
						DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  pid_state = %s pid_stop_count %zu (old %zu)) Notify??? YES!!!", __FUNCTION__, (int)initialize, DNBStateAsString (pid_state), ctx.GetProcessStopCount(), prev_pid_stop_count);
						remote->NotifyThatProcessStopped ();
					}
				}
				else
				{
					DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  pid_state = %s pid_stop_count %zu (old %zu)) Notify??? skipping...", __FUNCTION__, (int)initialize, DNBStateAsString (pid_state), ctx.GetProcessStopCount(), prev_pid_stop_count);
				}
			}
			return eRNBRunLoopModeInferiorExecuting; 
			
		case eStateStepping:
		case eStateRunning:
			return eRNBRunLoopModeInferiorExecuting; 
			
		case eStateExited:
			remote->HandlePacket_last_signal(NULL);
			return eRNBRunLoopModeExit;
		case eStateDetached:
            return eRNBRunLoopModeExit;
			
    }
	
    // Catch all...
    return eRNBRunLoopModeExit; 
}