⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debuggergdb.cpp

📁 非常好用的可移植的多平台C/C++源代码编辑器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            break;

        case CMD_DISASSEMBLE:
        {
//            Manager::Get()->GetMessageManager()->Log(m_PageIndex, "Disassembling...");
            if (m_pDisassembly)
                m_pDisassembly->ClearRegisters();
            for (int i = 0; i < 16; ++i)
            {
                long int val = ReadRegisterValue(i);
                if (m_pDisassembly)
                    m_pDisassembly->AddRegisterValue(i, val);
//                Manager::Get()->GetMessageManager()->Log(m_PageIndex, "%s: '%s' (%d)", DisassemblyDlg::Registers[i].c_str(), token.c_str(), val);
            }
            SendCommand(_T("disassemble"));
            break;
        }

        default: break;
    }
}

long int DebuggerGDB::ReadRegisterValue(int idx)
{
    SendCommand(_T("info registers ") + DisassemblyDlg::Registers[idx]);
    wxString line;
    do
    {
        line = GetNextOutputLineClean();
    } while (!line.IsEmpty() && line.StartsWith(GDB_PROMPT));
    if (line.IsEmpty())
        return 0;
    // break up the string in its parts
    wxStringTokenizer tkz(line, wxT("\t"));
    wxString token;
    while (tkz.HasMoreTokens())
    {
        token = tkz.GetNextToken();
    }
    long int val;
    if (token.StartsWith(_T("0x")))
        token.ToLong(&val, 16);
    else
        token.ToLong(&val, 10);
    return val;
}

void DebuggerGDB::CmdDisassemble()
{
    if (!m_pDisassembly)
        m_pDisassembly = new DisassemblyDlg(Manager::Get()->GetAppWindow(), this);
    m_pDisassembly->Show();
    RunCommand(CMD_DISASSEMBLE);
}

void DebuggerGDB::CmdBacktrace()
{
    if (!m_pBacktrace)
        m_pBacktrace = new BacktraceDlg(Manager::Get()->GetAppWindow(), this);
    m_pBacktrace->Clear();
    m_pBacktrace->Show();
    RunCommand(CMD_BACKTRACE);
}

void DebuggerGDB::CmdContinue()
{
	SetBreakpoints();
	if (!m_Tbreak.IsEmpty())
	{
		SendCommand(m_Tbreak);
		m_Tbreak.Clear();
	}
    RunCommand(CMD_CONTINUE);
}

void DebuggerGDB::CmdNext()
{
    RunCommand(CMD_STEP);
}

void DebuggerGDB::CmdStep()
{
    RunCommand(CMD_STEPIN);
}

bool DebuggerGDB::Validate(const wxString& line, const char cb)
{
	bool bResult = false;

	int bep = line.Find(cb)+1;
	int scs = line.Find(_T('\''))+1;
	int sce = line.Find(_T('\''),true)+1;
	int dcs = line.Find(_T('"'))+1;
	int dce = line.Find(_T('"'),true)+1;
	//No single and double quote
	if(!scs && !sce && !dcs && !dce) bResult = true;
	//No single/double quote in pair
	if(!(sce-scs) && !(dce-dcs)) bResult = true;
	//Outside of single quote
	if((sce-scs) && ((bep < scs)||(bep >sce))) bResult = true;
	//Outside of double quote
	if((dce-dcs) && ((bep < dcs)||(bep >dce))) bResult = true;

	return bResult;
}

void DebuggerGDB::CmdStepOut()
{
	cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
	if (!ed) return;
	ProjectFile* pf = ed->GetProjectFile();
	if (!pf) return;
	wxString filename = pf->file.GetFullName(), lineBuf, cmd;
	cbStyledTextCtrl* stc = ed->GetControl();
	int line = m_HaltAtLine;
	lineBuf = stc->GetLine(line);

	unsigned int nLevel = 1;
	while(nLevel){
		 if ((lineBuf.Find(_T('{'))+1) && Validate(lineBuf, _T('{')) &&
			 (line > m_HaltAtLine)) nLevel++;
		 if ((lineBuf.Find(_T('}'))+1) && Validate(lineBuf, _T('}'))) nLevel--;
		 if (nLevel) lineBuf = stc->GetLine(++line);
	}
	if (line == stc->GetCurrentLine())
		CmdNext();
	else {
		cmd << _T("tbreak ") << filename << _T(":") << line+1;
		m_Tbreak = cmd;
		CmdContinue();
	}
}

void DebuggerGDB::CmdRunToCursor()
{
    cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
	if (!ed)
		return;

	ProjectFile* pf = ed->GetProjectFile();
	if (!pf)
		return;
	wxString cmd, filename = pf->file.GetFullName();
	cmd << _T("tbreak ") << filename << _T(":") << ed->GetControl()->GetCurrentLine()+1;
	m_Tbreak = cmd;
	if (m_pProcess)
	{
		CmdContinue();
	}
	else
	{
		Debug();
	}
}

void DebuggerGDB::CmdToggleBreakpoint()
{
	ClearActiveMarkFromAllEditors();
    cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
	if (!ed)
		return;
	ed->MarkerToggle(BREAKPOINT_MARKER);
//	SetBreakpoints();
}

void DebuggerGDB::CmdStop()
{
	if (m_pProcess && m_Pid)
	{
		if (m_ProgramIsStopped)
		{
            RunCommand(CMD_STOP);
            m_pProcess->CloseOutput();
		}
		else
		{
            m_pProcess->CloseOutput();
			wxKillError err = m_pProcess->Kill(m_Pid, wxSIGKILL);
			if (err == wxKILL_OK){
/*
				wxMessageBox(_("Debug session terminated!"),
					_("Debug"), wxOK | wxICON_EXCLAMATION);
*/
			}
			m_ProgramIsStopped = true;
		}
	}
}

void DebuggerGDB::ParseOutput(const wxString& output)
{
	wxString buffer = output;
	if (buffer.StartsWith(g_EscapeChars)) // ->->
	{
		buffer.Remove(0, 2); // remove ->->
        if (m_HasDebugLog)
            m_pDbgLog->AddLog(buffer); // write it in the full debugger log
		// Is the program running?
		if (buffer.Matches(_T("starting")))
			m_ProgramIsStopped = false;

		// Is the program stopped?
		else if (buffer.Matches(_T("stopped")))
		{
			bool already = m_ProgramIsStopped;
			m_ProgramIsStopped = true;
			if (!already)
			{
				DoWatches();
				// if stopped with a signal, force a backtrace
				if (m_StoppedOnSignal)
				{
                    CmdBacktrace();
                    m_StoppedOnSignal = false; // reset for next time
				}
			}
		}

		// Is the program exited?
		else if (buffer.StartsWith(_T("exited ")))
		{
			m_ProgramIsStopped = true;
			Manager::Get()->GetMessageManager()->Log(m_PageIndex, buffer);
			CmdStop();
		}

		// error
		else if (buffer.Matches(_T("error")))
		{
			Manager::Get()->GetMessageManager()->Log(m_PageIndex, buffer);
			//CmdStop();
		}
		else if (buffer.StartsWith(_T("error-begin")))
		{
            wxString error = GetNextOutputLineClean(true);
			Manager::Get()->GetMessageManager()->Log(m_PageIndex, error);
			if (error.StartsWith(_T("No symbol table is loaded.")))
                m_NoDebugInfo = true;
			//CmdStop();
		}

		// signal
		else if (buffer.Matches(_T("signal-name")))
		{
			BringAppToFront();
			wxString sig = GetNextOutputLineClean();
			Manager::Get()->GetMessageManager()->Log(m_PageIndex, _("Program received signal (%s)"), sig.c_str());
			m_StoppedOnSignal = true;
		}
		else if (buffer.Matches(_T("signal-string")))
		{
			wxString sig = GetNextOutputLineClean();
			Manager::Get()->GetMessageManager()->Log(m_PageIndex, sig);
		}

		// Stack-frame info
		else if (buffer.Matches(_T("frames-invalid")))
            m_CurrentFrame.Clear();
		else if (buffer.StartsWith(_T("frame-begin ")))
		{
            m_CurrentFrame.Clear();
            sscanf(buffer.mb_str(), "frame-begin %d %x", &m_CurrentFrame.number, &m_CurrentFrame.address);
            m_CurrentFrame.valid = true;
        }
		else if (buffer.Matches(_T("frame-function-name")))
		{
            m_CurrentFrame.function = GetNextOutputLineClean();
//			Manager::Get()->GetMessageManager()->Log(m_PageIndex, "m_FrameFunction=%s", m_FrameFunction.c_str());
        }
		else if (buffer.Matches(_T("frame-source-file")))
			m_CurrentFrame.file = GetNextOutputLineClean();
		else if (buffer.Matches(_T("frame-source-line")))
			m_CurrentFrame.line = GetNextOutputLineClean();
		else if (buffer.Matches(_T("frame-end")) && m_CurrentFrame.valid)
		{
            if (m_pBacktrace)
                m_pBacktrace->AddFrame(m_CurrentFrame);
//			Manager::Get()->GetMessageManager()->Log(m_PageIndex,
//                                                    _("Frame #%-2d [0x%8.8x]: %s (%s:%s)"),
//                                                    m_CurrentFrame.number,
//                                                    m_CurrentFrame.address,
//                                                    m_CurrentFrame.valid ? m_CurrentFrame.function.c_str() : "??",
//                                                    m_CurrentFrame.valid && !m_CurrentFrame.file.IsEmpty() ? m_CurrentFrame.file.c_str() : "??",
//                                                    m_CurrentFrame.valid && !m_CurrentFrame.line.IsEmpty() ? m_CurrentFrame.line.c_str() : "??");
		}

		// source d:/wx2.4/samples/exec/exec.cpp:753:22811:beg:0x403e39
		else if (buffer.StartsWith(_T("source ")))
		{
			Manager::Get()->GetMessageManager()->DebugLog(buffer);
			buffer.Remove(0, 7); // remove "source "

			if (!reSource.IsValid())
			#ifdef __WXMSW__
				reSource.Compile(_T("([A-Za-z]:)([ A-Za-z0-9_/\\.~-]*):([0-9]*):[0-9]*:beg:(0x[0-9A-Za-z]*)"));
			#else
				reSource.Compile(_T("([ A-Za-z0-9_/\\.~-]*):([0-9]*):[0-9]*:beg:(0x[0-9A-Za-z]*)"));
			#endif
			if ( reSource.Matches(buffer) )
			{
			#ifdef __WXMSW__
				wxString file = reSource.GetMatch(buffer, 1) + reSource.GetMatch(buffer, 2);
				wxString lineStr = reSource.GetMatch(buffer, 3);
				wxString addr = reSource.GetMatch(buffer, 4);
            #else
				wxString file = reSource.GetMatch(buffer, 1);
				wxString lineStr = reSource.GetMatch(buffer, 2);
				wxString addr = reSource.GetMatch(buffer, 3);
            #endif
                if (m_pDisassembly)
                {
                    long int val;
                    addr.ToLong(&val, 16);
                    m_pDisassembly->SetActiveAddress(val);
                    // update CPU registers
                    // NOTE: this hangs; another solution must be found...
//                    for (int i = 0; i < 16; ++i)
//                    {
//                        val = ReadRegisterValue(i);
//                        m_pDisassembly->SetRegisterValue(i, val);
//                    }
                }
				long int line;
				lineStr.ToLong(&line);
//				Manager::Get()->GetMessageManager()->DebugLog("file %s, line %ld", file.c_str(), line);
				SyncEditor(file, line);
				m_HaltAtLine = line-1;
				BringAppToFront();
			}
		}
	}
	else
	{
        if (buffer.StartsWith(_T("Dump of assembler code")))
        {
//            Manager::Get()->GetMessageManager()->Log(m_PageIndex,
//                                                    "Starting disassembly of %s (starting address: 0x%8.8x)",
//                                                    m_CurrentFrame.valid ? m_CurrentFrame.function.c_str() : "??",
//                                                    m_CurrentFrame.valid ? m_CurrentFrame.address : 0);
            if (m_pDisassembly)
                m_pDisassembly->Clear(m_CurrentFrame);
            //0x00403977 <_ZN7MyFrame11OnLocalTestER14wxCommandEvent+521>:	ret
            wxRegEx re(_T("(0x[0-9A-Za-z]+)[ \t]+<.*>:[ \t]+(.*)"));
            wxString tmp;
            do
            {
                tmp = GetNextOutputLine();
                if (tmp.Matches(_T("End of assembler dump.")))
                {
//                    Manager::Get()->GetMessageManager()->Log(m_PageIndex, "Disassembly end");
                    break;
                }
                if (re.Matches(tmp) && m_pDisassembly)
                {
                    long int val;
                    wxString addr = re.GetMatch(tmp, 1);
                    addr.ToLong(&val, 16);
                    m_pDisassembly->AddAssemblerLine(val, re.GetMatch(tmp, 2));
                }
//                    Manager::Get()->GetMessageManager()->Log(m_PageIndex, "%s: %s", re.GetMatch(tmp, 1).c_str(), re.GetMatch(tmp, 2).c_str());
            }
            while (!tmp.IsEmpty());
            if (m_pDisassembly)
                m_pDisassembly->Show(true);
        }
	}
//        Manager::Get()->GetMessageManager()->Log(m_PageIndex, buffer);
}

void DebuggerGDB::BringAppToFront()
{
	wxWindow* app = Manager::Get()->GetAppWindow();
	if (app)
		app->Raise();
}

void DebuggerGDB::ClearActiveMarkFromAllEditors()
{
	EditorManager* edMan = Manager::Get()->GetEditorManager();
	if (!edMan)
        return;
	for (int i = 0; i < edMan->GetEditorsCount(); ++i)
	{
        cbEditor* ed = edMan->GetBuiltinEditor(i);
        if (ed)
            ed->MarkLine(ACTIVE_LINE, -1);
	}
}

void DebuggerGDB::SyncEditor(const wxString& filename, int line)
{
	ClearActiveMarkFromAllEditors();
	cbProject* project = Manager::Get()->GetProjectManager()->GetActiveProject();
	if (project)
	{
        wxFileName fname(filename);
	    ProjectFile* f = project->GetFileByFilename(fname.GetFullPath(), false, true);
    	if (f)
        {
        	cbEditor* ed = Manager::Get()->GetEditorManager()->Open(f->file.GetFullPath());
            if (ed)
			{
				ed->SetProjectFile(f);
            	ed->Show(true);
				ed->GetControl()->GotoLine(line - 10); // make sure we can see some context...
				ed->GetControl()->GotoLine(line - 1);
				ed->MarkLine(ACTIVE_LINE, line - 1);
			}
        }
        else
        {
            // no such file in project; maybe in another open project?
        	cbEditor* ed = Manager::Get()->GetEditorManager()->Open(fname.GetFullPath());
            if (ed)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -