bool DbgGdb::DoInitializeGdb(const std::vector<BreakpointInfo> &bpList, const wxArrayString &cmds) { //place breakpoint at first line #ifdef __WXMSW__ ExecuteCmd(wxT("set new-console on")); #endif ExecuteCmd(wxT("set unwindonsignal on")); if (m_info.enablePendingBreakpoints) { ExecuteCmd(wxT("set breakpoint pending on")); } if (m_info.catchThrow) { ExecuteCmd(wxT("catch throw")); } #ifdef __WXMSW__ if (m_info.debugAsserts) { ExecuteCmd(wxT("break assert")); } #endif ExecuteCmd(wxT("set width 0")); ExecuteCmd(wxT("set height 0")); ExecuteCmd(wxT("set print pretty on")); // pretty printing // Number of elements to show for arrays (including strings) wxString sizeCommand; sizeCommand << wxT("set print elements ") << m_info.maxDisplayStringSize; ExecuteCmd( sizeCommand ); // set the project startup commands for (size_t i=0; i<cmds.GetCount(); i++) { ExecuteCmd(cmds.Item(i)); } // keep the list of breakpoints m_bpList = bpList; if(GetIsRemoteDebugging() == false) // When remote debugging, apply the breakpoints after we connect the // gdbserver SetBreakpoints(); if (m_info.breakAtWinMain) { //try also to set breakpoint at WinMain WriteCommand(wxT("-break-insert main"), NULL); } return true; }
void BreakptMgr::ReconcileBreakpoints(const std::vector<BreakpointInfo>& li) { std::vector<BreakpointInfo> updated_bps; std::vector<BreakpointInfo>::const_iterator li_iter = li.begin(); for (; li_iter != li.end(); ++li_iter) { int index = FindBreakpointById(li_iter->debugger_id, m_bps); if (index == wxNOT_FOUND) { if(IsDuplicate(*li_iter, updated_bps)) continue; // This will happen e.g. if a bp was auto-set on Main() // If so, its internal_id will be invalid BreakpointInfo bp = *li_iter; bp.internal_id = GetNextID(); updated_bps.push_back(bp); } else { // We've match the debugger_id from -break-list with a bp // Update the ignore-count, then store it in a new vector BreakpointInfo bp = m_bps.at(index); bp.ignore_number = li_iter->ignore_number; bp.what = li_iter->what; bp.at = li_iter->at; // Remove it from the m_bps list m_bps.erase(m_bps.begin()+index); SetBestBPType(bp); // as this might have just changed updated_bps.push_back(bp); } } // All the still-existing bps have been added to updated_bps // So throw away m_bps (which will contain stale bps) and replace with the new vector // First though, delete all markers. Otherwise, if the last in a file has been deleted... DeleteAllBreakpointMarkers(); // All the stale breakpoints should be assigned to the 'm_pendingBreakpointList' m_pendingBreakpointsList = m_bps; m_bps.clear(); SetBreakpoints(updated_bps); RefreshBreakpointMarkers(); // update the Breakpoints pane too clMainFrame::Get()->GetDebuggerPane()->GetBreakpointView()->Initialize(); }
void DbgGdb::DoProcessAsyncCommand( wxString &line, wxString &id ) { if ( line.StartsWith( wxT( "^error" ) ) ) { // the command was error, for example: // finish in the outer most frame // print the error message and remove the command from the queue DbgCmdHandler *handler = PopHandler( id ); bool errorProcessed (false); if ( handler && handler->WantsErrors() ) { errorProcessed = handler->ProcessOutput( line ); } if ( handler ) { delete handler; } StripString( line ); //We also need to pass the control back to the program if (!errorProcessed) { m_observer->UpdateGotControl( DBG_CMD_ERROR ); } if ( !FilterMessage( line ) && m_info.enableDebugLog ) { m_observer->UpdateAddLine( line ); } } else if ( line.StartsWith( wxT( "^done" ) ) || line.StartsWith( wxT( "^connected" ) ) ) { //The synchronous operation was successful, results are the return values. DbgCmdHandler *handler = PopHandler( id ); if ( handler ) { handler->ProcessOutput( line ); delete handler; } } else if ( line.StartsWith( wxT( "^running" ) ) ) { //asynchronous command was executed //send event that we dont have the control anymore m_observer->UpdateLostControl(); } else if ( line.StartsWith( wxT( "*stopped" ) ) ) { //get the stop reason, if ( line == wxT( "*stopped" ) ) { if ( m_bpList.empty() ) { ExecuteCmd( wxT( "set auto-solib-add off" ) ); ExecuteCmd( wxT( "set stop-on-solib-events 0" ) ); } else { //no reason for the failure, this means that we stopped due to //hitting a loading of shared library //try to place all breakpoints which previously failed SetBreakpoints(); } Continue(); } else { //GDB/MI Out-of-band Records //caused by async command, this line indicates that we have the control back DbgCmdHandler *handler = PopHandler( id ); if ( handler ) { handler->ProcessOutput( line ); delete handler; } } } }
// Initialization stage bool DbgGdb::DoInitializeGdb(const DebugSessionInfo& sessionInfo) { m_goingDown = false; m_internalBpId = wxNOT_FOUND; #ifdef __WXMSW__ ExecuteCmd( wxT( "set new-console on" ) ); #endif ExecuteCmd( wxT( "set unwindonsignal on" ) ); wxString breakinsertcmd(wxT("-break-insert ")); if ( m_info.enablePendingBreakpoints ) { ExecuteCmd( wxT( "set breakpoint pending on" ) ); breakinsertcmd << wxT("-f "); } if ( m_info.catchThrow ) { ExecuteCmd( wxT( "catch throw" ) ); } #ifdef __WXMSW__ if ( m_info.debugAsserts ) { ExecuteCmd( wxT( "break assert" ) ); } #endif ExecuteCmd( wxT( "set width 0" ) ); ExecuteCmd( wxT( "set height 0" ) ); // Number of elements to show for arrays (including strings) wxString sizeCommand; sizeCommand << wxT( "set print elements " ) << m_info.maxDisplayStringSize; ExecuteCmd( sizeCommand ); // set the project startup commands for ( size_t i=0; i<sessionInfo.cmds.GetCount(); i++ ) { ExecuteCmd( sessionInfo.cmds.Item( i ) ); } // keep the list of breakpoints m_bpList = sessionInfo.bpList; bool setBreakpointsAfterMain( m_info.applyBreakpointsAfterProgramStarted ); if( GetIsRemoteDebugging() == false && !setBreakpointsAfterMain ) { // When remote debugging, apply the breakpoints after we connect the // gdbserver SetBreakpoints(); } else if( setBreakpointsAfterMain && m_bpList.empty() == false ) { // Place an 'internal' breakpoint at main. Once this breakpoint is hit // set all breakpoints and remove the 'internal' one. // Then 'continue', unless the user has said he actually _wants_ to break at main WriteCommand( breakinsertcmd + wxT("-t main"), new DbgFindMainBreakpointIdHandler( m_observer, this ) ); } if (m_info.breakAtWinMain) { // Set a breakpoint at WinMain // Use a temporary one, so that it isn't duplicated in future sessions WriteCommand( breakinsertcmd + wxT("-t main"), NULL ); // Flag that we've done this. DbgFindMainBreakpointIdHandler::ProcessOutput uses this // to decide whether or not to 'continue' after setting BPs after main() SetShouldBreakAtMain(true); } else { SetShouldBreakAtMain(false); // Needs explicitly to be set, in case the user has just changed his options } // Enable python based pretty printing? if ( sessionInfo.enablePrettyPrinting ) { WriteCommand( wxT( "-enable-pretty-printing" ), NULL ); } // Add the additional search paths for(size_t i=0; i<sessionInfo.searchPaths.GetCount(); ++i) { wxString dirCmd; wxString path = sessionInfo.searchPaths.Item(i); path.Trim().Trim(false); if ( path.Contains(" ") ) { path.Prepend('"').Append('"'); } dirCmd << "-environment-directory " << path; WriteCommand( dirCmd, NULL ); } return true; }