Skip to content

Commit

Permalink
Support of setting the current working directory and environment vari…
Browse files Browse the repository at this point in the history
…ables for Java8+ VSCode projects.
  • Loading branch information
entlicher committed Sep 24, 2021
1 parent e1ca394 commit e818ef7
Show file tree
Hide file tree
Showing 43 changed files with 1,242 additions and 136 deletions.
11 changes: 10 additions & 1 deletion cpplite/cpplite.debugger/nbproject/project.xml
Expand Up @@ -60,13 +60,22 @@
<specification-version>1.59</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.modules.extexecution.base</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>2</release-version>
<specification-version>1.20</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.modules.nativeimage.api</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>0</release-version>
<specification-version>0.4</specification-version>
<specification-version>0.5</specification-version>
</run-dependency>
</dependency>
<dependency>
Expand Down
Expand Up @@ -50,6 +50,7 @@
import org.netbeans.api.debugger.DebuggerInfo;
import org.netbeans.api.debugger.DebuggerManager;
import org.netbeans.api.debugger.DebuggerManagerAdapter;
import org.netbeans.api.extexecution.base.ExplicitProcessParameters;
import org.netbeans.modules.cnd.debugger.gdb2.mi.MICommand;
import org.netbeans.modules.cnd.debugger.gdb2.mi.MICommandInjector;
import org.netbeans.modules.cnd.debugger.gdb2.mi.MIConst;
Expand All @@ -75,6 +76,7 @@
import org.openide.text.Annotatable;
import org.openide.text.Line;
import org.openide.util.Exceptions;
import org.openide.util.Lookup;
import org.openide.util.Pair;
import org.openide.util.RequestProcessor;

Expand Down Expand Up @@ -811,15 +813,20 @@ public Object[] getServices () {
CPPLiteDebugger debugger = es[0].lookupFirst(null, CPPLiteDebugger.class);
List<String> executable = new ArrayList<>();
executable.add(configuration.getDebugger());
executable.add("--interpreter=mi");
executable.add("--tty=" + pty.getSlaveName());
executable.add("--interpreter=mi"); // NOI18N
executable.add("--tty=" + pty.getSlaveName()); // NOI18N
if (configuration.isAttach()) {
executable.add("-p");
executable.add("-p"); // NOI18N
executable.add(Long.toString(configuration.getAttachProcessId()));
}
if (configuration.getExecutable().size() > 1) {
executable.add("--args"); // NOI18N
}
executable.addAll(configuration.getExecutable());
Process debuggee = new ProcessBuilder(executable).directory(configuration.getDirectory()).start();
new RequestProcessor(configuration.getDisplayName() + " (pty deallocator)").post(() -> {
ProcessBuilder processBuilder = new ProcessBuilder(executable);
setParameters(processBuilder, configuration);
Process debuggee = processBuilder.start();
new RequestProcessor(configuration.getDisplayName() + " (pty deallocator)").post(() -> { // NOI18N
try {
while (debuggee.isAlive()) {
try {
Expand Down Expand Up @@ -878,6 +885,25 @@ public void destroy() {
};
}

private static void setParameters(ProcessBuilder processBuilder, CPPLiteDebuggerConfig configuration) {
ExplicitProcessParameters processParameters = configuration.getProcessParameters();
if (processParameters.getWorkingDirectory() != null) {
processBuilder.directory(processParameters.getWorkingDirectory());
}
if (!processParameters.getEnvironmentVariables().isEmpty()) {
Map<String, String> environment = processBuilder.environment();
for (Map.Entry<String, String> entry : processParameters.getEnvironmentVariables().entrySet()) {
String env = entry.getKey();
String val = entry.getValue();
if (val != null) {
environment.put(env, val);
} else {
environment.remove(env);
}
}
}
}

private class BreakpointsHandler extends DebuggerManagerAdapter implements PropertyChangeListener {

private final Map<String, CPPLiteBreakpoint> breakpointsById = new ConcurrentHashMap<>();
Expand Down
Expand Up @@ -19,10 +19,12 @@

package org.netbeans.modules.cpplite.debugger;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.netbeans.api.annotations.common.NullAllowed;
import org.netbeans.api.extexecution.base.ExplicitProcessParameters;
import org.openide.util.Exceptions;

/**
*
Expand All @@ -31,16 +33,33 @@
public final class CPPLiteDebuggerConfig {

private final List<String> executable;
private final File directory;
private final ExplicitProcessParameters processParameters;
@NullAllowed
private final Long processId;
private final String debugger;

public CPPLiteDebuggerConfig(List<String> executable, File directory, @NullAllowed Long processId, String debugger) {
this.executable = executable;
this.directory = directory;
public CPPLiteDebuggerConfig(List<String> executable, ExplicitProcessParameters processParameters, @NullAllowed Long processId, String debugger) {
this.processParameters = processParameters;
this.processId = processId;
this.debugger = debugger;
if (processParameters.isArgReplacement()) {
this.executable = new ArrayList<>();
this.executable.add(executable.get(0));
if (processParameters.getArguments() != null) {
this.executable.addAll(processParameters.getArguments());
}
} else {
if (processParameters.getArguments() != null) {
this.executable = new ArrayList<>();
this.executable.addAll(executable);
this.executable.addAll(processParameters.getArguments());
} else {
this.executable = executable;
}
}
if (processParameters.getLauncherArguments() != null) {
Exceptions.printStackTrace(new IllegalStateException("Launcher arguments " + processParameters.getLauncherArguments() + " can not be accepted by CPPLite debugger"));
}
}

public String getDisplayName() {
Expand All @@ -55,10 +74,10 @@ public List<String> getExecutable() {
}

/**
* Get the directory in which the executable command is to be launched.
* Get the parameters which the executable command is to be launched with.
*/
public File getDirectory() {
return directory;
public ExplicitProcessParameters getProcessParameters() {
return processParameters;
}

/**
Expand Down
Expand Up @@ -21,6 +21,7 @@
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.netbeans.api.extexecution.base.ExplicitProcessParameters;

import org.netbeans.modules.cpplite.debugger.CPPLiteDebugger;
import org.netbeans.modules.cpplite.debugger.CPPLiteDebuggerConfig;
Expand All @@ -38,8 +39,9 @@ public static Process startInDebugger(List<String> command) throws IOException {

public static Process startInDebugger(List<String> command, File directory) throws IOException {
CPPLiteDebugger[] debugger = new CPPLiteDebugger[] { null };
ExplicitProcessParameters processParameters = ExplicitProcessParameters.builder().workingDirectory(directory).build();
Process engineProcess = CPPLiteDebugger.startDebugging(
new CPPLiteDebuggerConfig(command, directory, null, "gdb"),
new CPPLiteDebuggerConfig(command, processParameters, null, "gdb"),
engine -> {
debugger[0] = engine.lookupFirst(null, CPPLiteDebugger.class);
});
Expand Down
Expand Up @@ -31,6 +31,7 @@
import org.netbeans.api.debugger.DebuggerEngine;
import org.netbeans.api.extexecution.ExecutionDescriptor;
import org.netbeans.api.extexecution.ExecutionService;
import org.netbeans.api.extexecution.base.ExplicitProcessParameters;
import org.netbeans.modules.cpplite.debugger.CPPFrame;
import org.netbeans.modules.cpplite.debugger.CPPLiteDebugger;
import org.netbeans.modules.cpplite.debugger.CPPLiteDebuggerConfig;
Expand All @@ -42,12 +43,14 @@
import org.netbeans.modules.nativeimage.api.debug.NIFrame;
import org.netbeans.modules.nativeimage.api.debug.NILineBreakpointDescriptor;
import org.netbeans.modules.nativeimage.api.debug.NIVariable;
import org.netbeans.modules.nativeimage.api.debug.StartDebugParameters;
import org.netbeans.modules.nativeimage.spi.debug.NIDebuggerProvider;
import org.netbeans.modules.nativeimage.spi.debug.filters.FrameDisplayer;

import org.openide.LifecycleManager;
import org.openide.util.RequestProcessor;
import org.netbeans.modules.nativeimage.spi.debug.filters.VariableDisplayer;
import org.openide.util.Lookup;

/**
*
Expand Down Expand Up @@ -85,10 +88,20 @@ public void setVariablesDisplayer(VariableDisplayer variablesDisplayer) {
}

@Override
public CompletableFuture<Void> start(List<String> command, File workingDirectory, String miDebugger, String displayName, ExecutionDescriptor executionDescriptor, Consumer<DebuggerEngine> startedEngine) {
public CompletableFuture<Void> start(StartDebugParameters debugParameters, Consumer<DebuggerEngine> startedEngine) {
if (debugger != null) {
throw new IllegalStateException("Debugger has started already.");
}
List<String> command = debugParameters.getCommand();
String miDebugger = debugParameters.getDebugger();
String displayName = debugParameters.getDisplayName();
ExecutionDescriptor executionDescriptor = debugParameters.getExecutionDescriptor();
Lookup contextLookup = debugParameters.getContextLookup();
ExplicitProcessParameters explicitParameters = contextLookup != null ? ExplicitProcessParameters.buildExplicitParameters(contextLookup) : null;
if (explicitParameters == null) {
explicitParameters = ExplicitProcessParameters.builder().workingDirectory(debugParameters.getWorkingDirectory()).build();
}
final ExplicitProcessParameters processParameters = explicitParameters;
if (executionDescriptor == null) {
executionDescriptor = new ExecutionDescriptor()
.showProgress(true)
Expand All @@ -104,7 +117,7 @@ public CompletableFuture<Void> start(List<String> command, File workingDirectory
try {
LifecycleManager.getDefault().saveAll();
engineProcess = CPPLiteDebugger.startDebugging(
new CPPLiteDebuggerConfig(command, workingDirectory, null, miDebugger),
new CPPLiteDebuggerConfig(command, processParameters, null, miDebugger),
engine -> {
debugger[0] = engine.lookupFirst(null, CPPLiteDebugger.class);
this.debugger = debugger[0];
Expand Down Expand Up @@ -147,10 +160,11 @@ public CompletableFuture<Void> attach(String executablePath, long processId, Str
if (debugger != null) {
throw new IllegalStateException("Debugger has started already.");
}
ExplicitProcessParameters processParameters = ExplicitProcessParameters.builder().workingDirectory(new File(System.getProperty("user.dir", ""))).build(); // NOI18N
CompletableFuture<Void> completed = new CompletableFuture<>();
try {
CPPLiteDebugger.startDebugging(
new CPPLiteDebuggerConfig(Collections.singletonList(executablePath), new File(System.getProperty("user.dir")), processId, miDebugger),
new CPPLiteDebuggerConfig(Collections.singletonList(executablePath), processParameters, processId, miDebugger),
engine -> {
CPPLiteDebugger debugger = engine.lookupFirst(null, CPPLiteDebugger.class);
this.debugger = debugger;
Expand Down
Expand Up @@ -18,21 +18,34 @@
*/
package org.netbeans.modules.cpplite.debugger;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import junit.framework.Test;

import org.netbeans.api.debugger.DebuggerEngine;
import org.netbeans.api.extexecution.base.ExplicitProcessParameters;
import org.netbeans.junit.NbModuleSuite;
import org.netbeans.junit.NbTestCase;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;

public abstract class AbstractDebugTest extends NbTestCase {

protected DebuggerEngine engine;
protected CPPLiteDebugger debugger;
protected Process process;
protected StringBuffer stdOut;
protected StringBuffer stdErr;

private final int[] suspendCount = new int[]{0};
private final int[] resumeCount = new int[]{0};
Expand All @@ -41,6 +54,14 @@ protected AbstractDebugTest(String s) {
super(s);
}

protected final static void createSourceFile(String fileName, File wd, String content) throws IOException {
FileObject source = FileUtil.createData(FileUtil.toFileObject(wd), "main.cpp");
try (OutputStream os = source.getOutputStream();
Writer w = new OutputStreamWriter(os)) {
w.append(content);
}
}

protected final static void compileC(String name, File wd) throws IOException, InterruptedException {
Process compile = new ProcessBuilder("gcc", "-o", name, "-g", name + ".c").directory(wd).start();
assertEquals(0, compile.waitFor());
Expand All @@ -52,9 +73,20 @@ protected final static void compileCPP(String name, File wd) throws IOException,
}

protected final void startDebugging(String name, File wd) throws IOException {
ExplicitProcessParameters processParameters = ExplicitProcessParameters.builder().workingDirectory(wd).build();
startDebugging(name, wd, processParameters);
}

protected final void startDebugging(String name, File wd, ExplicitProcessParameters processParameters) throws IOException {
startDebugging(Arrays.asList(new File(wd, name).getAbsolutePath()), processParameters);
}

protected final void startDebugging(List<String> executable, ExplicitProcessParameters processParameters) throws IOException {
this.process = CPPLiteDebugger.startDebugging(
new CPPLiteDebuggerConfig(Arrays.asList(new File(wd, name).getAbsolutePath()), wd, null, "gdb"),
new CPPLiteDebuggerConfig(executable, processParameters, null, "gdb"),
engine -> this.engine = engine);
stdOut = outputFrom(process.getInputStream());
stdErr = outputFrom(process.getErrorStream());
debugger = engine.lookupFirst(null, CPPLiteDebugger.class);
debugger.addStateListener(new CPPLiteDebugger.StateListener() {
@Override
Expand Down Expand Up @@ -120,4 +152,23 @@ protected final void assertStoppedAt(URI file, int line) {
public static Test suite() {
return NbModuleSuite.emptyConfiguration().gui(false).suite();
}

private static StringBuffer outputFrom(InputStream inputStream) {
StringBuffer buffer = new StringBuffer();
new Thread("Process output") {
@Override
public void run() {
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = br.readLine()) != null) {
buffer.append(line);
buffer.append('\n');
}
} catch (IOException ex) {
buffer.append(ex);
}
}
}.start();
return buffer;
}
}

0 comments on commit e818ef7

Please sign in to comment.