Patch #2349 2008-01-27 23:23

pecan

Found cause of Debugger crash when deleting breakpoints
Download
2349-Found_cause_of.patch (2.2 KB)
Category
 
Status
Closed
Close date
2008-02-16 00:05
Assigned to
mandrav
Recently, I've been running a pgm under the debugger that
causes CB to crash when I delete a breakpoint. But the pgm runs ok
when not being debugged.

So I placed asm(int3) traps until I bracked the problem.
It seems that GdbCmd_RemoveBreakpoint::ParseOutput is assigning
a -1 to a breakpoint that has already been deleted.
Here is a way to reproduce the error.

I do not know the debugger well enough to know how to fix it.

In debuggerstate.cpp at line 191, place a trap and note
the bp address that's being deleted.

DebuggerBreakpoint* DebuggerState::RemoveBreakpoint(int idx, bool deleteit)
{
    // do we have a valid index?
    if (idx < 0 || idx >= (int)m_Breakpoints.GetCount())
        return 0;
    // yes, remove it from the list
    DebuggerBreakpoint* bp = m_Breakpoints[idx];
    m_Breakpoints.RemoveAt(idx);

    // notify driver if it is active
    if (m_pDriver)
        m_pDriver->RemoveBreakpoint(bp);

    if (deleteit)
    {
        asm("int3"); /*trap*/ //<===============
        delete bp; //<= look at bp address
        return 0;
    }
    return bp;
}


In gdb_command.h at line 777, place the following trap.
when the debugger stops at "cmd->ParseOutput(buffer.Left(idx));"
step int the GdbCmd_RemoveBreakpoint() routine and
look at m_BP of the line: "m_BP->index = -1;".
m_BP is the exact address of the bp that got previously deleted.

class GdbCmd_RemoveBreakpoint : public DebuggerCmd
{
    < lines skipped>

//        DebugLog(wxString::Format(_T("Command parsing output (cmd: %s): %s"), cmd->m_Cmd.c_str(), buffer.Left(idx).c_str()));
        RemoveTopCommand(false);
        buffer.Remove(idx);
        // remove the '>>>>>>' part of the prompt (or what's left of it)
        int cnt = 6; // max 6 '>'
        while (buffer.Last() == _T('>') && cnt--)
            buffer.RemoveLast();
        if (buffer.Last() == _T('\n'))
            buffer.RemoveLast();
        wxString cmdString = cmd->m_Cmd;               /*trap*/
        if (cmdString.StartsWith(_T("delete "))) asm("int3"); /*trap*/
        cmd->ParseOutput(buffer.Left(idx));
        delete cmd;
        RunQueue();
    }



This is the culprit: line 508 in gdb_commands.h . m_BP has alread been deleted.

            // invalidate bp number
            m_BP->index = -1;
mandrav 2008-02-02 12:09

I don't see if this is a patch or not, but I do see what you mean.

Have you tried commenting out gdb_commands.h:508?

Does this fix the problem?

pecan 2008-02-02 16:45
I accidently used the wrong URL to post this. But I don't know how to move it.

Yes, commenting out:

            // invalidate bp number
            m_BP->index = -1;

at gdb_command.h:508 solved the problem.
pecan 2008-02-16 00:05

Fixed