void Xcode::FetchFrames(SBProcess process, bool variables, bool verbose) { auto pCount = process.GetNumThreads(); for (int p = 0; p < pCount; p++) { SBThread thread(process.GetThreadAtIndex(p)); auto tCount = thread.GetNumFrames (); if (verbose) printf("%s %d %d {%d}\n",thread.GetQueueName(),tCount,thread.GetStopReason(),eStopReasonBreakpoint); for (int t = 0; t < tCount; t++) { SBFrame frame(thread.GetFrameAtIndex(t)); auto fp = frame.GetFP(); SBThread thread_dup = frame.GetThread(); SBFileSpec filespec(process.GetTarget().GetExecutable()); std::string path(1024,0); filespec.GetPath(&path[0],1024); auto state = process.GetState(); auto pCount_dup = process.GetNumThreads(); auto byte_size = process.GetAddressByteSize(); auto pc = frame.GetPC(); SBSymbolContext context(frame.GetSymbolContext(0x0000006e)); SBModule module(context.GetModule()); SBLineEntry entry(context.GetLineEntry()); SBFileSpec entry_filespec(process.GetTarget().GetExecutable()); std::string entry_path(1024,0); entry_filespec.GetPath(&entry_path[0],1024); auto line_1 = entry.GetLine(); auto line_2 = entry.GetLine(); auto fname = frame.GetFunctionName(); if (verbose) printf("%llu %s %d %d %llu %s %d %s\n",fp,path.c_str(),state,byte_size,pc,entry_path.c_str(),line_1,fname); if (variables) FetchVariables (frame, 0, verbose); } } }
void SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, FILE *out, FILE *err) { if (!process.IsValid()) return; TargetSP target_sp (process.GetTarget().GetSP()); if (!target_sp) return; const uint32_t event_type = event.GetType(); char stdio_buffer[1024]; size_t len; Mutex::Locker api_locker (target_sp->GetAPIMutex()); if (event_type & (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged)) { // Drain stdout when we stop just in case we have any bytes while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0) if (out != NULL) ::fwrite (stdio_buffer, 1, len, out); } if (event_type & (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged)) { // Drain stderr when we stop just in case we have any bytes while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0) if (err != NULL) ::fwrite (stdio_buffer, 1, len, err); } if (event_type & Process::eBroadcastBitStateChanged) { StateType event_state = SBProcess::GetStateFromEvent (event); if (event_state == eStateInvalid) return; bool is_stopped = StateIsStoppedState (event_state); if (!is_stopped) process.ReportEventState (event, out); } }
// This function handles events that were broadcast by the process. void Driver::HandleProcessEvent (const SBEvent &event) { using namespace lldb; const uint32_t event_type = event.GetType(); if (event_type & SBProcess::eBroadcastBitSTDOUT) { // The process has stdout available, get it and write it out to the // appropriate place. GetProcessSTDOUT (); } else if (event_type & SBProcess::eBroadcastBitSTDERR) { // The process has stderr available, get it and write it out to the // appropriate place. GetProcessSTDERR (); } else if (event_type & SBProcess::eBroadcastBitStateChanged) { // Drain all stout and stderr so we don't see any output come after // we print our prompts GetProcessSTDOUT (); GetProcessSTDERR (); // Something changed in the process; get the event and report the process's current status and location to // the user. StateType event_state = SBProcess::GetStateFromEvent (event); if (event_state == eStateInvalid) return; SBProcess process (SBProcess::GetProcessFromEvent (event)); assert (process.IsValid()); switch (event_state) { case eStateInvalid: case eStateUnloaded: case eStateConnected: case eStateAttaching: case eStateLaunching: case eStateStepping: case eStateDetached: { char message[1024]; int message_len = ::snprintf (message, sizeof(message), "Process %llu %s\n", process.GetProcessID(), m_debugger.StateAsCString (event_state)); m_io_channel_ap->OutWrite(message, message_len, ASYNC); } break; case eStateRunning: // Don't be chatty when we run... break; case eStateExited: { SBCommandReturnObject result; m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false); m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC); m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC); } break; case eStateStopped: case eStateCrashed: case eStateSuspended: // Make sure the program hasn't been auto-restarted: if (SBProcess::GetRestartedFromEvent (event)) { // FIXME: Do we want to report this, or would that just be annoyingly chatty? char message[1024]; int message_len = ::snprintf (message, sizeof(message), "Process %llu stopped and was programmatically restarted.\n", process.GetProcessID()); m_io_channel_ap->OutWrite(message, message_len, ASYNC); } else { if (GetDebugger().GetSelectedTarget() == process.GetTarget()) { SBCommandReturnObject result; UpdateSelectedThread (); m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false); m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC); m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC); } else { SBStream out_stream; uint32_t target_idx = GetDebugger().GetIndexOfTarget(process.GetTarget()); if (target_idx != UINT32_MAX) out_stream.Printf ("Target %d: (", target_idx); else out_stream.Printf ("Target <unknown index>: ("); process.GetTarget().GetDescription (out_stream, eDescriptionLevelBrief); out_stream.Printf (") stopped.\n"); m_io_channel_ap->OutWrite (out_stream.GetData(), out_stream.GetSize(), ASYNC); } } break; } } }