From 25eacf2a263861d7082f56f5fa83909d7eb5860c Mon Sep 17 00:00:00 2001 From: Vladimir Parfinenko Date: Wed, 2 Oct 2024 21:44:26 +0200 Subject: [PATCH] [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 --- .../intellij.java.debugger.agent.holder.iml | 10 +++++----- .../debugger/impl/RemoteConnectionBuilder.java | 17 ++++++++++------- .../execution/JavaTestConfigurationBase.java | 17 +++++++++++++++++ .../JavaTestFrameworkRunnableState.java | 11 +++++++++++ .../util/resources/misc/registry.properties | 2 ++ .../resources/messages/JUnitBundle.properties | 2 ++ .../intellij/execution/junit/TestObject.java | 5 +++++ .../configuration/JUnitSettingsEditor.java | 6 ++++++ .../resources/messages/TestngBundle.properties | 1 + .../TestNGConfigurationEditor.form | 14 ++++++++++++-- .../TestNGConfigurationEditor.java | 8 ++++++++ .../configuration/TestNGRunnableState.java | 5 +++++ 12 files changed, 84 insertions(+), 14 deletions(-) diff --git a/java/debugger/debugger-agent/intellij.java.debugger.agent.holder.iml b/java/debugger/debugger-agent/intellij.java.debugger.agent.holder.iml index 0f518f29ca7e..822d679aa00e 100644 --- a/java/debugger/debugger-agent/intellij.java.debugger.agent.holder.iml +++ b/java/debugger/debugger-agent/intellij.java.debugger.agent.holder.iml @@ -7,19 +7,19 @@ - + - - 5a46643970b5a84635d16c07996263c4791323a56cb4dc2b24373d343714b56f + + 9001b25c08cb408ceeb419d13000e0bbdd4d75d50d8be52dc8705edc05961642 - + - + diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/RemoteConnectionBuilder.java b/java/debugger/impl/src/com/intellij/debugger/impl/RemoteConnectionBuilder.java index f2b6d6845abd..ff9a2db1486c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/RemoteConnectionBuilder.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/RemoteConnectionBuilder.java @@ -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"); - } - } } } diff --git a/java/execution/impl/src/com/intellij/execution/JavaTestConfigurationBase.java b/java/execution/impl/src/com/intellij/execution/JavaTestConfigurationBase.java index 4cef570d12ee..31e9c60ae866 100644 --- a/java/execution/impl/src/com/intellij/execution/JavaTestConfigurationBase.java +++ b/java/execution/impl/src/com/intellij/execution/JavaTestConfigurationBase.java @@ -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; + } } diff --git a/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java b/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java index 0e5379e4c433..e124c498bd1c 100644 --- a/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java +++ b/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java @@ -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 diff --git a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitSettingsEditor.java b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitSettingsEditor.java index 1a61531fc96e..760b22bfda25 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitSettingsEditor.java +++ b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitSettingsEditor.java @@ -122,6 +122,12 @@ public class JUnitSettingsEditor extends JavaSettingsEditorBase JUnitBundle.message("junit.configuration.fork.mode." + s.toLowerCase(Locale.ENGLISH))); fragments.add(forkMode); + SettingsEditorFragment 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(); diff --git a/plugins/testng/resources/messages/TestngBundle.properties b/plugins/testng/resources/messages/TestngBundle.properties index db30eb2a250f..814dcfc60df1 100644 --- a/plugins/testng/resources/messages/TestngBundle.properties +++ b/plugins/testng/resources/messages/TestngBundle.properties @@ -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 diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.form b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.form index 4109b74bf1b9..a436a0ede2a6 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.form +++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.form @@ -3,12 +3,12 @@ - + - + @@ -129,6 +129,16 @@ + + + + + + + + + + diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java index b91ba939dd54..dc5b334047da 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java +++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java @@ -90,6 +90,7 @@ public class TestNGConfigurationEditor extends Se private JPanel myListenersPanel; private LabeledComponent myShortenCommandLineCombo; private LabeledComponent myUseModulePath; + private LabeledComponent myAsyncStackTraceForExceptions; TextFieldWithBrowseButton myPatternTextField; private final CommonJavaParametersPanel commonJavaParameters = new CommonJavaParametersPanel(); private final ArrayList> propertiesList = new ArrayList<>(); @@ -184,6 +185,10 @@ public class TestNGConfigurationEditor 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 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 extends Se config.setShortenCommandLine(myShortenCommandLineCombo.getComponent().getSelectedItem()); config.setUseModulePath(myUseModulePath.isVisible() && myUseModulePath.getComponent().isSelected()); + + config.setPrintAsyncStackTraceForExceptions(myAsyncStackTraceForExceptions.getComponent().isSelected()); } public ConfigurationModuleSelector getModuleSelector() { diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java index efdce4beeafe..48cc20776707 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java +++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java @@ -131,6 +131,11 @@ public class TestNGRunnableState extends JavaTestFrameworkRunnableState