diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOffer.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOffer.java index 7f78c98fac..0e72a46596 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOffer.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOffer.java @@ -591,8 +591,11 @@ public abstract class AbstractDebuggerProgramLaunchOffer implements DebuggerProg monitor.incrementProgress(1); monitor.setMessage("Launching"); locals.futureTarget = listenForTarget(l.getModel()); + if (prompt) { + return launch(l, true, configurator); + } return AsyncTimer.DEFAULT_TIMER.mark() - .timeOut(launch(l, prompt, configurator), getTimeoutMillis(), + .timeOut(launch(l, false, configurator), getTimeoutMillis(), () -> onTimedOutLaunch(monitor)); }).thenCompose(__ -> { checkCancelled(monitor); diff --git a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AgentWindow.java b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AgentWindow.java index e35f283c5d..78207f1d58 100644 --- a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AgentWindow.java +++ b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AgentWindow.java @@ -21,6 +21,7 @@ import java.awt.event.WindowListener; import java.net.SocketAddress; import javax.swing.*; +import javax.swing.text.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.Appender; @@ -36,8 +37,8 @@ import log.LogPanelAppender; public class AgentWindow extends JFrame implements WindowListener, LogListener { public static final int MAX_LOG_CHARS = 100000; - protected final JTextArea logArea = new JTextArea(); - protected final JScrollPane logScroll = new JScrollPane(logArea); + protected final JTextPane logPane = new JTextPane(); + protected final JScrollPane logScroll = new JScrollPane(logPane); public AgentWindow(String title, SocketAddress localAddress) { super(title); @@ -45,10 +46,12 @@ public class AgentWindow extends JFrame implements WindowListener, LogListener { addWindowListener(this); add(new JLabel("This agent is listening at " + localAddress + ". Close this window to terminate it."), BorderLayout.NORTH); - logArea.setEditable(false); - logArea.setFont(Font.decode(Font.MONOSPACED)); - logArea.setAutoscrolls(true); + logPane.setEditable(false); + logPane.setFont(Font.decode(Font.MONOSPACED)); + logPane.setAutoscrolls(true); logScroll.setAutoscrolls(true); + DefaultCaret caret = (DefaultCaret) logPane.getCaret(); + caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); add(logScroll); setMinimumSize(new Dimension(400, 300)); setVisible(true); @@ -70,13 +73,21 @@ public class AgentWindow extends JFrame implements WindowListener, LogListener { @Override public void messageLogged(String message, boolean isError) { - String fMessage = isError ? "" + message + "" : message; Swing.runIfSwingOrRunLater(() -> { - String allText = logArea.getText() + fMessage + "\n"; - logArea.setText( - allText.substring(Math.max(0, allText.length() - MAX_LOG_CHARS), allText.length())); - JScrollBar vScroll = logScroll.getVerticalScrollBar(); - vScroll.setValue(vScroll.getMaximum()); + MutableAttributeSet attributes = new SimpleAttributeSet(); + if (isError) { + StyleConstants.setForeground(attributes, Color.RED); + } + Document document = logPane.getStyledDocument(); + try { + document.insertString(document.getLength(), message + "\n", attributes); + if (document.getLength() > MAX_LOG_CHARS) { + document.remove(0, document.getLength() - MAX_LOG_CHARS); + } + } + catch (BadLocationException e) { + throw new AssertionError(e); + } }); }