# HG changeset patch # User Egor Ushakov # Date 1233841350 -10800 # Node ID 4261df01ab8eaf2c07498ca458ed18ad60d93909 # Parent db1a3a2b82ea6ebf657a2b4e15c72401b1b8cc4b fix for IZ:156138 (IDE hangs on start debugger) diff -r db1a3a2b82ea -r 4261df01ab8e cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/GdbContext.java --- a/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/GdbContext.java Thu Jan 29 15:55:27 2009 +0100 +++ b/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/GdbContext.java Thu Feb 05 16:42:30 2009 +0300 @@ -44,10 +44,7 @@ import java.beans.PropertyChangeSupport; import java.util.HashMap; import java.util.Map; -import org.netbeans.api.debugger.DebuggerEngine; -import org.netbeans.api.debugger.DebuggerManager; import org.netbeans.modules.cnd.debugger.gdb.proxy.GdbProxy; -import org.netbeans.modules.cnd.debugger.gdb.utils.CommandBuffer; /** * Describes a context of debugging @@ -63,18 +60,25 @@ private static final int SYNC_UPDATE_TIMEOUT=30000; public static final String PROP_REGISTERS = "Registers"; // NOI18N + public static final String PROP_STEP = "Step"; // NOI18N + public static final String PROP_EXIT = "Exit"; // NOI18N private GdbContext() { requests.put(PROP_REGISTERS, new Request() { - protected void request(CommandBuffer cb, GdbProxy gdb) { - gdb.data_list_register_values(cb, ""); // NOI18N - gdb.data_list_changed_registers(cb); + protected void request(GdbProxy gdb) { + gdb.data_list_register_values(""); // NOI18N + gdb.data_list_changed_registers(); } }); pcs.addPropertyChangeListener(this); // used to notify sync updates } + + public void gdbExit() { + invalidate(true); + pcs.firePropertyChange(PROP_EXIT, 0, 1); + } - public void invalidate(boolean fireUpdates) { + private void invalidate(boolean fireUpdates) { cache.clear(); // fire updates if requested @@ -87,14 +91,15 @@ } } - public void update() { + public void gdbStep() { invalidate(false); //request update of all properties that have listeners for (Map.Entry entry : requests.entrySet()) { if (hasListeners(entry.getKey())) { - entry.getValue().run(true); + entry.getValue().run(/*true*/); } } + pcs.firePropertyChange(PROP_STEP, 0, 1); } public void propertyChange(PropertyChangeEvent evt) { @@ -118,7 +123,7 @@ } synchronized (lock) { waitLocks.put(name, lock); - if (child || requests.get(name).run(true)) { + if (child || requests.get(name).run(/*true*/)) { try { lock.wait(SYNC_UPDATE_TIMEOUT); } catch (InterruptedException ie) { @@ -140,7 +145,10 @@ pcs.addPropertyChangeListener(propertyName, listener); //request property update if needed if (!cache.containsKey(propertyName)) { - requests.get(propertyName).run(true); + Request request = requests.get(propertyName); + if (request != null) { + requests.get(propertyName).run(/*true*/); + } } } @@ -161,11 +169,7 @@ } public static GdbProxy getCurrentGdb() { - DebuggerEngine currentEngine = DebuggerManager.getDebuggerManager().getCurrentEngine(); - if (currentEngine == null) { - return null; - } - GdbDebugger debugger = currentEngine.lookupFirst(null, GdbDebugger.class); + GdbDebugger debugger = GdbDebugger.getGdbDebugger(); if (debugger == null) { return null; } @@ -174,22 +178,22 @@ /////// Request private static abstract class Request { - public boolean run(boolean async) { + public boolean run(/*boolean async*/) { GdbProxy gdb = getCurrentGdb(); if (gdb != null) { - CommandBuffer cb = null; - if (!async) { - cb = new CommandBuffer(gdb); - } - request(cb, gdb); - if (cb != null) { - cb.waitForCompletion(); - } +// CommandBuffer cb = null; +// if (!async) { +// cb = new CommandBuffer(gdb); +// } + request(/*cb,*/ gdb); +// if (cb != null) { +// cb.waitForCompletion(); +// } return true; } return false; } - protected abstract void request(CommandBuffer cb, GdbProxy gdb); + protected abstract void request(/*CommandBuffer cb, */GdbProxy gdb); } } diff -r db1a3a2b82ea -r 4261df01ab8e cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/GdbDebugger.java --- a/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/GdbDebugger.java Thu Jan 29 15:55:27 2009 +0100 +++ b/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/GdbDebugger.java Thu Feb 05 16:42:30 2009 +0300 @@ -290,7 +290,7 @@ boolean isSharedLibrary = false; final String path = getFullPath(baseDir, pae.getExecutable()); - programPID = (Long) lookupProvider.lookupFirst(null, Long.class); + programPID = lookupProvider.lookupFirst(null, Long.class); if (((MakeConfiguration) pae.getConfiguration()).isDynamicLibraryConfiguration()) { pgm = getExePath(programPID); gdb.file_exec_and_symbols(pgm); @@ -298,11 +298,9 @@ } else { gdb.file_exec_and_symbols(path); } - CommandBuffer cb = new CommandBuffer(gdb); - gdb.target_attach(cb, Long.toString(programPID)); - cb.waitForCompletion(); + CommandBuffer cb = gdb.target_attach(Long.toString(programPID)); String err = cb.getError(); - if (err != null || cb.timedOut()) { + if (err != null || cb.isTimedOut()) { final String msg; if (err == null) { msg = NbBundle.getMessage(GdbDebugger.class, "ERR_AttachTimeout"); // NOI18N @@ -331,7 +329,7 @@ } // 1) see if path was explicitly loaded by target_attach (this is system dependent) - if (!symbolsRead(cb.toString(), path)) { + if (!symbolsRead(cb.getResponse(), path)) { // 2) see if we can validate via /proc (or perhaps other platform specific means) if (validAttachViaSlashProc(programPID, path)) { // Linux or Solaris if (isSolaris()) { @@ -339,10 +337,7 @@ } setLoading(); } else if (isSharedLibrary && platform == PlatformTypes.PLATFORM_MACOSX) { - cb = new CommandBuffer(gdb); - gdb.info_share(cb); - cb.waitForCompletion(); - String addr = getMacDylibAddress(path, cb.toString()); + String addr = getMacDylibAddress(path, gdb.info_share(true).getResponse()); if (addr != null) { gdb.addSymbolFile(path, addr); setLoading(); @@ -360,10 +355,7 @@ } else { // 3) send an "info files" command to gdb. Its response should say what symbols // are read. - cb = new CommandBuffer(gdb); - gdb.info_files(cb); - cb.waitForCompletion(); - if (symbolsReadFromInfoFiles(cb.toString(), path)) { + if (symbolsReadFromInfoFiles(gdb.info_files().getResponse(), path)) { setLoading(); } else { final String msg = NbBundle.getMessage(GdbDebugger.class, "ERR_AttachValidationFailure"); // NOI18N @@ -432,12 +424,10 @@ gdb.exec_run(pae.getProfile().getArgsFlat() + inRedir); } catch (Exception ex) { ErrorManager.getDefault().notify(ex); - ((Session) lookupProvider.lookupFirst(null, Session.class)).kill(); + (lookupProvider.lookupFirst(null, Session.class)).kill(); } if (platform == PlatformTypes.PLATFORM_WINDOWS) { - CommandBuffer cb = new CommandBuffer(gdb); - gdb.info_threads(cb); // we get the PID from this... - String msg = cb.waitForCompletion(); + String msg = gdb.info_threads().getResponse(); // we get the PID from this... int pos1 = msg.indexOf("* 1 thread "); // NOI18N if (pos1 >= 0) { int pos2 = msg.indexOf('.', pos1); @@ -495,10 +485,6 @@ return platform; } - /*public InputOutput getIO() { - return iotab; - }*/ - public PathMap getPathMap() { return pathMap; } @@ -508,7 +494,7 @@ if (currentEngine == null) { return null; } - return (GdbDebugger) currentEngine.lookupFirst(null, GdbDebugger.class); + return currentEngine.lookupFirst(null, GdbDebugger.class); } private String getCompilerSetPath(ProjectActionEvent pae) { @@ -578,9 +564,7 @@ } catch (InterruptedException ex) { } } - CommandBuffer cb = new CommandBuffer(gdb); - gdb.info_threads(cb); - String results = cb.waitForCompletion(); + String results = gdb.info_threads().getResponse(); if (results.length() > 0) { List list = new ArrayList(); StringBuilder sb = new StringBuilder(); @@ -647,9 +631,7 @@ public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(PROP_STATE)) { if (evt.getNewValue().equals(STATE_LOADING)) { - CommandBuffer cb = new CommandBuffer(gdb); - shareToken = gdb.info_share(); - cb.setID(shareToken); + shareToken = gdb.info_share(false).getID(); } else if (evt.getNewValue().equals(STATE_READY)) { if (platform == PlatformTypes.PLATFORM_WINDOWS) { gdb.break_insert("dlopen"); // NOI18N @@ -665,7 +647,7 @@ } } else if (evt.getNewValue() == STATE_STOPPED) { updateLocalVariables(0); - GdbContext.getInstance().update(); + GdbContext.getInstance().gdbStep(); } else if (evt.getNewValue() == STATE_SILENT_STOP) { interrupt(); } else if (evt.getNewValue() == STATE_RUNNING && @@ -678,7 +660,7 @@ } else if (evt.getPropertyName().equals(PROP_CURRENT_THREAD)) { updateCurrentCallStack(); updateLocalVariables(0); - GdbContext.getInstance().update(); + GdbContext.getInstance().gdbStep(); } } @@ -706,7 +688,7 @@ if (platform == PlatformTypes.PLATFORM_WINDOWS) { return winpath(path1).equals(winpath(path2)); } - return path1.equals(path1); + return path1.equals(path2); } private String winpath(String path) { @@ -800,15 +782,10 @@ } private String getMacExePath() { - CommandBuffer cb = new CommandBuffer(gdb); - - gdb.info_files(cb); - cb.waitForCompletion(); - String info = cb.toString(); + String info = gdb.info_files().getResponse(); for (String line : info.split("\\\\n")) { // NOI18N if (line.contains("Symbols from ")) { // NOI18N - String ep = line.substring(15, line.length() - 3); - return ep; + return line.substring(15, line.length() - 3); } } return null; @@ -923,7 +900,7 @@ programPID = 0; removeRTCBreakpoint(); gdbEngineProvider.getDestructor().killEngine(); - GdbActionHandler gah = (GdbActionHandler) lookupProvider.lookupFirst(null, GdbActionHandler.class); + GdbActionHandler gah = lookupProvider.lookupFirst(null, GdbActionHandler.class); if (gah != null) { // gah is null if we attached (but we don't need it then) gah.executionFinished(0); } @@ -934,7 +911,7 @@ if (iotab != null) { iotab.getOut().close(); } - GdbContext.getInstance().invalidate(true); + GdbContext.getInstance().gdbExit(); GdbTimer.getTimer("Step").reset(); // NOI18N } } @@ -1100,7 +1077,7 @@ if (cb != null) { cb.done(); if (token == shareToken) { - shareTab = createShareTab(cb.toString()); + shareTab = createShareTab(cb.getResponse()); /*if (shareTab.containsKey("GdbHelper")) { // NOI18N ProjectActionEvent pae; pae = (ProjectActionEvent) lookupProvider.lookupFirst(null, ProjectActionEvent.class); @@ -1838,9 +1815,7 @@ private void checkSharedLibs() { RequestProcessor.getDefault().post(new Runnable() { public void run() { - CommandBuffer cb = new CommandBuffer(gdb); - gdb.info_share(cb); - String share = cb.waitForCompletion(); + String share = gdb.info_share(true).getResponse(); Map nuTab = createShareTab(share); if (nuTab.size() > shareTab.size()) { // dlopened a shared library @@ -1883,10 +1858,12 @@ */ private void stepOutOfDlopen() { String oldState = state; - state = STATE_SILENT_STOP; - CommandBuffer cb = new CommandBuffer(gdb); - cb.setID(gdb.stack_list_frames(cb)); - String msg = cb.waitForCompletion(); + setSilentStop(); + + String msg = gdb.stack_list_framesEx().getResponse(); + // response have the form ",stack=...", so we trim it + msg = msg.substring(7, msg.length() - 1); + int i = 0; boolean valid = true; boolean checkNextFrame = false; @@ -2206,23 +2183,32 @@ if (gdb == null) { return null; } - CommandBuffer cb = new CommandBuffer(gdb); - if (expression.indexOf('(') != -1) { + boolean suspendAll = expression.indexOf('(') != -1; + + if (suspendAll) { suspendBreakpointsAndSignals(); - gdb.data_evaluate_expression(cb, '"' + expression + '"'); // NOI18N + } + CommandBuffer cb = gdb.data_evaluate_expressionEx('"' + expression + '"'); // NOI18N + if (suspendAll) { restoreBreakpointsAndSignals(); - } else { - gdb.data_evaluate_expression(cb, '"' + expression + '"'); // NOI18N } - String response = cb.waitForCompletion(); - if (cb.getState() == CommandBuffer.STATE_ERROR) { - return NbBundle.getMessage(GdbDebugger.class, "ERR_WatchedFunctionAborted"); + + if (cb.isError()) { + String err = cb.getError(); + if (err.startsWith("\"The program being debugged was signaled while in a function called from GDB")) { // NOI18N + err = NbBundle.getMessage(GdbDebugger.class, "ERR_WatchedFunctionAborted"); } + return err; + } + + String response = cb.getResponse(); + // response have the form ",value=...", so we trim it + response = response.substring(7, response.length() - 1); + if (response.startsWith("@0x")) { // NOI18N - cb = new CommandBuffer(gdb); - gdb.print(cb, expression); - response = cb.waitForCompletion(); + cb = gdb.print(expression); + response = cb.getResponse(); if (response.length() > 0 && response.charAt(0) == '$') { int pos = response.indexOf('='); if (pos != -1 && (pos + 2) < response.length()) { @@ -2252,21 +2238,19 @@ assert !Thread.currentThread().getName().equals("GdbReaderRP"); // NOI18N if (state.equals(STATE_STOPPED)) { - CommandBuffer cb = new CommandBuffer(gdb); - gdb.data_evaluate_expression(cb, name); - String info = cb.waitForCompletion(); - if (info.length() == 0 || cb.getState() != CommandBuffer.STATE_OK) { - if (cb.getState() == CommandBuffer.STATE_ERROR) { - log.fine("GD.requestValue[" + cb.getID() + "]: Error [" + cb.getError() + "]"); // NOI18N + CommandBuffer cb = gdb.data_evaluate_expressionEx(name); + String info = cb.getResponse(); + if (info.length() == 0 || !cb.isOK()) { + if (cb.isError()) { + log.fine("GD.requestValue Error[" + cb + "]"); // NOI18N // TODO: do not enclose the message in >< throw new GdbErrorException('>' + cb.getError() + '<'); } else { - log.fine("GD.requestValue[" + cb.getID() + "]: Failure [" + // NOI18N - info.length() + ", " + cb.getState() + "]"); // NOI18N + log.fine("GD.requestValue Failure[" + cb + "]"); // NOI18N return ""; } } else { - return info; + return info.substring(7, info.length() - 1); } } else { return null; @@ -2277,17 +2261,14 @@ assert !Thread.currentThread().getName().equals("GdbReaderRP"); // NOI18N if (state.equals(STATE_STOPPED) && name != null && name.length() > 0) { - CommandBuffer cb = new CommandBuffer(gdb); - gdb.whatis(cb, name); - String info = cb.waitForCompletion(); - if (info.length() == 0 || cb.getState() != CommandBuffer.STATE_OK) { - if (cb.getState() == CommandBuffer.STATE_ERROR) { - log.fine("GD.requestWhatis[" + cb.getID() + "]: Error [" + cb.getError() + "]"); // NOI18N -// return '>' + cb.getError() + '<'; Show error in Value field... + CommandBuffer cb = gdb.whatis(name); + String info = cb.getResponse(); + if (info.length() == 0 || !cb.isOK()) { + if (cb.isError()) { + log.fine("GD.requestWhatis Error[" + cb + "]"); // NOI18N return ""; } else { - log.fine("GD.requestWhatis[" + cb.getID() + "]: Failure [" + // NOI18N - info.length() + ", " + cb.getState() + "]"); // NOI18N + log.fine("GD.requestWhatis Failure[" + cb + "]"); // NOI18N return ""; } } else { @@ -2302,21 +2283,18 @@ assert !Thread.currentThread().getName().equals("GdbReaderRP"); // NOI18N if (state.equals(STATE_STOPPED) && type != null && type.length() > 0) { - CommandBuffer cb = new CommandBuffer(gdb); - gdb.symbol_type(cb, type); - String info = cb.waitForCompletion(); - if (info.length() == 0 || cb.getState() != CommandBuffer.STATE_OK) { - if (cb.getState() == CommandBuffer.STATE_ERROR) { - log.fine("GD.requestSymbolType[" + cb.getID() + "]: Error [" + cb.getError() + "]"); // NOI18N -// return '>' + cb.getError() + '<'; Show error in Value field... + CommandBuffer cb = gdb.symbol_type(type); + String info = cb.getResponse(); + if (info.length() == 0 || !cb.isOK()) { + if (cb.isError()) { + log.fine("GD.requestSymbolType Error[" + cb + "]"); // NOI18N return ""; } else { - log.fine("GD.requestSymbolType[" + cb.getID() + "]: Failure [" + // NOI18N - info.length() + ", " + cb.getState() + "]. Returning original type"); // NOI18N + log.fine("GD.requestSymbolType Failure[" + cb + "]. Returning original type"); // NOI18N return type; } } else { - log.fine("GD.requestSymbolType[" + cb.getID() + "]: " + type + " --> [" + info + "]"); + log.fine("GD.requestSymbolType[" + cb + "]: " + type + " --> [" + info + "]"); return info.substring(7, info.length() - 2); } } else { @@ -2325,15 +2303,14 @@ } // TODO: unify with requestWhatis and requestValueEx - public String requestSymbolTypeFromName(String type) { + public String requestSymbolTypeFromName(String name) { assert !Thread.currentThread().getName().equals("GdbReaderRP"); // NOI18N - if (state.equals(STATE_STOPPED) && type != null && type.length() > 0) { - CommandBuffer cb = new CommandBuffer(gdb); - gdb.symbol_type(cb, type); - String info = cb.waitForCompletion(); - if (info.length() == 0 || cb.getState() != CommandBuffer.STATE_OK) { - if (cb.getState() == CommandBuffer.STATE_ERROR) { + if (state.equals(STATE_STOPPED) && name != null && name.length() > 0) { + CommandBuffer cb = gdb.symbol_type(name); + String info = cb.getResponse(); + if (info.length() == 0 || !cb.isOK()) { + if (cb.isError()) { log.fine("GD.requestSymbolTypeFromName Error[" + cb + "]"); // NOI18N return ""; } else { @@ -2341,7 +2318,7 @@ return ""; } } else { - log.fine("GD.requestSymbolTypeFromName[" + cb + "]: " + type + " --> [" + info + "]"); + log.fine("GD.requestSymbolTypeFromName[" + cb + "]: " + name + " --> [" + info + "]"); return info.substring(7, info.length() - 2); } } else { diff -r db1a3a2b82ea -r 4261df01ab8e cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/proxy/GdbProxy.java --- a/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/proxy/GdbProxy.java Thu Jan 29 15:55:27 2009 +0100 +++ b/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/proxy/GdbProxy.java Thu Feb 05 16:42:30 2009 +0300 @@ -52,6 +52,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -83,9 +84,9 @@ private final GdbDebugger debugger; private final GdbProxyEngine engine; private final GdbLogger gdbLogger; - private final Logger log = Logger.getLogger("gdb.gdbproxy.logger"); // NOI18N + private static final Logger log = Logger.getLogger("gdb.gdbproxy.logger"); // NOI18N - private final Map map = new HashMap(); + private final Map map = Collections.synchronizedMap(new HashMap()); /** * Creates a new instance of GdbProxy @@ -145,9 +146,9 @@ } /** Attach to a running program */ - public int target_attach(CommandBuffer cb, String pid) { + public CommandBuffer target_attach(String pid) { // return engine.sendCommand("-target-attach " + pid); // NOI18N - no implementaion - return engine.sendCommand(cb, "attach " + pid); // NOI18N + return engine.sendCommandEx("attach " + pid); // NOI18N } /** Detach from a running program */ @@ -166,8 +167,8 @@ } /** Ask gdb for its version */ - public int gdb_version() { - return engine.sendCommand("-gdb-version"); // NOI18N + public CommandBuffer gdb_version() { + return engine.sendCommandEx("-gdb-version"); // NOI18N } /** Ask gdb about a variable (currently used to find the current language) */ @@ -239,18 +240,14 @@ * Note: In gdb 6.5.50 the -threads-list-all-threads command isn't implemented so we * revert to the gdb command "info threads". */ - public int info_threads(CommandBuffer cb) { - return engine.sendCommand(cb, "info threads"); // NOI18N; + public CommandBuffer info_threads() { + return engine.sendCommandEx("info threads"); // NOI18N; } - public int info_threads() { - return engine.sendCommand("info threads"); // NOI18N; + public CommandBuffer info_files() { + return engine.sendCommandEx("info files"); // NOI18N } - public int info_files(CommandBuffer cb) { - return engine.sendCommand(cb, "info files"); // NOI18N - } - /** Set the current thread */ public int thread_select(String id) { return engine.sendCommand("-thread-select " + id); // NOI18N @@ -264,19 +261,15 @@ return engine.sendCommand("info proc"); // NOI18N } - public int info_share() { - return engine.sendCommand("info share"); // NOI18N + public CommandBuffer info_share(boolean waitForCompletion) { + return engine.sendCommandEx("info share", waitForCompletion); // NOI18N } - public int info_share(CommandBuffer cb) { - return engine.sendCommand(cb, "info share"); // NOI18N - } - /** * Use this to call _CndSigInit() to initialize signals in Cygwin processes. */ - public int data_evaluate_expression(CommandBuffer cb, String string) { - return engine.sendCommand(cb, "-data-evaluate-expression " + string); // NOI18N + public CommandBuffer data_evaluate_expressionEx(String string) { + return engine.sendCommandEx("-data-evaluate-expression " + string); // NOI18N } /** @@ -294,14 +287,14 @@ /** */ - public int data_list_register_values(CommandBuffer cb, String regIds) { - return engine.sendCommand(cb, "-data-list-register-values x " + regIds); // NOI18N + public void data_list_register_values(String regIds) { + engine.sendCommand("-data-list-register-values x " + regIds); // NOI18N } /** */ - public int data_list_changed_registers(CommandBuffer cb) { - return engine.sendCommand(cb, "-data-list-changed-registers"); // NOI18N + public void data_list_changed_registers() { + engine.sendCommand("-data-list-changed-registers"); // NOI18N } /* @@ -325,12 +318,12 @@ /* * @param addr - address to read from */ - public int data_read_memory(CommandBuffer cb, String addr, int lines) { - return engine.sendCommand(cb, "-data-read-memory " + addr + " x 1 " + lines + " " + MEMORY_READ_WIDTH + " ."); // NOI18N + public CommandBuffer data_read_memory(String addr, int lines) { + return engine.sendCommandEx("-data-read-memory " + addr + " x 1 " + lines + " " + MEMORY_READ_WIDTH + " ."); // NOI18N } - public int print(CommandBuffer cb, String expression) { - return engine.sendCommand(cb, "print " + expression); // NOI18N + public CommandBuffer print(String expression) { + return engine.sendCommandEx("print " + expression); // NOI18N } /** @@ -340,8 +333,8 @@ * * @return null if action is accepted, otherwise return error message */ - public int file_list_exec_source_file() { - return engine.sendCommand("-file-list-exec-source-file"); // NOI18N + public CommandBuffer file_list_exec_source_file() { + return engine.sendCommandEx("-file-list-exec-source-file"); // NOI18N } /** @@ -628,8 +621,8 @@ } /** Request a stack dump from gdb */ - public int stack_list_frames(CommandBuffer cb) { - return engine.sendCommand(cb, "-stack-list-frames "); // NOI18N + public CommandBuffer stack_list_framesEx() { + return engine.sendCommandEx("-stack-list-frames "); // NOI18N } public int gdb_set(String command, String value) { @@ -661,8 +654,8 @@ * Request the type of a symbol. As of gdb 6.6, this is unimplemented so we send a * non-mi command "ptype". We should only be called when symbol is in scope. */ - public int symbol_type(CommandBuffer cb, String symbol) { - return engine.sendCommand(cb, "ptype " + symbol); // NOI18N + public CommandBuffer symbol_type(String symbol) { + return engine.sendCommandEx("ptype " + symbol); // NOI18N } /** @@ -670,17 +663,16 @@ * so we send a gdb "whatis" command. This is different from -system-type in the case * of abstract data structures (structs and classes). Its the same for other types. */ - public int whatis(CommandBuffer cb, String symbol) { - return engine.sendCommand(cb, "whatis " + symbol); // NOI18N + public CommandBuffer whatis(String symbol) { + return engine.sendCommandEx("whatis " + symbol); // NOI18N } /** * Send "-gdb-exit" to the debugger * This command forces gdb to exit immediately. */ - public int gdb_exit() { - int token = engine.sendCommand("-gdb-exit "); // NOI18N + public void gdb_exit() { + engine.sendCommand("-gdb-exit "); // NOI18N engine.stopSending(); - return token; } } /* End of public class GdbProxy */ diff -r db1a3a2b82ea -r 4261df01ab8e cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/proxy/GdbProxyEngine.java --- a/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/proxy/GdbProxyEngine.java Thu Jan 29 15:55:27 2009 +0100 +++ b/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/proxy/GdbProxyEngine.java Thu Feb 05 16:42:30 2009 +0300 @@ -87,9 +87,12 @@ private boolean active; private InteractiveCommandProvider provider = null; private RequestProcessor.Task gdbReader = null; + + // This queue was created due to the issue 156138 + private final RequestProcessor sendQueue = new RequestProcessor("sendQueue"); // NOI18N private final boolean timerOn = Boolean.getBoolean("gdb.proxy.timer"); // NOI18N - private final Logger log = Logger.getLogger("gdb.gdbproxy.logger"); // NOI18N + private static final Logger log = Logger.getLogger("gdb.gdbproxy.logger"); // NOI18N /** * Create a gdb process @@ -221,7 +224,7 @@ } } - private int nextToken() { + private synchronized int nextToken() { return nextToken++; } @@ -230,29 +233,18 @@ * * @param cmd - a command to be sent to the debugger */ - public int sendCommand(String cmd) { - return sendCommand(null, cmd, false); + int sendCommand(String cmd) { + int token = nextToken(); + sendCommand(token, cmd); + return token; } - public int sendCommand(CommandBuffer cb, String cmd) { - return sendCommand(cb, cmd, false); - } - - public synchronized int sendCommand(CommandBuffer cb, String cmd, boolean consoleCommand) { + private synchronized void sendCommand(final int token, final String cmd) { if (active) { - String time; - if (timerOn) { - time = Long.toString(System.currentTimeMillis()) + ':'; - } else { - time = ""; - } - int token = nextToken(); - if (cb != null) { - cb.setID(token); - } - if (consoleCommand) { - token += 10000; - } else if (cmd.charAt(0) != '-') { + sendQueue.post(new Runnable() { + public void run() { + String time = CommandBuffer.getTimePrefix(timerOn); + if (cmd.charAt(0) != '-') { tokenList.add(new CommandInfo(token, cmd)); } StringBuilder fullcmd = new StringBuilder(String.valueOf(token)); @@ -260,16 +252,31 @@ fullcmd.append('\n'); gdbProxy.getLogger().logMessage(time + fullcmd.toString()); toGdb.print(fullcmd.toString()); - return token; - } else { - return -1; } + }); + } } - public int sendConsoleCommand(String cmd) { - return sendCommand(null, cmd, true); + CommandBuffer sendCommandEx(String cmd) { + return sendCommandEx(cmd, true); } + CommandBuffer sendCommandEx(String cmd, boolean waitForCompletion) { + int token = nextToken(); + CommandBuffer cb = new CommandBuffer(gdbProxy, token); + gdbProxy.putCB(token, cb); + sendCommand(token, cmd); + if (waitForCompletion) { + cb.waitForCompletion(); + } + return cb; + } + + void sendConsoleCommand(String cmd) { + int token = nextToken() + 10000; + sendCommand(token, cmd); + } + void stopSending() { active = false; } @@ -280,12 +287,7 @@ * @return null if the reply is not recognized, otherwise return reply */ private void processMessage(String msg) { - String time; - if (timerOn) { - time = Long.toString(System.currentTimeMillis()) + ':'; - } else { - time = ""; - } + String time = CommandBuffer.getTimePrefix(timerOn); if (msg.equals("(gdb)")) { // NOI18N return; // skip prompts } diff -r db1a3a2b82ea -r 4261df01ab8e cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/ui/MemoryViewTopComponent.java --- a/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/ui/MemoryViewTopComponent.java Thu Jan 29 15:55:27 2009 +0100 +++ b/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/ui/MemoryViewTopComponent.java Thu Feb 05 16:42:30 2009 +0300 @@ -40,10 +40,13 @@ package org.netbeans.modules.cnd.debugger.gdb.ui; import java.awt.Font; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.Serializable; import java.util.List; import java.util.Map; import java.util.logging.Logger; +import javax.swing.SwingUtilities; import org.netbeans.modules.cnd.debugger.gdb.GdbContext; import org.netbeans.modules.cnd.debugger.gdb.proxy.GdbProxy; import org.netbeans.modules.cnd.debugger.gdb.utils.CommandBuffer; @@ -52,12 +55,11 @@ import org.openide.util.NbBundle; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; -import org.openide.util.Utilities; /** * Top component which displays something. */ -final class MemoryViewTopComponent extends TopComponent { +final class MemoryViewTopComponent extends TopComponent implements PropertyChangeListener { private static MemoryViewTopComponent instance; /** path to the icon used by the component and its open action */ @@ -170,7 +172,6 @@ if (gdb == null) { return; } - CommandBuffer cb = new CommandBuffer(gdb); String addr = tfAddress.getText(); if (addr == null || addr.length() == 0) { return; @@ -188,13 +189,12 @@ if (len < 1) { return; } - gdb.data_read_memory(cb, addr, (len-1)/GdbProxy.MEMORY_READ_WIDTH+1); - String msg = cb.waitForCompletion(); - if (cb.getState() == CommandBuffer.STATE_ERROR) { + CommandBuffer cb = gdb.data_read_memory(addr, (len-1)/GdbProxy.MEMORY_READ_WIDTH+1); + if (cb.isError()) { taResult.setText(cb.getError()); } else { // parse output - Map res = GdbUtils.createMapFromString(msg); + Map res = GdbUtils.createMapFromString(cb.getResponse()); String mem = res.get("memory"); // NOI18N List lines = GdbUtils.createListOfValues(mem); StringBuilder text = new StringBuilder(); @@ -283,12 +283,28 @@ @Override public void componentOpened() { - // TODO add custom code on component opening + GdbContext.getInstance().addPropertyChangeListener(GdbContext.PROP_STEP, this); + GdbContext.getInstance().addPropertyChangeListener(GdbContext.PROP_EXIT, this); + update(); } @Override public void componentClosed() { - // TODO add custom code on component closing + GdbContext.getInstance().addPropertyChangeListener(GdbContext.PROP_STEP, this); + GdbContext.getInstance().addPropertyChangeListener(GdbContext.PROP_EXIT, this); + } + + @Override + protected void componentShowing() { + update(); + } + + public void propertyChange(PropertyChangeEvent evt) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + update(); + } + }); } /** replaces this in object stream */ diff -r db1a3a2b82ea -r 4261df01ab8e cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/utils/CommandBuffer.java --- a/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/utils/CommandBuffer.java Thu Jan 29 15:55:27 2009 +0100 +++ b/cnd.debugger.gdb/src/org/netbeans/modules/cnd/debugger/gdb/utils/CommandBuffer.java Thu Feb 05 16:42:30 2009 +0300 @@ -45,36 +45,32 @@ /** * This class is intended for gathering multiline responses to a single gdb command. - * + * * @author gordonp */ public class CommandBuffer { // Static parts - public static final int STATE_NONE = 0; - public static final int STATE_WAITING = 1; - public static final int STATE_COMMAND_TIMEDOUT = 2; - public static final int STATE_OK = 3; - public static final int STATE_ERROR = 4; - private final int WAIT_TIME = 30000; - private boolean timerOn = Boolean.getBoolean("gdb.proxy.timer"); // NOI18N + private static enum State { + NONE, WAITING, TIMEOUT, OK, ERROR; + } + + private static final int WAIT_TIME = 30000; + private static final boolean timerOn = Boolean.getBoolean("gdb.proxy.timer"); // NOI18N // Instance parts - private final StringBuilder buf; - private Integer token; - private String err; - private int state; + private final StringBuilder buf = new StringBuilder(); + private final int token; + private String err = null; + private State state = State.NONE; private final Object lock = new Object(); - protected static Logger log = Logger.getLogger("gdb.logger.cb"); // NOI18N + protected static final Logger log = Logger.getLogger("gdb.logger.cb"); // NOI18N private final GdbProxy gdb; - public CommandBuffer(GdbProxy gdb) { - buf = new StringBuilder(); - token = null; - state = STATE_NONE; - err = null; + public CommandBuffer(GdbProxy gdb, int token) { assert gdb != null; this.gdb = gdb; + this.token = token; } /** @@ -86,57 +82,46 @@ public String waitForCompletion() { assert !Thread.currentThread().getName().equals("GdbReaderRP"); synchronized (lock) { - if (state == STATE_NONE) { - state = STATE_WAITING; // this will change unless we timeout + if (state == State.NONE) { + state = State.WAITING; // this will change unless we timeout } try { long tstart = System.currentTimeMillis(); long tend = tstart; - while (state == STATE_WAITING) { + while (state == State.WAITING) { lock.wait(WAIT_TIME); tend = System.currentTimeMillis(); if ((tend - tstart) > WAIT_TIME) { - if (state == STATE_OK) { - log.finest("CB.postAndWait[" + token + "]: Timed out after Done [" + toString() + "]"); + if (state == State.OK) { + log.finest("CB.postAndWait[" + token + "]: Timed out after Done [" + getResponse() + "]"); } else { - state = STATE_COMMAND_TIMEDOUT; + state = State.TIMEOUT; } } } - if (state == STATE_COMMAND_TIMEDOUT) { + if (state == State.TIMEOUT) { log.warning("CB.postAndWait[" + token + "]: Timeout at " + tend + " on " + GdbUtils.threadId()); } else if (log.isLoggable(Level.FINE)) { - if (state == STATE_ERROR && + if (state == State.ERROR && !Thread.currentThread().getName().equals("ToolTip-Evaluator")) { // NOI18N log.fine("CB.postAndWait[" + token + "]: Error wait of " + (tend - tstart) + " ms on " + GdbUtils.threadId()); - } else if (state == STATE_OK) { + } else if (state == State.OK) { log.fine("CB.postAndWait[" + token + "]: OK wait of " + (tend - tstart) + " ms on " + GdbUtils.threadId()); } } + return getResponse(); + } catch (InterruptedException ex) { + return ""; + } finally { gdb.removeCB(token); - return toString(); - } catch (InterruptedException ex) { - gdb.removeCB(token); - return ""; } } } - - public Integer getID() { + + public int getID() { return token; - } - - public void setID(int token) { - synchronized (lock) { - this.token = token; - gdb.putCB(this.token, this); - } - } - - public int getState() { - return state; } public void append(String line) { @@ -144,47 +129,63 @@ } public void done() { - String time; - if (timerOn && log.isLoggable(Level.FINEST)) { - time = Long.toString(System.currentTimeMillis()) + ':'; - } else { - time = ""; - } + String time = getTimePrefix(timerOn && log.isLoggable(Level.FINEST)); synchronized (lock) { - state = STATE_OK; + state = State.OK; + log.finest("CB.done[" + time + token + "]: Released lock on " + GdbUtils.threadId()); + gdb.removeCB(token); lock.notifyAll(); - log.finest("CB.done[" + time + token + "]: Released lock on " + GdbUtils.threadId()); } } public void error(String msg) { - String time; - if (timerOn && log.isLoggable(Level.FINEST)) { - time = Long.toString(System.currentTimeMillis()) + ':'; - } else { - time = ""; - } + String time = getTimePrefix(timerOn && log.isLoggable(Level.FINEST)); synchronized (lock) { err = msg; - state = STATE_ERROR; + state = State.ERROR; log.finest("CB.error[" + time + token + "]: Releasing lock on " + GdbUtils.threadId()); + gdb.removeCB(token); lock.notifyAll(); } } public String getError() { - if (state == STATE_ERROR && err != null) { + if (state == State.ERROR && err != null) { return err; } return null; } - public boolean timedOut() { - return state == STATE_COMMAND_TIMEDOUT; + public boolean isTimedOut() { + return state == State.TIMEOUT; + } + + public boolean isError() { + return state == State.ERROR; + } + + public boolean isOK() { + return state == State.OK; + } + + public String getResponse() { + return buf.toString(); } @Override public String toString() { - return buf.toString(); + return "CommandBuffer(id=" + token + ", text=" + getResponse() + ", state=" + state + ", error=" + err + ")"; // NOI18N + } + + /** + * @param show - if true - return empty string + * @return + */ + public static String getTimePrefix(boolean show) { + if (show) { + return Long.toString(System.currentTimeMillis()) + ':'; + } else { + return ""; + } } }