bool Driver::HandleIOEvent (const SBEvent &event) { bool quit = false; const uint32_t event_type = event.GetType(); if (event_type & IOChannel::eBroadcastBitHasUserInput) { // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for // handling. const char *command_string = SBEvent::GetCStringFromEvent(event); if (command_string == NULL) command_string = ""; SBCommandReturnObject result; // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd // output orderings and problems with the prompt. m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true); if (result.GetOutputSize() > 0) m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), NO_ASYNC); if (result.GetErrorSize() > 0) m_io_channel_ap->OutWrite (result.GetError(), result.GetErrorSize(), NO_ASYNC); // We are done getting and running our command, we can now clear the // m_waiting_for_command so we can get another one. m_waiting_for_command = false; // If our editline input reader is active, it means another input reader // got pushed onto the input reader and caused us to become deactivated. // When the input reader above us gets popped, we will get re-activated // and our prompt will refresh in our callback if (m_editline_reader.IsActive()) { ReadyForCommand (); } } else if (event_type & IOChannel::eBroadcastBitUserInterrupt) { // This is here to handle control-c interrupts from the user. It has not yet really been implemented. // TO BE DONE: PROPERLY HANDLE CONTROL-C FROM USER //m_io_channel_ap->CancelInput(); // Anything else? Send Interrupt to process? } else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) || (event_type & IOChannel::eBroadcastBitThreadDidExit)) { // If the IOChannel thread is trying to go away, then it is definitely // time to end the debugging session. quit = true; } return quit; }
void Driver::ExecuteInitialCommands (bool before_file) { size_t num_commands; std::vector<std::pair<bool, std::string> > *command_set; if (before_file) command_set = &(m_option_data.m_initial_commands); else command_set = &(m_option_data.m_after_file_commands); num_commands = command_set->size(); SBCommandReturnObject result; bool old_async = GetDebugger().GetAsync(); GetDebugger().SetAsync(false); for (size_t idx = 0; idx < num_commands; idx++) { bool is_file = (*command_set)[idx].first; const char *command = (*command_set)[idx].second.c_str(); char command_string[PATH_MAX * 2]; const bool dump_stream_only_if_no_immediate = true; const char *executed_command = command; if (is_file) { ::snprintf (command_string, sizeof(command_string), "command source -s %i '%s'", m_option_data.m_source_quietly, command); executed_command = command_string; } m_debugger.GetCommandInterpreter().HandleCommand (executed_command, result, false); if (!m_option_data.m_source_quietly || result.Succeeded() == false) { const size_t output_size = result.GetOutputSize(); if (output_size > 0) { const char *cstr = result.GetOutput(dump_stream_only_if_no_immediate); if (cstr) printf ("%s", cstr); } const size_t error_size = result.GetErrorSize(); if (error_size > 0) { const char *cstr = result.GetError(dump_stream_only_if_no_immediate); if (cstr) printf ("%s", cstr); } } if (result.Succeeded() == false) { const char *type = before_file ? "before file" : "after_file"; if (is_file) ::fprintf(stderr, "Aborting %s command execution, command file: '%s' failed.\n", type, command); else ::fprintf(stderr, "Aborting %s command execution, command: '%s' failed.\n", type, command); break; } result.Clear(); } GetDebugger().SetAsync(old_async); }
// 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; } } }