[debugger] print async stack trace during exception stack trace printing in debug and test runs, IDEA-356859

Java is supported completely, Kotlin -- partially

GitOrigin-RevId: 345192cb18ea86cf39d97b5dd538bb44d29e41ab
This commit is contained in:
Vladimir Parfinenko
2024-10-02 21:56:49 +00:00
committed by intellij-monorepo-bot
parent 9765a5c4ce
commit 25eacf2a26
12 changed files with 84 additions and 14 deletions
@@ -7,19 +7,19 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library name="debugger-agent" type="repository">
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps:debugger-agent:1.30">
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps:debugger-agent:1.35">
<verification>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/debugger-agent/1.30/debugger-agent-1.30.jar">
<sha256sum>5a46643970b5a84635d16c07996263c4791323a56cb4dc2b24373d343714b56f</sha256sum>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/debugger-agent/1.35/debugger-agent-1.35.jar">
<sha256sum>9001b25c08cb408ceeb419d13000e0bbdd4d75d50d8be52dc8705edc05961642</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/debugger-agent/1.30/debugger-agent-1.30.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/debugger-agent/1.35/debugger-agent-1.35.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/debugger-agent/1.30/debugger-agent-1.30-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/debugger-agent/1.35/debugger-agent-1.35-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
@@ -211,19 +211,22 @@ public class RemoteConnectionBuilder {
try (AccessToken ignore = SlowOperations.knownIssue("IDEA-307303, EA-835503")) {
parametersList.add(prefix + agentPath + generateAgentSettings(project));
}
if (Registry.is("debugger.async.stacks.coroutines", false)) {
parametersList.addProperty("kotlinx.coroutines.debug.enable.creation.stack.trace", "false");
parametersList.addProperty("debugger.agent.enable.coroutines", "true");
if (Registry.is("debugger.async.stacks.flows", false)) {
parametersList.addProperty("kotlinx.coroutines.debug.enable.flows.stack.trace", "true");
}
}
if (!Registry.is("debugger.async.stack.trace.for.exceptions.printing", false)) {
parametersList.addProperty("debugger.agent.support.throwable", "false");
}
}
}
else {
LOG.error("Capture agent not found: " + agentArtifactPath);
}
}
if (Registry.is("debugger.async.stacks.coroutines", false)) {
parametersList.addProperty("kotlinx.coroutines.debug.enable.creation.stack.trace", "false");
parametersList.addProperty("debugger.agent.enable.coroutines", "true");
if (Registry.is("debugger.async.stacks.flows", false)) {
parametersList.addProperty("kotlinx.coroutines.debug.enable.flows.stack.trace", "true");
}
}
}
}
@@ -25,6 +25,8 @@ public abstract class JavaTestConfigurationBase extends JavaRunConfigurationBase
private ShortenCommandLine myShortenCommandLine = null;
private boolean myUseModulePath = true;
private static final @NonNls String USE_CLASS_PATH_ONLY = "useClassPathOnly";
private boolean myPrintAsyncStackTraceForExceptions = true;
private static final @NonNls String PRINT_ASYNC_STACK_TRACE_FOR_EXCEPTIONS_ATTRIBUTE = "printAsyncStackTraceForExceptions";
public JavaTestConfigurationBase(String name,
@NotNull JavaRunConfigurationModule configurationModule,
@@ -76,6 +78,10 @@ public abstract class JavaTestConfigurationBase extends JavaRunConfigurationBase
Element mode = element.getChild("shortenClasspath");
setShortenCommandLine(mode != null ? ShortenCommandLine.valueOf(mode.getAttributeValue("name")) : null);
myUseModulePath = element.getChild(USE_CLASS_PATH_ONLY) == null;
{
var value = element.getAttributeValue(PRINT_ASYNC_STACK_TRACE_FOR_EXCEPTIONS_ATTRIBUTE);
myPrintAsyncStackTraceForExceptions = value == null || Boolean.parseBoolean(value);
}
}
@Override
@@ -87,6 +93,9 @@ public abstract class JavaTestConfigurationBase extends JavaRunConfigurationBase
if (!myUseModulePath) {
element.addContent(new Element(USE_CLASS_PATH_ONLY));
}
if (!myPrintAsyncStackTraceForExceptions) {
element.setAttribute(PRINT_ASYNC_STACK_TRACE_FOR_EXCEPTIONS_ATTRIBUTE, "false");
}
}
public boolean isUseModulePath() {
@@ -96,4 +105,12 @@ public abstract class JavaTestConfigurationBase extends JavaRunConfigurationBase
public void setUseModulePath(boolean useModulePath) {
myUseModulePath = useModulePath;
}
public boolean isPrintAsyncStackTraceForExceptions() {
return myPrintAsyncStackTraceForExceptions;
}
public void setPrintAsyncStackTraceForExceptions(boolean printAsyncStackTraceForExceptions) {
myPrintAsyncStackTraceForExceptions = printAsyncStackTraceForExceptions;
}
}
@@ -3,6 +3,7 @@ package com.intellij.execution;
import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil;
import com.intellij.debugger.impl.GenericDebuggerRunnerSettings;
import com.intellij.debugger.impl.RemoteConnectionBuilder;
import com.intellij.diagnostic.logging.OutputFileUtil;
import com.intellij.execution.configurations.*;
import com.intellij.execution.filters.ArgumentFileFilter;
@@ -48,6 +49,7 @@ import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;
@@ -216,6 +218,10 @@ public abstract class JavaTestFrameworkRunnableState<T extends
return false;
}
protected boolean isPrintAsyncStackTraceForExceptions() {
return true;
}
@Override
public void prepareTargetEnvironmentRequest(@NotNull TargetEnvironmentRequest request,
@NotNull TargetProgressIndicator targetProgressIndicator) throws ExecutionException {
@@ -248,6 +254,11 @@ public abstract class JavaTestFrameworkRunnableState<T extends
appendForkInfo(getEnvironment().getExecutor());
appendRepeatMode();
var asyncStackTraceForExceptions = isPrintAsyncStackTraceForExceptions();
if (asyncStackTraceForExceptions && Registry.is("debugger.async.stack.trace.for.exceptions.printing", false)) {
RemoteConnectionBuilder.addDebuggerAgent(getJavaParameters(), getEnvironment().getProject(), true);
}
TargetedCommandLineBuilder commandLineBuilder = super.createTargetedCommandLine(request);
File inputFile = InputRedirectAware.getInputFile(getConfiguration());
if (inputFile != null) {
@@ -590,6 +590,8 @@ debugger.async.stacks.max.depth=500
debugger.async.stacks.max.depth.description=Maximum depth of captured async stacks
debugger.log.async.stacks=false
debugger.log.async.stacks.description=Log async stack trace when log stack trace is checked in breakpoint properties
debugger.async.stack.trace.for.exceptions.printing=true
debugger.async.stack.trace.for.exceptions.printing.description=Include async stack trace in exception's printed stacktrace
debugger.resume.yourkit.threads=true
debugger.keep.step.requests=false
debugger.enable.memory.view=true
@@ -1,6 +1,8 @@
fork.mode.label=&Fork mode:
fork.mode.name=Fork mode
async.stack.trace.for.exceptions.name=Print async stack trace for exceptions
repeat.label=&Repeat:
repeat.name=Repeat
repeat.count.label=&Repeat count:
@@ -522,6 +522,11 @@ public abstract class TestObject extends JavaTestFrameworkRunnableState<JUnitCon
return getConfiguration().getForkMode();
}
@Override
protected boolean isPrintAsyncStackTraceForExceptions() {
return getConfiguration().isPrintAsyncStackTraceForExceptions();
}
/**
* Dependencies for full & forked per module configurations are downloaded;
* <p>
@@ -122,6 +122,12 @@ public class JUnitSettingsEditor extends JavaSettingsEditorBase<JUnitConfigurati
forkMode.setVariantNameProvider(s -> JUnitBundle.message("junit.configuration.fork.mode." + s.toLowerCase(Locale.ENGLISH)));
fragments.add(forkMode);
SettingsEditorFragment<JUnitConfiguration, ?> asyncStackTraceForExceptions =
SettingsEditorFragment.createTag("asyncStackTraceForExceptions", JUnitBundle.message("async.stack.trace.for.exceptions.name"), group,
settings -> settings.isPrintAsyncStackTraceForExceptions(),
(settings, value) -> settings.setPrintAsyncStackTraceForExceptions(value));
fragments.add(asyncStackTraceForExceptions);
testKind.addSettingsEditorListener(
editor -> {
int selectedType = testKind.getTestKind();
@@ -112,3 +112,4 @@ action.text.unknown.test.object=Unknown
action.text.temp.suite=Temp Suite
action.text.tests.in.package=Tests in "{0}"
dialog.message.file.not.found=File ''{0}'' not found
async.stack.trace.for.exceptions.label=Async stack trace for exceptions
@@ -3,12 +3,12 @@
<grid id="27dc6" binding="panel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="772" height="523"/>
<xy x="20" y="20" width="772" height="546"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="b9bd" layout-manager="GridLayoutManager" row-count="7" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="b9bd" layout-manager="GridLayoutManager" row-count="8" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
@@ -129,6 +129,16 @@
<visible value="true"/>
</properties>
</component>
<component id="7e297" class="com.intellij.openapi.ui.LabeledComponent" binding="myAsyncStackTraceForExceptions" default-binding="true">
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<componentClass value="javax.swing.JCheckBox"/>
<labelLocation value="West"/>
<text value=""/>
</properties>
</component>
</children>
</grid>
<tabbedpane id="7ce0a" class="com.intellij.ui.components.JBTabbedPane" default-binding="true">
@@ -90,6 +90,7 @@ public class TestNGConfigurationEditor<T extends TestNGConfiguration> extends Se
private JPanel myListenersPanel;
private LabeledComponent<ShortenCommandLineModeCombo> myShortenCommandLineCombo;
private LabeledComponent<JCheckBox> myUseModulePath;
private LabeledComponent<JCheckBox> myAsyncStackTraceForExceptions;
TextFieldWithBrowseButton myPatternTextField;
private final CommonJavaParametersPanel commonJavaParameters = new CommonJavaParametersPanel();
private final ArrayList<Map.Entry<String, String>> propertiesList = new ArrayList<>();
@@ -184,6 +185,10 @@ public class TestNGConfigurationEditor<T extends TestNGConfiguration> extends Se
myUseModulePath.setAnchor(moduleClasspath.getLabel());
myUseModulePath.getComponent().setText(ExecutionBundle.message("use.module.path.checkbox.label"));
myUseModulePath.getComponent().setSelected(true);
myAsyncStackTraceForExceptions.setAnchor(outputDirectory.getLabel());
myAsyncStackTraceForExceptions.getComponent().setText(TestngBundle.message("async.stack.trace.for.exceptions.label"));
myAsyncStackTraceForExceptions.getComponent().setSelected(true);
}
private void evaluateModuleClassPath() {
@@ -282,6 +287,7 @@ public class TestNGConfigurationEditor<T extends TestNGConfiguration> extends Se
myUseDefaultReportersCheckBox.setSelected(data.USE_DEFAULT_REPORTERS);
myShortenCommandLineCombo.getComponent().setSelectedItem(config.getShortenCommandLine());
myUseModulePath.getComponent().setSelected(config.isUseModulePath());
myAsyncStackTraceForExceptions.getComponent().setSelected(config.isPrintAsyncStackTraceForExceptions());
if (!project.isDefault()) {
SwingUtilities.invokeLater(() ->
ReadAction.nonBlocking(() -> FilenameIndex.getFilesByName(project, PsiJavaModule.MODULE_INFO_FILE, GlobalSearchScope.projectScope(project)).length > 0)
@@ -325,6 +331,8 @@ public class TestNGConfigurationEditor<T extends TestNGConfiguration> extends Se
config.setShortenCommandLine(myShortenCommandLineCombo.getComponent().getSelectedItem());
config.setUseModulePath(myUseModulePath.isVisible() && myUseModulePath.getComponent().isSelected());
config.setPrintAsyncStackTraceForExceptions(myAsyncStackTraceForExceptions.getComponent().isSelected());
}
public ConfigurationModuleSelector getModuleSelector() {
@@ -131,6 +131,11 @@ public class TestNGRunnableState extends JavaTestFrameworkRunnableState<TestNGCo
return "none";
}
@Override
protected boolean isPrintAsyncStackTraceForExceptions() {
return getConfiguration().isPrintAsyncStackTraceForExceptions();
}
@Override
public @Nullable SearchForTestsTask createSearchingForTestsTask(@NotNull TargetEnvironment targetEnvironment) {
return new SearchingForTestsTask(getServerSocket(), config, myTempFile) {