Git commit ae04361c5c222e2607b929a52712f6c0b3617e34 by Shaheed Haque. Committed on 01/01/2013 at 00:32. Pushed by shaheed into branch 'master'. Restart development 1. Migrate to Python 3. 2. Move to invoking gdb itself with --interpreter=3Dmi, and adapt parsing accordingly. M +43 -43 kate/plugins/pate/src/plugins/gdb/cli.py M +5 -2 kate/plugins/pate/src/plugins/gdb/miparser.py M +164 -185 kate/plugins/pate/src/plugins/gdb/qgdb.py http://commits.kde.org/kate/ae04361c5c222e2607b929a52712f6c0b3617e34 diff --git a/kate/plugins/pate/src/plugins/gdb/cli.py b/kate/plugins/pate/s= rc/plugins/gdb/cli.py index 2341dd8..808e821 100644 --- a/kate/plugins/pate/src/plugins/gdb/cli.py +++ b/kate/plugins/pate/src/plugins/gdb/cli.py @@ -89,16 +89,20 @@ class CommandDb(object): # classes_db =3D None = - def __init__(self, helpText): + def __init__(self, gdb): super(CommandDb, self).__init__() # # Start from scratch. # self.keyword_db =3D dict() self.classes_db =3D list() - + # + # First, read all the command line help to find out what GDB has. + # + helpText =3D gdb.consoleCommand("help all", True) clazz =3D None for line in helpText: + line =3D line.strip() if line.startswith("Command class"): clazz =3D line[15:] self.classes_db.append(clazz) @@ -136,6 +140,8 @@ class CommandDb(object): # Add the new keyword to the current dictionary. # dictionary[keywords[i]] =3D (apropos, None, clazz,= None) + else: + raise Exception("Unmatched line '{}'".format(line)) = def addCustom(self, function): """Add a custom command to the global database. @@ -276,7 +282,7 @@ class CommandDb(object): """ Walk the contents of the database level. """ - for keyword in sorted(level.iterkeys()): + for keyword in sorted(level.keys()): (oldApropos, oldLevel, oldClazz, oldFunction) =3D level[keywor= d] userCallback(userFilter, userArg, indentation, prefix, keyword= , oldApropos, oldClazz, oldFunction) if oldLevel: @@ -366,9 +372,6 @@ class Cli(cmd.Cmd): #self.gdb.start() #_gdbThreadStarted.acquire() self.gdb =3D QGdbInterpreter(["gdb"]) - # - # Ask GDB for all the commands it has. - # self.createCommandDb() = def dbg0(self, msg, *args): @@ -383,12 +386,9 @@ class Cli(cmd.Cmd): def createCommandDb(self): """Create a command database we can use to implement our CLI.""" # - # First, read all the command line help to find out what GDB has. + # Ask GDB for all the commands it has. # - error, helpText =3D self.gdb.consoleCommand("h all") - if error: - raise QGdbException("Unable to read supported commands: {} '{}= '..'{}'".format(error, helpText[0], helpText[-1])) - self.commandDb =3D CommandDb(helpText) + self.commandDb =3D CommandDb(self.gdb) self.findFilesCommand() # # Add in all our overrides; that's any routine starting doXXX. @@ -610,8 +610,8 @@ class Cli(cmd.Cmd): = def do_disassemble(self, args, getSynopsis =3D False): parser =3D MyArgs(prog =3D "disassemble", add_help =3D False) - parser.add_argument("-s", "--start-addr", type =3D long) - parser.add_argument("-e", "--end-addr", type =3D long) + parser.add_argument("-s", "--start-addr", type =3D int) + parser.add_argument("-e", "--end-addr", type =3D int) parser.add_argument("-f", "--filename") parser.add_argument("-l", "--linenum", type =3D int) parser.add_argument("-n", "--lines", type =3D int) @@ -725,13 +725,13 @@ class Cli(cmd.Cmd): = def do_x(self, args, getSynopsis =3D False): parser =3D MyArgs(prog =3D "x", add_help =3D False) - parser.add_argument("address", type =3D long) + parser.add_argument("address", type =3D int) parser.add_argument("word_format", choices =3D ["x", "d", "u", "o"= , "t", "a", "c", "f"]) parser.add_argument("word_size", type =3D int) parser.add_argument("nr_rows", type =3D int) parser.add_argument("nr_cols", type =3D int) parser.add_argument("aschar", nargs=3D"?", default =3D ".") - parser.add_argument("-o", "--offset-bytes", type =3D long) + parser.add_argument("-o", "--offset-bytes", type =3D int) if getSynopsis: return parser.format_help() args =3D parser.parse_args(args.split()) @@ -1219,35 +1219,35 @@ class Cli(cmd.Cmd): #'-interpreter-exec' #'-list-features' = - def do_apropos(self, args): - """ - support - NAME - apropos -- Search for commands matching a REGEXP + def do_apropos(self, args): + """ + support + NAME + apropos -- Search for commands matching a REGEXP = - SYNOPSIS - apropos REGEXP + SYNOPSIS + apropos REGEXP = - DESCRIPTION - Type "apropos word" to search for commands related to "wor= d". - """ + DESCRIPTION + Type "apropos word" to search for commands related to "word". + """ = - def printAproposEntry(regexp, arg, indentation, prefix, keywor= d, apropos, clazz, function): - """Dump the contents of the database as help text. - Only leaf items which match the given regexp are emitted. - """ - if regexp.search(keyword) or regexp.search(apropos): - self._out("\t" + prefix + keyword + " -- " + apropos) + def printAproposEntry(regexp, arg, indentation, prefix, keyword, a= propos, clazz, function): + """Dump the contents of the database as help text. + Only leaf items which match the given regexp are emitted. + """ + if regexp.search(keyword) or regexp.search(apropos): + self._out("\t" + prefix + keyword + " -- " + apropos) = - # - # We emit our help database, so that we can override GDB if ne= eded. - # - if args =3D=3D "": - self._out("REGEXP string is empty") - return - self._out("LIST OF COMMANDS MATCHING '" + args + "'") - self.commandDb.walk(printAproposEntry, re.compile(args, re.IGN= ORECASE), None, "\t") - print + # + # We emit our help database, so that we can override GDB if needed. + # + if args =3D=3D "": + self._out("REGEXP string is empty") + return + self._out("LIST OF COMMANDS MATCHING '" + args + "'") + self.commandDb.walk(printAproposEntry, re.compile(args, re.IGNOREC= ASE), None, "\t") + print = def do_EOF(self, args): """ @@ -1343,7 +1343,7 @@ class Cli(cmd.Cmd): # # Emit GDB help for the class. # - error, helpText =3D self.gdb.consoleCommand("help " + = classes[0]) + error, helpText =3D self.gdb.consoleCommand("help " + = classes[0], True) apropos =3D helpText[0] synopsis =3D None for i in range(1, len(helpText)): @@ -1415,7 +1415,7 @@ class Cli(cmd.Cmd): # # Emit help for the GDB implementation. # - error, helpText =3D self.gdb.consoleCommand("help " + matc= hed) + error, helpText =3D self.gdb.consoleCommand("help " + matc= hed, True) if len(helpText) > 1 and (helpText[1].startswith(matched) = or helpText[1].startswith("Usage:")): synopsis =3D helpText[1] helpText =3D ["\t" + line for line in helpText[2:]] @@ -1440,7 +1440,7 @@ class Cli(cmd.Cmd): # # Emit summary help from GDB. # - error, helpText =3D self.gdb.consoleCommand("help") + error, helpText =3D self.gdb.consoleCommand("help", True) self._out("LIST OF CLASSES OF COMMANDS") for line in helpText[2:]: self._out("\t" + line) diff --git a/kate/plugins/pate/src/plugins/gdb/miparser.py b/kate/plugins/p= ate/src/plugins/gdb/miparser.py index b6d32fe..b4766e6 100644 --- a/kate/plugins/pate/src/plugins/gdb/miparser.py +++ b/kate/plugins/pate/src/plugins/gdb/miparser.py @@ -77,7 +77,10 @@ class MiParser(): try: t.value =3D hex(int(t.value, 16)) except ValueError: - pass + # + # De-escape strings. + # + t.value =3D t.value.replace("\\n", "\n").replace("\\t", "\= t").replace('\\"', '"') return t = # Error handling rule @@ -112,7 +115,7 @@ class MiParser(): # 'named_values : named_values COMMA value' p[0] =3D dict() - for k, v in p[1].iteritems(): + for k, v in p[1].items(): if isinstance(v, dict): v =3D [v] v.append(p[3]) diff --git a/kate/plugins/pate/src/plugins/gdb/qgdb.py b/kate/plugins/pate/= src/plugins/gdb/qgdb.py index 52786f4..5f10b46 100644 --- a/kate/plugins/pate/src/plugins/gdb/qgdb.py +++ b/kate/plugins/pate/src/plugins/gdb/qgdb.py @@ -22,6 +22,8 @@ import os = from PyQt4.QtCore import * from PyKDE4.kdecore import * +import sys +sys.argv =3D ["gdb"] from IPython.zmq.ipkernel import IPKernelApp = from miparser import MiParser @@ -29,10 +31,10 @@ from miparser import MiParser class QGdbException(Exception): pass = -class QGdbTimeoutError(QGdbException): +class QGdbInterrupted(QGdbException): pass = -class QGdbInvalidResults(QGdbException): +class QGdbTimeoutError(QGdbException): pass = class QGdbExecuteError(QGdbException): @@ -76,8 +78,8 @@ class DebuggerKernel(): s.stop_on_recv() s.close() = - class InferiorIo(QThread): + """Thread handling IO with the running inferior.""" _pty =3D None def __init__(self, parent): super(InferiorIo, self).__init__(parent) @@ -100,7 +102,7 @@ class InferiorIo(QThread): line =3D self._masterFd.readline() if not line: break - self.parent().gdbStreamTarget.emit(line[:-1]) + self.parent().gdbStreamInferior.emit(line[:-1]) print("inferior reader done!!!!") = def interruptWait(self): @@ -145,9 +147,10 @@ class DebuggerIo(QThread): # # Start. # + self.arguments.insert(1, "--interpreter=3Dmi") self._gdbThread.start(self.arguments[0], self.arguments[1:]) self._gdbThread.waitForStarted() - self.waitForPromptConsole("cmd: " + self.arguments[0]) + self.waitForPrompt(None, "cmd: " + self.arguments[0]) except QGdbException as e: self.dbg0("TODO make signal work: {}", e) traceback.print_exc() @@ -162,49 +165,50 @@ class DebuggerIo(QThread): self._inferiorThread =3D InferiorIo(self) return self._inferiorThread.ttyName() = - def consoleCommand(self, command): + def consoleCommand(self, command, captureConsole =3D False): + """Execute a non-MI command using the GDB/MI interpreter.""" + #command =3D "interpreter-exec mi \"{}\"".format(command) self.dbg1("consoleCommand: {}", command) self._gdbThread.write(command + "\n") self._gdbThread.waitForBytesWritten() - return self.waitForPromptConsole(command) + records =3D self.waitForPrompt("", command, captureConsole) + status, msg =3D records[-1] + del records[-1] + if status or msg: + raise QGdbException("Unexpected {} result, {}".format(status, = msg)) + return records = def miCommand(self, command): - """Execute a command using the GDB/MI interpreter.""" + """Execute a MI command using the GDB/MI interpreter.""" self._miToken +=3D 1 - command =3D "interpreter-exec mi \"{}{}\"".format(self._miToken, c= ommand) + #command =3D "interpreter-exec mi \"{}{}\"".format(self._miToken, = command) + command =3D "{}{}".format(self._miToken, command) self.dbg1("miCommand: '{}'", command) self._gdbThread.write(command + "\n") self._gdbThread.waitForBytesWritten() - return self.waitForPromptMi(self._miToken, command) + records =3D self.waitForPrompt(str(self._miToken), command) + status, msg =3D records[-1] + del records[-1] + if status or msg: + raise QGdbException("Unexpected {} result, {}".format(status, = msg)) + return records = def miCommandOne(self, command): """A specialisation of miCommand() where we expect exactly one res= ult record.""" - error, records =3D self.miCommand(command) - # - # We expect exactly one record. - # - if error =3D=3D curses.ascii.CAN: - raise QGdbTimeoutError("Timeout after {} results, '{}' ".forma= t(len(records), records)) - elif len(records) !=3D 1: - raise QGdbInvalidResults("Expected 1 result, not {}, '{}' ".fo= rmat(len(records), records)) - status, results =3D records[0] - self.dbg2("miCommandOne: {}", records[0]) - if status =3D=3D "error": - raise QGdbExecuteError(results[0][5:-1]) - return results + records =3D self.miCommand(command) + if records: + raise QGdbException("Unexpected {} records {}".format(len(reco= rds), records)) = def miCommandExec(self, command, args): self.miCommandOne(command) = - def waitForPromptConsole(self, why, endLine =3D None, timeoutMs =3D 10= 000): + def waitForPrompt(self, token, why, captureConsole =3D False, endLine = =3D None, timeoutMs =3D 10000): """Read responses from GDB until a prompt, or interrupt. = - @return (error, lines) Where error is None (normal prompt seen), - curses.ascii.ESC (user interrupt) or - curses.ascii.CAN (caller timeout) + @return lines Each entry in the lines array is either a console = string or a + parsed dictionary of output. The last entry should= be a result. """ prompt =3D "(gdb) " - lines =3D [] maxTimeouts =3D timeoutMs / 100 self.dbg1("reading for: {}", why) @@ -218,130 +222,94 @@ class DebuggerIo(QThread): maxTimeouts -=3D 1 if self._gdbThread.canReadLine(): line =3D self._gdbThread.readLine() - line =3D unicode(line[:-1], "utf-8") - lines.append(line) - if endLine and line.startswith(endLine): - # - # Yay, got to the end! - # - self.dbg2("All lines read: {}", len(lines)) - return (None, lines) - # - # We managed to read a line, so reset the timeout. - # - maxTimeouts =3D timeoutMs / 100 - elif self._gdbThread.peek(len(prompt)) =3D=3D prompt: - self._gdbThread.read(len(prompt)) - # - # Yay, got to the end! + line =3D str(line[:-1], "utf-8") # - self.dbg2("All lines read: {}", len(lines)) - return (None, lines) - elif self._interruptPending: - # - # User got fed up. Note, there may be more to read! - # - self.dbg0("Interrupt after {} lines read, '{}'", len(lines= ), lines) - return (curses.ascii.ESC, lines) - elif not maxTimeouts: + # TODO: check what IPython does now. # - # Caller got fed up. Note, there may be more to read! - # - self.dbg0("Timeout after {} lines read, '{}'", len(lines),= lines) - return (curses.ascii.CAN, lines) - - def waitForPromptMi(self, token, why, timeoutMs =3D 10000): - """Read responses from GDB until a prompt, or interrupt. - - @return (error, lines) Where error is None (normal prompt seen), - curses.ascii.ESC (user interrupt) or - curses.ascii.CAN (caller timeout) - """ - prompt =3D "(gdb) " - lines =3D [] - maxTimeouts =3D timeoutMs / 100 - self.dbg1("reading for: {}", why) - self._interruptPending =3D False - token =3D str(token) - while True: - while not self._gdbThread.canReadLine() and \ - self._gdbThread.peek(len(prompt)) !=3D prompt and \ - not self._interruptPending and \ - maxTimeouts: - self._gdbThread.waitForReadyRead(100) - maxTimeouts -=3D 1 - if self._gdbThread.canReadLine(): - line =3D self._gdbThread.readLine() - line =3D unicode(line[:-1], "utf-8") - if line[0] =3D=3D "~": - line =3D line[1:] - # - # Console stream record. Not added to return value! - # - self.gdbStreamConsole.emit(line) - elif line[0] =3D=3D "@": - line =3D line[1:] - # - # Target stream record. Not added to return value! - # - self.gdbStreamTarget.emit(line) - elif line[0] =3D=3D "&": - line =3D line[1:] - # - # Log stream record. Not added to return value! - # - self.gdbStreamLog.emit(line) - elif line[0] =3D=3D "*": + if endLine and line.startswith(endLine): # - # OOB record. + # Yay, got to the end! # - line =3D line[1:] - tuple =3D self.parseOobRecord(line) - self.signalEvent(tuple[0], tuple[1]) - lines.append(tuple) - elif line.startswith(token + "^"): + self.dbg2("TODO: check what IPython does: All lines re= ad: {}", len(lines)) + return lines + elif line =3D=3D prompt: # - # Result record. + # Yay, got to the end! # - line =3D line[len(token) + 1:] - tuple =3D self.parseResultRecord(line) - self.signalEvent(tuple[0], tuple[1]) - lines.append(tuple) + self.dbg2("All lines read: {}", len(lines)) + return lines else: - # TODO: other record types. - self.dbg0("NYI: unexpected record string {}", line) + line =3D self.parseLine(line, token, captureConsole) + if line: + lines.append(line) # # We managed to read a line, so reset the timeout. # maxTimeouts =3D timeoutMs / 100 - elif self._gdbThread.peek(len(prompt)) =3D=3D prompt: - self._gdbThread.read(len(prompt)) - # - # Yay, got to the end! - # - self.dbg2("All lines read: {}", len(lines)) - return (None, lines) elif self._interruptPending: # # User got fed up. Note, there may be more to read! # - self.dbg0("Interrupt after {} lines read", len(lines)) - return (curses.ascii.ESC, lines) + raise QGdbInterrupted("Interrupt after {} lines read, {}".= format(len(lines), lines)) elif not maxTimeouts: # # Caller got fed up. Note, there may be more to read! # - self.dbg0("Timeout after {} lines read", len(lines)) - return (curses.ascii.CAN, lines) + raise QGdbTimeoutError("Timeout after {} lines read, {}".f= ormat(len(lines), lines)) + + def parseLine(self, line, token, captureConsole =3D False): + if line[0] =3D=3D "~": + line =3D self.parseStringRecord(line[1:]) + # + # GDB console stream record. Not added to return value unless = the caller + # asked for it. + # + if captureConsole: + return line + else: + self.gdbStreamConsole.emit(line) + elif line[0] =3D=3D "@": + line =3D self.parseStringRecord(line[1:]) + # + # Target stream record. Not added to return value! + # + self.gdbStreamInferior.emit(line) + elif line[0] =3D=3D "&": + line =3D self.parseStringRecord(line[1:]) + # + # GDB log stream record. Not added to return value! + # + self.gdbStreamLog.emit(line) + elif line[0] in ["*", "=3D"]: + # + # GDB OOB stream record. TODO: does "*" mean inferior state ch= ange to stopped? + # + line =3D line[1:] + tuple =3D self.parseOobRecord(line) + self.signalEvent(tuple[0], tuple[1]) + return tuple + elif line.startswith(token + "^"): + # + # GDB result-of-command record. + # + line =3D line[len(token) + 1:] + tuple =3D self.parseResultRecord(line) + self.signalEvent(tuple[0], tuple[1]) + return tuple + else: + # TODO: other record types. + self.dbg0("NYI: unexpected record string '{}'", line) + return None + + def parseStringRecord(self, line): + return self.miParser.parse("t=3D" + line)['t'].strip() = def parseOobRecord(self, line): """GDB/MI OOB record.""" self.dbg1("OOB string {}", line) tuple =3D line.split(",", 1) - if tuple[0] =3D=3D "stop": - tuple[0] =3D "" - else: - self.dbg0("Unexpected OOB string {}", line) + if tuple[0] in ["stop", "stopped"]: + tuple[0] =3D "stopped" if len(tuple) > 1: tuple[1] =3D self.miParser.parse(tuple[1]) else: @@ -352,18 +320,20 @@ class DebuggerIo(QThread): def parseResultRecord(self, line): """GDB/MI Result record. = - @param result "error" for ^error - "exit" for ^exit - "" for normal cases (^done, ^running, ^connected) - @param data "c-string" for ^error - "results" for ^done + @param result "error" for ^error + "exit" for ^exit + "" for normal cases (^done, ^running, ^connected) + @param data "c-string" for ^error + "results" for ^done """ self.dbg1("Result string {}", line) tuple =3D line.split(",", 1) - if tuple[0] in ["done", "running" ]: + if tuple[0] in ["done", "running"]: tuple[0] =3D "" - elif tuple[0] !=3D "error": - self.dbg0("Unexpected result string {}", line) + elif tuple[0] =3D=3D "error": + raise QGdbExecuteError(self.miParser.parse(tuple[1])["msg"]) + else: + raise QGdbException("Unexpected result string '{}'".format(lin= e)) if len(tuple) > 1: tuple[1] =3D self.miParser.parse(tuple[1]) else: @@ -372,47 +342,57 @@ class DebuggerIo(QThread): return tuple = def signalEvent(self, event, args): - """Signal whoever is interested of interesting events.""" - if event =3D=3D "stop": - self.onStopped.emit(args) - elif event.startswith("thread-group"): - if event =3D=3D "thread-group-added": - self.onThreadGroupAdded.emit(args) - elif event =3D=3D "thread-group-removed": - self.onThreadGroupRemoved.emit(args) - elif event =3D=3D "thread-group-started": - self.onThreadGroupStarted.emit(args) - elif event =3D=3D "thread-group-exited": - self.onThreadGroupExited.emit(args) - else: - self.onUnknownEvent.emit(event, args) - elif event.startswith("thread"): - if event =3D=3D "thread-created": - self.onThreadCreated.emit(args) - elif event =3D=3D "thread-exited": - self.onThreadExited.emit(args) - elif event =3D=3D "thread-selected": - self.onThreadSelected.emit(args) - else: - self.onUnknownEvent.emit(event, args) - elif event.startswith("library"): - if event =3D=3D "library-loaded": - self.onLibraryLoaded.emit(args) - elif event =3D=3D "library-unloaded": - self.onLibraryUnloaded.emit(args) - else: - self.onUnknownEvent.emit(event, args) - elif event.startswith("breakpoint"): - if event =3D=3D "breakpoint-created": - self.onBreakpointCreated.emit(args) - elif event =3D=3D "breakpoint-modified": - self.onBreakpointModified.emit(args) - elif event =3D=3D "breakpoint-deleted": - self.onBreakpointDeleted.emit(args) + """Signal any interesting events.""" + try: + if event =3D=3D "stopped": + self.onStopped.emit(args) + elif event.startswith("thread-group"): + id =3D args["id"] + if event =3D=3D "thread-group-added": + self.onThreadGroupAdded.emit(id) + elif event =3D=3D "thread-group-removed": + self.onThreadGroupRemoved.emit(id) + elif event =3D=3D "thread-group-started": + self.onThreadGroupStarted.emit(id, int(args["pid"])) + elif event =3D=3D "thread-group-exited": + try: + exitCode =3D int(args["exit-code"]) + except KeyError: + exitCode =3D 0 + self.onThreadGroupExited.emit(id, exitCode) + else: + self.onUnknownEvent.emit(event, args) + elif event.startswith("thread"): + if event =3D=3D "thread-created": + self.onThreadCreated.emit(args) + elif event =3D=3D "thread-exited": + self.onThreadExited.emit(args) + elif event =3D=3D "thread-selected": + self.onThreadSelected.emit(args) + else: + self.onUnknownEvent.emit(event, args) + elif event.startswith("library"): + if event =3D=3D "library-loaded": + self.onLibraryLoaded.emit(args) + elif event =3D=3D "library-unloaded": + self.onLibraryUnloaded.emit(args) + else: + self.onUnknownEvent.emit(event, args) + elif event.startswith("breakpoint"): + if event =3D=3D "breakpoint-created": + self.onBreakpointCreated.emit(args) + elif event =3D=3D "breakpoint-modified": + self.onBreakpointModified.emit(args) + elif event =3D=3D "breakpoint-deleted": + self.onBreakpointDeleted.emit(args) + else: + self.onUnknownEvent.emit(event, args) else: self.onUnknownEvent.emit(event, args) - else: - self.onUnknownEvent.emit(event, args) + except Exception as e: + self.dbg0("TODO make signal work: {}", e) + traceback.print_exc() + self.dbg.emit(0, str(e)) = def dbg0(self, msg, *args): print("ERR-0", msg.format(*args)) @@ -447,7 +427,7 @@ class DebuggerIo(QThread): gdbStreamConsole =3D pyqtSignal('QString') = """GDB/MI Stream record, GDB target output.""" - gdbStreamTarget =3D pyqtSignal('QString') + gdbStreamInferior =3D pyqtSignal('QString') = """GDB/MI Stream record, GDB log output.""" gdbStreamLog =3D pyqtSignal('QString') @@ -462,9 +442,9 @@ class DebuggerIo(QThread): """thread-group-removed,id=3D"id". """ onThreadGroupRemoved =3D pyqtSignal('QString') """thread-group-started,id=3D"id",pid=3D"pid". """ - onThreadGroupStarted =3D pyqtSignal('QString', 'QString') + onThreadGroupStarted =3D pyqtSignal('QString', int) """thread-group-exited,id=3D"id"[,exit-code=3D"code"]. """ - onThreadGroupExited =3D pyqtSignal('QString', 'QString') + onThreadGroupExited =3D pyqtSignal('QString', int) = """thread-created,id=3D"id",group-id=3D"gid". """ onThreadCreated =3D pyqtSignal('QString', 'QString') @@ -480,11 +460,11 @@ class DebuggerIo(QThread): onLibraryUnloaded =3D pyqtSignal('QString', 'QString', 'QString', 'QSt= ring') = """breakpoint-created,bkpt=3D{...}. """ - onBreakpointCreated =3D pyqtSignal('QString') + onBreakpointCreated =3D pyqtSignal(dict) """breakpoint-modified,bkpt=3D{...}. """ - onBreakpointModified =3D pyqtSignal('QString') + onBreakpointModified =3D pyqtSignal(dict) """breakpoint-deleted,bkpt=3D{...}. """ - onBreakpointDeleted =3D pyqtSignal('QString') + onBreakpointDeleted =3D pyqtSignal(dict) = class Breakpoints(): """Model of GDB breakpoints, tracepoints and watchpoints.""" @@ -791,7 +771,7 @@ class Python(): # Wait for the line that announces the IPython connection stri= ng. # connectionInfo =3D "[IPKernelApp] --existing " - error, lines =3D self._gdb.waitForPromptConsole(command, endLi= ne =3D connectionInfo) + error, lines =3D self._gdb.waitForPrompt(None, command, endLin= e =3D connectionInfo) if not lines[-1].startswith(connectionInfo): raise QGdbException("IPython connection error '{}'".format= (lines)) self._connectionId =3D lines[-1][len(connectionInfo):] @@ -801,12 +781,11 @@ class Python(): def exit(self): command =3D "%Quit" self._pythonCommand(command) - error, lines =3D self._gdb.waitForPromptConsole("xxxxxxxxxxxxxxx") + error, lines =3D self._gdb.waitForPrompt(None, "xxxxxxxxxxxxxxx") print("exiting!!!!!!!!!!!!!",error,lines) - error, lines =3D self._gdb.waitForPromptConsole("yyyyyyyyyyy") + error, lines =3D self._gdb.waitForPrompt(None, "yyyyyyyyyyy") print("exiting222!!!!!!!!!!!!!",error,lines) = - class Stack(): """Model of GDB stack.""" =20