From 1dc6b579a6b5f94deed108bcd119f46f07326138 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Mon, 14 Apr 2003 19:24:17 +0000 Subject: [PATCH] Be more robust if breakpoints cannot be restored when a session is started. --- kdbg/dbgdriver.h | 10 ++++-- kdbg/debugger.cpp | 85 ++++++++++++++++++++++++++++++++------------------- kdbg/debugger.h | 2 +- kdbg/gdbdriver.cpp | 16 +++++++--- kdbg/gdbdriver.h | 2 +- kdbg/xsldbgdriver.cpp | 2 +- kdbg/xsldbgdriver.h | 2 +- 7 files changed, 77 insertions(+), 42 deletions(-) diff --git a/kdbg/dbgdriver.h b/kdbg/dbgdriver.h index e46698c..c25c62a 100644 --- a/kdbg/dbgdriver.h +++ b/kdbg/dbgdriver.h @@ -124,6 +124,8 @@ enum MemoryDumpType { MDTformatmask = 0xf0 }; +struct Breakpoint; + /** * Debugger commands are placed in a queue. Only one command at a time is * sent down to the debugger. All other commands in the queue are retained @@ -143,6 +145,8 @@ struct CmdQueueItem // remember file position QString m_fileName; int m_lineNo; + // the breakpoint info + Breakpoint* m_brkpt; // whether command was emitted due to direct user request (only set when relevant) bool m_byUser; @@ -153,6 +157,7 @@ struct CmdQueueItem m_expr(0), m_exprWnd(0), m_lineNo(0), + m_brkpt(0), m_byUser(false) { } }; @@ -407,11 +412,12 @@ public: * @param output The output of the debugger. * @param id Returns the breakpoint id. * @param file Returns the file name in which the breakpoint is. - * @param lineNo Returns he zero-based line number of the breakpoint. + * @param lineNo Returns the zero-based line number of the breakpoint. + * @param address Returns the address of the breakpoint. * @return False if there was no breakpoint. */ virtual bool parseBreakpoint(const char* output, int& id, - QString& file, int& lineNo) = 0; + QString& file, int& lineNo, QString& address) = 0; /** * Parses the output of the DCinfolocals command. diff --git a/kdbg/debugger.cpp b/kdbg/debugger.cpp index 50bd556..2188322 100644 --- a/kdbg/debugger.cpp +++ b/kdbg/debugger.cpp @@ -750,11 +750,6 @@ void KDebugger::saveBreakpoints(KSimpleConfig* config) void KDebugger::restoreBreakpoints(KSimpleConfig* config) { QString groupName; - QString fileName; - QString address; - int lineNo; - bool enabled, temporary; - QString condition; /* * We recognize the end of the list if there is no Enabled entry * present. @@ -766,35 +761,35 @@ void KDebugger::restoreBreakpoints(KSimpleConfig* config) /* group not present, assume that we've hit them all */ break; } - fileName = config->readEntry(File); - lineNo = config->readNumEntry(Line, -1); - address = config->readEntry(Address); - if ((fileName.isEmpty() || lineNo < 0) && address.isEmpty()) + Breakpoint* bp = new Breakpoint; + bp->fileName = config->readEntry(File); + bp->lineNo = config->readNumEntry(Line, -1); + bp->address = config->readEntry(Address); + if ((bp->fileName.isEmpty() || bp->lineNo < 0) && bp->address.isEmpty()) { + delete bp; continue; - enabled = config->readBoolEntry(Enabled, true); - temporary = config->readBoolEntry(Temporary, false); - condition = config->readEntry(Condition); + } + bp->enabled = config->readBoolEntry(Enabled, true); + bp->temporary = config->readBoolEntry(Temporary, false); + bp->condition = config->readEntry(Condition); + bp->hitCount = 0; + bp->ignoreCount = 0; + bp->id = 0; + /* - * Add the breakpoint. We assume that we have started a new - * instance of gdb, because we assign the breakpoint ids ourselves, - * starting with 1. Then we use this id to disable the breakpoint, - * if necessary. If this assignment of ids doesn't work, (maybe - * because this isn't a fresh gdb at all), we disable the wrong - * breakpoint! Oh well... for now it works. + * Add the breakpoint. */ - if (!fileName.isEmpty()) { - m_d->executeCmd(temporary ? DCtbreakline : DCbreakline, - fileName, lineNo); + CmdQueueItem* cmd; + if (!bp->fileName.isEmpty()) { + cmd = m_d->executeCmd(bp->temporary ? DCtbreakline : DCbreakline, + bp->fileName, bp->lineNo); } else { - m_d->executeCmd(temporary ? DCtbreakaddr : DCbreakaddr, - address); - } - if (!enabled) { - m_d->executeCmd(DCdisable, i+1); - } - if (!condition.isEmpty()) { - m_d->executeCmd(DCcondition, condition, i+1); + cmd = m_d->executeCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr, + bp->address.asString()); } + // the new breakpoint is disabled or conditionalized later + // in newBreakpoint() using this reference: + cmd->m_brkpt = bp; } m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride); } @@ -926,7 +921,7 @@ void KDebugger::parse(CmdQueueItem* cmd, const char* output) case DCbreakaddr: case DCtbreakaddr: case DCwatchpoint: - newBreakpoint(output); + newBreakpoint(cmd, output); // fall through case DCdelete: case DCenable: @@ -1738,13 +1733,36 @@ void KDebugger::handleRegisters(const char* output) * The output of the DCbreak* commands has more accurate information about * the file and the line number. */ -void KDebugger::newBreakpoint(const char* output) +void KDebugger::newBreakpoint(CmdQueueItem* cmd, const char* output) { int id; QString file; int lineNo; - if (!m_d->parseBreakpoint(output, id, file, lineNo)) + QString address; + if (!m_d->parseBreakpoint(output, id, file, lineNo, address)) + { + delete cmd->m_brkpt; return; + } + + // is this a breakpoint restored from the settings? + if (cmd->m_brkpt != 0) + { + // yes, add it + cmd->m_brkpt->id = id; + + int n = m_brkpts.size(); + m_brkpts.resize(n+1); + m_brkpts[n] = cmd->m_brkpt; + + // set the remaining properties + if (!cmd->m_brkpt->enabled) { + m_d->executeCmd(DCdisable, id); + } + if (!cmd->m_brkpt->condition.isEmpty()) { + m_d->executeCmd(DCcondition, cmd->m_brkpt->condition, id); + } + } // see if it is new for (int i = m_brkpts.size()-1; i >= 0; i--) { @@ -1752,6 +1770,8 @@ void KDebugger::newBreakpoint(const char* output) // not new; update m_brkpts[i]->fileName = file; m_brkpts[i]->lineNo = lineNo; + if (!address.isEmpty()) + m_brkpts[i]->address = address; return; } } @@ -1764,6 +1784,7 @@ void KDebugger::newBreakpoint(const char* output) bp->ignoreCount = 0; bp->fileName = file; bp->lineNo = lineNo; + bp->address = address; int n = m_brkpts.size(); m_brkpts.resize(n+1); m_brkpts[n] = bp; diff --git a/kdbg/debugger.h b/kdbg/debugger.h index 8d70893..642d337 100644 --- a/kdbg/debugger.h +++ b/kdbg/debugger.h @@ -330,7 +330,7 @@ protected: Breakpoint* breakpointByFilePos(QString file, int lineNo, const DbgAddr& address); - void newBreakpoint(const char* output); + void newBreakpoint(CmdQueueItem* cmd, const char* output); void updateBreakList(const char* output); bool stopMayChangeBreakList() const; void saveBreakpoints(KSimpleConfig* config); diff --git a/kdbg/gdbdriver.cpp b/kdbg/gdbdriver.cpp index f9ee182..b5c9afb 100644 --- a/kdbg/gdbdriver.cpp +++ b/kdbg/gdbdriver.cpp @@ -1764,7 +1764,7 @@ bool GdbDriver::parseThreadList(const char* output, QList& threads) } bool GdbDriver::parseBreakpoint(const char* output, int& id, - QString& file, int& lineNo) + QString& file, int& lineNo, QString& address) { const char* o = output; // skip lines of that begin with "(Cannot find" @@ -1781,14 +1781,23 @@ bool GdbDriver::parseBreakpoint(const char* output, int& id, // breakpoint id output += 11; /* skip "Breakpoint " */ char* p; - int num = strtoul(output, &p, 10); + id = strtoul(output, &p, 10); if (p == o) return false; + + // check for the address + if (strncmp(p, " at 0x", 6) == 0) { + char* start = p+4; /* skip " at ", but not 0x */ + p += 6; + while (isxdigit(*p)) + ++p; + address = FROM_LATIN1(start, p-start); + } // file name char* fileStart = strstr(p, "file "); if (fileStart == 0) - return false; + return !address.isEmpty(); /* parse error only if there's no address */ fileStart += 5; // line number @@ -1799,7 +1808,6 @@ bool GdbDriver::parseBreakpoint(const char* output, int& id, if (numStart == p) return false; - id = num; file = fileName; lineNo = line-1; /* zero-based! */ return true; diff --git a/kdbg/gdbdriver.h b/kdbg/gdbdriver.h index 6ccadcf..d188bdb 100644 --- a/kdbg/gdbdriver.h +++ b/kdbg/gdbdriver.h @@ -56,7 +56,7 @@ public: virtual bool parseBreakList(const char* output, QList& brks); virtual bool parseThreadList(const char* output, QList& threads); virtual bool parseBreakpoint(const char* output, int& id, - QString& file, int& lineNo); + QString& file, int& lineNo, QString& address); virtual void parseLocals(const char* output, QList& newVars); virtual bool parsePrintExpr(const char* output, bool wantErrorValue, VarTree*& var); diff --git a/kdbg/xsldbgdriver.cpp b/kdbg/xsldbgdriver.cpp index 5262c64..79d6497 100644 --- a/kdbg/xsldbgdriver.cpp +++ b/kdbg/xsldbgdriver.cpp @@ -1252,7 +1252,7 @@ XsldbgDriver::parseThreadList(const char */*output*/, bool XsldbgDriver::parseBreakpoint(const char */*output*/, int &/*id*/, - QString & /*file*/, int &/*lineNo*/) + QString & /*file*/, int &/*lineNo*/, QString&/*address*/) { TRACE("parseBreakpoint"); return true; diff --git a/kdbg/xsldbgdriver.h b/kdbg/xsldbgdriver.h index 05198f6..beb83c1 100644 --- a/kdbg/xsldbgdriver.h +++ b/kdbg/xsldbgdriver.h @@ -64,7 +64,7 @@ class XsldbgDriver:public DebuggerDriver { virtual bool parseThreadList(const char *output, QList < ThreadInfo > &threads); virtual bool parseBreakpoint(const char *output, int &id, - QString & file, int &lineNo); + QString & file, int &lineNo, QString& address); virtual void parseLocals(const char *output, QList < VarTree > &newVars); virtual bool parsePrintExpr(const char *output, bool wantErrorValue, -- 2.11.4.GIT