Programmatically start debugger

Hi everyone,

I'm developing an IntelliJ IDEA Plugin in which at some point I need to start the debugger. The scenario is as follows:

  1. Programmatically set a breakpoint (at a specific line of a specific file).
  2. Show the run/debug configurations to the user (and let him select one).
  3. Programmatically execute the selected run/debug configuration.

 

This lets me print the run/debug configurations of the project to the console:

final Project project = event.getProject();
final RunManager runManager = RunManager.getInstance(project);
List<RunConfiguration> runConfigurations = runManager.getAllConfigurationsList();

for (RunConfiguration runConfiguration : runConfigurations) {
System.out.println(runConfiguration.getName());
}

 

I already read the following blog post to run the configuration but unfortunately, it didn't help:

https://intellij-support.jetbrains.com/hc/en-us/community/posts/207137575-Is-there-any-way-to-trigger-start-Run-Debug-configuration-programmatically-?input_string=Programmatically%20start

 

Thanks for your help in advance,

Alex

 

4 comments
Comment actions Permalink

To add a breakpoint you can use XBreakpointManager.addLineBreakpoint,

to debug a configuration - ExecutionEnvironmentBuilder.create(project, DefaultDebugExecutor.getDebugExecutorInstance(), runConf).buildAndExecute()

1
Comment actions Permalink

Hi Egor,

thanks for your reply!

I'm able to execute the run configuration but still struggling with setting a breakpoint.

The following code snippet shows what I'm working on (and failing). I assume there needs to be a much simpler way:

private void makeBreakpoint(Project project) {
class MyBreakpointProperties extends XBreakpointProperties<MyBreakpointProperties> {
public String myOption;

public MyBreakpointProperties() {}

@Override
public MyBreakpointProperties getState() {
return this;
}

@Override
public void loadState(final MyBreakpointProperties state) {
myOption = state.myOption;
}
}

class MyLineBreakpointType extends XLineBreakpointType<MyBreakpointProperties> {
public MyLineBreakpointType() {
super("testId", "testTitle");
}

@Override
public MyBreakpointProperties createBreakpointProperties(VirtualFile file, final int line) {
return null;
}

@Override
public MyBreakpointProperties createProperties() {
return new MyBreakpointProperties();
}
}

XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
final String fileUrl = "C:\\Users\\alex\\IdeaProjects\\untitled\\src\\Main.java";
final int line = 3;

final MyLineBreakpointType MY_LINE_BREAKPOINT_TYPE = new MyLineBreakpointType();
final MyBreakpointProperties MY_LINE_BREAKPOINT_PROPERTIES = new MyBreakpointProperties();
breakpointManager.addLineBreakpoint(MY_LINE_BREAKPOINT_TYPE, fileUrl, line, MY_LINE_BREAKPOINT_PROPERTIES);
}

 

Cheers,

Alex

0
Comment actions Permalink

To toggle a line breakpoint you can use XDebuggerUtil.toggleLineBreakpoint

1
Comment actions Permalink

Thanks for your support Egor.

Here is the solution that worked for me, if someone else tries to implement something similar:

1. Programmatically set a breakpoint (at a specific line of a specific file).

// add a new line break point to the specified line of the given file and activate it
private void addLineBreakpoint(final Project project, final String fileUrl, final int line) {
class MyBreakpointProperties extends XBreakpointProperties<MyBreakpointProperties> {
public String myOption;

public MyBreakpointProperties() {}

@Override
public MyBreakpointProperties getState() {
return this;
}

@Override
public void loadState(final MyBreakpointProperties state) {
myOption = state.myOption;
}
}

class MyLineBreakpointType extends XLineBreakpointType<MyBreakpointProperties> {
public MyLineBreakpointType() {
super("testId", "testTitle");
}

@Override
public MyBreakpointProperties createBreakpointProperties(VirtualFile file, final int line) {
return null;
}

@Override
public MyBreakpointProperties createProperties() {
return new MyBreakpointProperties();
}
}

final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
final MyLineBreakpointType MY_LINE_BREAKPOINT_TYPE = new MyLineBreakpointType();
final MyBreakpointProperties MY_LINE_BREAKPOINT_PROPERTIES = new MyBreakpointProperties();

// add new line break point
Runnable runnable = () -> breakpointManager.addLineBreakpoint(
MY_LINE_BREAKPOINT_TYPE,
fileUrl,
line,
MY_LINE_BREAKPOINT_PROPERTIES
);
WriteCommandAction.runWriteCommandAction(project, runnable);

// toggle breakpoint to activate
VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(new File(fileUrl));
XDebuggerUtil.getInstance().toggleLineBreakpoint(project, virtualFile, line);
}

2. Show the run/debug configurations to the user (and let him select one).

// print all run configurations to the console
private List<RunConfiguration> printRunConfigurations(final Project project) {
final RunManager runManager = RunManager.getInstance(project);
final List<RunConfiguration> runConfigurations = runManager.getAllConfigurationsList();

for (RunConfiguration runConfiguration : runConfigurations) {
System.out.println(runConfiguration.getName());
}

return runConfigurations;
}

3. Programmatically execute the selected run/debug configuration.

// start the run configuration in debugging mode
private void startDebugger(Project project, RunConfiguration runConfiguration) throws ExecutionException {
Executor executor = DefaultDebugExecutor.getDebugExecutorInstance();

ExecutionEnvironmentBuilder
.create(project, executor, runConfiguration)
.buildAndExecute();
}

Finally, run it:

// file to set breakpoint in
final String fileUrl = "C:\\Users\\Alex\\IdeaProjects\\untitled\\src\\Main.java";

// line to set breakpoint at
final int line = 2;

// 1. create and toggle a line break point
addLineBreakpoint(project, fileUrl, line);

// 2. print all run configurations to the console
List<RunConfiguration> runConfigurations = printRunConfigurations(project);

// 3. execute the first run configuration
try {
startDebugger(project, runConfigurations.get(0));
} catch(ExecutionException ex) {
System.out.print(ex.getMessage());
}

 

 

0

Please sign in to leave a comment.