Skip to content

Commit dd9f39d

Browse files
fix: write openocd debug output to a file
1 parent 13f90b1 commit dd9f39d

File tree

3 files changed

+83
-6
lines changed

3 files changed

+83
-6
lines changed

bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/process/IdfRuntimeProcess.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
import java.util.Map;
1111

1212
import org.eclipse.cdt.dsf.gdb.launching.GDBProcess;
13+
import org.eclipse.core.runtime.CoreException;
1314
import org.eclipse.debug.core.DebugPlugin;
1415
import org.eclipse.debug.core.ILaunch;
1516
import org.eclipse.debug.core.model.IStreamsProxy;
16-
import org.eclipse.debug.core.model.RuntimeProcess;
1717
import org.eclipse.debug.internal.core.NullStreamsProxy;
18+
import org.eclipse.debug.ui.IDebugUIConstants;
1819

19-
import com.espressif.idf.core.util.StringUtil;
2020
import com.espressif.idf.debug.gdbjtag.openocd.dsf.process.monitors.StreamsProxy;
2121

2222
/**
@@ -60,7 +60,32 @@ protected IStreamsProxy createStreamsProxy()
6060
DebugPlugin.log(e);
6161
}
6262
}
63-
StreamsProxy streamsProxy = new StreamsProxy(this, getSystemProcess(), charset, getLabel());
63+
// Use Eclipse Common tab attribute for output file and append
64+
final String outputFileName = getAttributeSafe(getLaunch().getLaunchConfiguration()::getAttribute,
65+
IDebugUIConstants.ATTR_CAPTURE_IN_FILE, "");
66+
67+
final boolean append = getAttributeSafe(getLaunch().getLaunchConfiguration()::getAttribute,
68+
IDebugUIConstants.ATTR_APPEND_TO_FILE, false);
69+
StreamsProxy streamsProxy = new StreamsProxy(this, getSystemProcess(), charset, getLabel(), outputFileName, append);
6470
return streamsProxy;
6571
}
72+
73+
private <T> T getAttributeSafe(AttributeGetter<T> getter, String attribute, T defaultValue)
74+
{
75+
try
76+
{
77+
return getter.get(attribute, defaultValue);
78+
}
79+
catch (CoreException e)
80+
{
81+
DebugPlugin.log(e);
82+
return defaultValue;
83+
}
84+
}
85+
86+
@FunctionalInterface
87+
interface AttributeGetter<T>
88+
{
89+
T get(String attribute, T defaultValue) throws CoreException;
90+
}
6691
}

bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/process/StreamListener.java

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66

77
import java.io.BufferedReader;
88
import java.io.File;
9+
import java.io.FileWriter;
910
import java.io.IOException;
11+
import java.io.PrintWriter;
1012
import java.io.StringReader;
1113
import java.nio.charset.Charset;
1214
import java.util.List;
1315

16+
import org.eclipse.core.variables.VariablesPlugin;
1417
import org.eclipse.debug.core.IStreamListener;
1518
import org.eclipse.debug.core.model.IFlushableStreamMonitor;
1619
import org.eclipse.debug.core.model.IProcess;
@@ -50,11 +53,24 @@ public class StreamListener implements IStreamListener
5053
private boolean fStreamClosed = false;
5154
private List<ReHintPair> reHintsList;
5255

56+
private String outputFile;
57+
private PrintWriter fileWriter;
58+
5359
public StreamListener(IProcess iProcess, IStreamMonitor errorStreamMonitor, IStreamMonitor outputStreamMonitor,
54-
Charset charset)
60+
Charset charset, String outputFile, boolean append)
5561
{
5662
fErrorStreamMonitor = errorStreamMonitor;
5763
fOutputStreamMonitor = outputStreamMonitor;
64+
this.outputFile = outputFile;
65+
String resolvedOutputFile = resolveOutputFilePath(outputFile);
66+
if (resolvedOutputFile != null && !resolvedOutputFile.isEmpty()) {
67+
try {
68+
fileWriter = new PrintWriter(new FileWriter(resolvedOutputFile, append), true);
69+
} catch (IOException e) {
70+
Logger.log(e);
71+
fileWriter = null;
72+
}
73+
}
5874

5975
idfProcessConsole = IdfProcessConsoleFactory.showAndActivateConsole(charset);
6076
// Clear the console only at the beginning, when OpenOCD starts
@@ -112,6 +128,9 @@ public void streamAppended(String text, IStreamMonitor monitor)
112128
{
113129
while ((line = bufferedReader.readLine()) != null)
114130
{
131+
if (outputFile != null && !outputFile.isEmpty() && fileWriter != null) {
132+
fileWriter.println(line);
133+
}
115134

116135
if (line.startsWith("Error:") && fConsoleErrorOutputStream != null) //$NON-NLS-1$
117136
{
@@ -186,5 +205,38 @@ public void dispose()
186205
}
187206
fErrorStreamMonitor = null;
188207
fOutputStreamMonitor = null;
208+
if (fileWriter != null) {
209+
fileWriter.close();
210+
fileWriter = null;
211+
}
212+
}
213+
214+
/**
215+
* Resolves the output file path, expands variables, handles directory case, and ensures file/parent directories exist.
216+
*/
217+
private static String resolveOutputFilePath(String outputFile) {
218+
if (outputFile == null || outputFile.isEmpty()) {
219+
return null;
220+
}
221+
try {
222+
// Expand Eclipse variables (e.g., ${workspace_loc:...})
223+
String expanded = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(outputFile);
224+
File file = new File(expanded);
225+
if (file.isDirectory() || (!file.exists() && expanded.endsWith(File.separator))) {
226+
// If it's a directory or ends with a separator, append openocd.log
227+
file = new File(file, "openocd.log");
228+
}
229+
File parent = file.getParentFile();
230+
if (parent != null && !parent.exists()) {
231+
parent.mkdirs();
232+
}
233+
if (!file.exists()) {
234+
file.createNewFile();
235+
}
236+
return file.getAbsolutePath();
237+
} catch (Exception e) {
238+
Logger.log(e);
239+
return null;
240+
}
189241
}
190242
}

bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/process/monitors/StreamsProxy.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ public class StreamsProxy implements IBinaryStreamsProxy {
6262
* @param charset the process's charset or <code>null</code> if default
6363
* @param processLabel The name for the process label
6464
*/
65-
public StreamsProxy(IProcess iProcess, Process process, Charset charset, String processLabel) {
65+
public StreamsProxy(IProcess iProcess, Process process, Charset charset, String processLabel, String outputFile, boolean append) {
6666
if (process == null) {
6767
return;
6868
}
6969
fOutputMonitor = new CustomOutputStreamMonitor(process.getInputStream(), charset);
7070
fErrorMonitor = new CustomOutputStreamMonitor(process.getErrorStream(), charset);
7171
// Our own addition to make sure that we utilize only one listener for all streams
72-
StreamListener streamListener = new StreamListener(iProcess, fErrorMonitor, fOutputMonitor, charset);
72+
StreamListener streamListener = new StreamListener(iProcess, fErrorMonitor, fOutputMonitor, charset, outputFile, append);
7373
fOutputMonitor.addListener(streamListener);
7474
fErrorMonitor.addListener(streamListener);
7575
fInputMonitor = new InputStreamMonitor(process.getOutputStream(), charset);

0 commit comments

Comments
 (0)