From e43fa59477be0f054b4f893e4350ce1f3ecce86f Mon Sep 17 00:00:00 2001 From: Egor Ushakov Date: Fri, 17 Aug 2018 11:27:09 +0300 Subject: [PATCH] support SAPIDAttachingConnector for IDEA-168185 --- .../debugger/actions/ThreadDumpAction.java | 2 +- .../debugger/engine/DebugProcessEvents.java | 47 ++-- .../debugger/engine/DebugProcessImpl.java | 33 ++- .../engine/JavaAttachDebuggerProvider.java | 227 ++++++++++++++---- .../debugger/engine/PidRemoteConnection.java | 20 ++ .../engine/requests/RequestManagerImpl.java | 4 +- .../debugger/jdi/VirtualMachineProxyImpl.java | 10 + .../src/messages/DebuggerBundle.properties | 1 + resources/src/META-INF/JavaIdePlugin.xml | 1 + 9 files changed, 271 insertions(+), 74 deletions(-) create mode 100644 java/debugger/impl/src/com/intellij/debugger/engine/PidRemoteConnection.java diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java index 66f3025bcce6..84902b7cc0e5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java @@ -157,7 +157,7 @@ public class ThreadDumpAction extends AnAction implements AnAction.TransparentUp hasEmptyStack = frames.size() == 0; final TIntObjectHashMap> lockedAt = new TIntObjectHashMap<>(); - if (vmProxy.canGetMonitorFrameInfo()) { + if (vmProxy.canGetMonitorFrameInfo() && vmProxy.canBeModified()) { for (MonitorInfo info : threadReference.ownedMonitorsAndFrames()) { final int stackDepth = info.stackDepth(); List monitors; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java index acf02a5b650d..c70e8c8cccb5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java @@ -73,8 +73,11 @@ public class DebugProcessEvents extends DebugProcessImpl { super.commitVM(vm); if(vm != null) { vmAttached(); - myEventThread = new DebuggerEventThread(); - ApplicationManager.getApplication().executeOnPooledThread(ConcurrencyUtil.underThreadNameRunnable("DebugProcessEvents", myEventThread)); + if (vm.canBeModified()) { + myEventThread = new DebuggerEventThread(); + ApplicationManager.getApplication().executeOnPooledThread( + ConcurrencyUtil.underThreadNameRunnable("DebugProcessEvents", myEventThread)); + } } } @@ -323,26 +326,28 @@ public class DebugProcessEvents extends DebugProcessImpl { LOG.assertTrue(!isAttached()); if (myState.compareAndSet(State.INITIAL, State.ATTACHED)) { final VirtualMachineProxyImpl machineProxy = getVirtualMachineProxy(); - final EventRequestManager requestManager = machineProxy.eventRequestManager(); + if (machineProxy.canBeModified()) { + final EventRequestManager requestManager = machineProxy.eventRequestManager(); - if (machineProxy.canGetMethodReturnValues()) { - myReturnValueWatcher = new MethodReturnValueWatcher(requestManager, this); + if (machineProxy.canGetMethodReturnValues()) { + myReturnValueWatcher = new MethodReturnValueWatcher(requestManager, this); + } + + enableNonSuspendingRequest(requestManager.createThreadStartRequest(), + event -> { + ThreadReference thread = ((ThreadStartEvent)event).thread(); + getVirtualMachineProxy().threadStarted(thread); + myDebugProcessDispatcher.getMulticaster().threadStarted(this, thread); + }); + + enableNonSuspendingRequest(requestManager.createThreadDeathRequest(), + event -> { + ThreadReference thread = ((ThreadDeathEvent)event).thread(); + getVirtualMachineProxy().threadStopped(thread); + myDebugProcessDispatcher.getMulticaster().threadStopped(this, thread); + }); } - enableNonSuspendingRequest(requestManager.createThreadStartRequest(), - event -> { - ThreadReference thread = ((ThreadStartEvent)event).thread(); - getVirtualMachineProxy().threadStarted(thread); - myDebugProcessDispatcher.getMulticaster().threadStarted(this, thread); - }); - - enableNonSuspendingRequest(requestManager.createThreadDeathRequest(), - event -> { - ThreadReference thread = ((ThreadDeathEvent)event).thread(); - getVirtualMachineProxy().threadStopped(thread); - myDebugProcessDispatcher.getMulticaster().threadStopped(this, thread); - }); - // fill position managers ((DebuggerManagerImpl)DebuggerManager.getInstance(getProject())).getCustomPositionManagerFactories() .map(factory -> factory.fun(this)) @@ -374,6 +379,10 @@ public class DebugProcessEvents extends DebugProcessImpl { final String transportName = DebuggerBundle.getTransportName(getConnection()); showStatusText(DebuggerBundle.message("status.connected", addressDisplayName, transportName)); LOG.debug("leave: processVMStartEvent()"); + + if (!machineProxy.canBeModified()) { + myDebugProcessDispatcher.getMulticaster().paused(getSuspendManager().pushSuspendContext(EventRequest.SUSPEND_ALL, 0)); + } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java index 0920439d412b..a9b561fc036f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -95,6 +95,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb @NonNls private static final String SHMEM_ATTACHING_CONNECTOR_NAME = "com.sun.jdi.SharedMemoryAttach"; @NonNls private static final String SOCKET_LISTENING_CONNECTOR_NAME = "com.sun.jdi.SocketListen"; @NonNls private static final String SHMEM_LISTENING_CONNECTOR_NAME = "com.sun.jdi.SharedMemoryListen"; + @NonNls static final String SAPID_ATTACHING_CONNECTOR_NAME = "sun.jvm.hotspot.jdi.SAPIDAttachingConnector"; private final Project myProject; private final RequestManagerImpl myRequestManager; @@ -440,7 +441,27 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb } final String address = myConnection.getAddress(); - if (myConnection.isServerMode()) { + + if (myConnection instanceof PidRemoteConnection) { + String pid = ((PidRemoteConnection)myConnection).getPid(); + if (StringUtil.isEmpty(pid)) { + throw new CantRunException(DebuggerBundle.message("error.no.pid")); + } + AttachingConnector connector = (AttachingConnector)findConnector(SAPID_ATTACHING_CONNECTOR_NAME); + myArguments = connector.defaultArguments(); + Connector.Argument pidArg = myArguments.get("pid"); + if (pidArg != null) { + pidArg.setValue(pid); + } + myDebugProcessDispatcher.getMulticaster().connectorIsReady(); + try { + return connector.attach(myArguments); + } + catch (IllegalArgumentException e) { + throw new CantRunException(e.getLocalizedMessage()); + } + } + else if (myConnection.isServerMode()) { ListeningConnector connector = (ListeningConnector)findConnector(myConnection.isUseSockets(), true); myArguments = connector.defaultArguments(); if (myArguments == null) { @@ -567,7 +588,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb } @NotNull - private static Connector findConnector(String connectorName) throws ExecutionException { + static Connector findConnector(String connectorName) throws ExecutionException { VirtualMachineManager virtualMachineManager; try { virtualMachineManager = Bootstrap.virtualMachineManager(); @@ -1449,7 +1470,13 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb @Override protected void action() { if (isAttached()) { - final VirtualMachineProxyImpl virtualMachineProxy = getVirtualMachineProxy(); + VirtualMachineProxyImpl virtualMachineProxy = getVirtualMachineProxy(); + + if (!virtualMachineProxy.canBeModified()) { + closeProcess(true); + return; + } + if (myIsTerminateTargetVM) { virtualMachineProxy.exit(-1); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaAttachDebuggerProvider.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaAttachDebuggerProvider.java index 0fc6a7ee4f5c..629b15dde98c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaAttachDebuggerProvider.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaAttachDebuggerProvider.java @@ -2,14 +2,15 @@ package com.intellij.debugger.engine; import com.intellij.debugger.impl.DebuggerManagerImpl; -import com.intellij.execution.ProgramRunnerUtil; -import com.intellij.execution.RunManager; -import com.intellij.execution.RunnerAndConfigurationSettings; -import com.intellij.execution.configurations.ConfigurationTypeUtil; -import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.debugger.impl.GenericDebuggerRunner; +import com.intellij.execution.*; +import com.intellij.execution.configurations.*; import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.process.ProcessInfo; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.internal.DebugAttachDetector; +import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; @@ -17,17 +18,19 @@ import com.intellij.openapi.util.UserDataHolder; import com.intellij.openapi.util.text.StringUtil; import com.intellij.rt.execution.application.AppMainV2; import com.intellij.util.ArrayUtil; -import com.intellij.util.ReflectionUtil; import com.intellij.util.execution.ParametersListUtil; import com.intellij.xdebugger.attach.XDefaultLocalAttachGroup; import com.intellij.xdebugger.attach.XLocalAttachDebugger; import com.intellij.xdebugger.attach.XLocalAttachDebuggerProvider; import com.intellij.xdebugger.attach.XLocalAttachGroup; +import com.sun.jdi.connect.Connector; import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.VirtualMachine; +import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.io.IOException; import java.util.*; @@ -35,6 +38,18 @@ import java.util.*; * @author egor */ public class JavaAttachDebuggerProvider implements XLocalAttachDebuggerProvider { + private static final boolean SA_PID_ATTACH_AVAILABLE; + + static { + Connector sapidAttachConnector = null; + try { + sapidAttachConnector = DebugProcessImpl.findConnector(DebugProcessImpl.SAPID_ATTACHING_CONNECTOR_NAME); + } + catch (ExecutionException ignored) { + } + SA_PID_ATTACH_AVAILABLE = sapidAttachConnector != null; + } + private static class JavaLocalAttachDebugger implements XLocalAttachDebugger { private final Project myProject; private final LocalAttachInfo myInfo; @@ -52,31 +67,10 @@ public class JavaAttachDebuggerProvider implements XLocalAttachDebuggerProvider @Override public void attachDebugSession(@NotNull Project project, @NotNull ProcessInfo processInfo) { - // TODO: first need to remove circular dependency with intellij.java.execution.impl - //RunnerAndConfigurationSettings runSettings = RunManager.getInstance(project) - // .createRunConfiguration(StringUtil.notNullize(address.first) + ":" + address.second, - // RemoteConfigurationType.getInstance().getFactory()); - // - //RemoteConfiguration configuration = (RemoteConfiguration)runSettings.getConfiguration(); - //configuration.HOST = address.first; - //configuration.PORT = String.valueOf(address.second); - //configuration.USE_SOCKET_TRANSPORT = true; - //configuration.SERVER_MODE = false; - - RunnerAndConfigurationSettings runSettings = RunManager.getInstance(myProject).createRunConfiguration( - "localhost:" + myInfo.myAddress, - Objects.requireNonNull(ConfigurationTypeUtil.findConfigurationType("Remote")).getConfigurationFactories()[0]); - - RunConfiguration remoteConfiguration = runSettings.getConfiguration(); - ReflectionUtil.setField(remoteConfiguration.getClass(), remoteConfiguration, String.class, "HOST", - DebuggerManagerImpl.LOCALHOST_ADDRESS_FALLBACK); - ReflectionUtil.setField(remoteConfiguration.getClass(), remoteConfiguration, String.class, - myInfo.myUseSocket ? "PORT" : "SHMEM_ADDRESS", myInfo.myAddress); - ReflectionUtil.setField(remoteConfiguration.getClass(), remoteConfiguration, boolean.class, "USE_SOCKET_TRANSPORT", - myInfo.myUseSocket); - ReflectionUtil.setField(remoteConfiguration.getClass(), remoteConfiguration, boolean.class, "SERVER_MODE", false); - - ProgramRunnerUtil.executeConfiguration(runSettings, DefaultDebugExecutor.getDebugExecutorInstance()); + RunnerAndConfigurationSettings runSettings = + RunManager.getInstance(myProject).createRunConfiguration(myInfo.getSessionName(), ProcessAttachRunConfigurationType.FACTORY); + ((ProcessAttachRunConfiguration)runSettings.getConfiguration()).myAttachInfo = myInfo; + ProgramRunnerUtil.executeConfiguration(runSettings, ProcessAttachDebugExecutor.INSTANCE); } } @@ -99,20 +93,20 @@ public class JavaAttachDebuggerProvider implements XLocalAttachDebuggerProvider public String getProcessDisplayText(@NotNull Project project, @NotNull ProcessInfo info, @NotNull UserDataHolder dataHolder) { LocalAttachInfo attachInfo = getAttachInfo(info, dataHolder.getUserData(ADDRESS_MAP_KEY)); assert attachInfo != null; - StringBuilder res = new StringBuilder(); + String res = ""; String executable = info.getExecutableDisplayName(); if ("java".equals(executable)) { if (!StringUtil.isEmpty(attachInfo.myClass)) { - res.append(attachInfo.myClass); + res = attachInfo.myClass; } else { - res.append(StringUtil.notNullize(ArrayUtil.getLastElement(info.getCommandLine().split(" ")))); // should be class name + res = StringUtil.notNullize(ArrayUtil.getLastElement(info.getCommandLine().split(" "))); // should be class name } } else { - res.append(executable); + res = executable; } - return res.append(" (").append(attachInfo.myAddress).append(')').toString(); + return attachInfo.getProcessDisplayText(res); } }; @@ -147,16 +141,17 @@ public class JavaAttachDebuggerProvider implements XLocalAttachDebuggerProvider @Nullable private static LocalAttachInfo getAttachInfo(ProcessInfo processInfo, @Nullable Map addressMap) { LocalAttachInfo res; + String pidString = String.valueOf(processInfo.getPid()); if (addressMap != null) { - res = addressMap.get(String.valueOf(processInfo.getPid())); + res = addressMap.get(pidString); } else { - res = getProcessAttachInfo(String.valueOf(processInfo.getPid())); + res = getProcessAttachInfo(pidString); } if (res == null) { Pair address = DebugAttachDetector.getAttachAddress(ParametersListUtil.parse(processInfo.getCommandLine())); if (address != null) { - res = new LocalAttachInfo(true, String.valueOf(address.getSecond()), null); + res = new DebuggerLocalAttachInfo(true, String.valueOf(address.getSecond()), null, pidString); } } return res; @@ -168,16 +163,20 @@ public class JavaAttachDebuggerProvider implements XLocalAttachDebuggerProvider try { vm = VirtualMachine.attach(pid); Properties agentProperties = vm.getAgentProperties(); + String command = agentProperties.getProperty("sun.java.command"); + if (!StringUtil.isEmpty(command)) { + command = StringUtil.replace(command, AppMainV2.class.getName(), "").trim(); + command = StringUtil.substringBefore(command, " "); + } String property = agentProperties.getProperty("sun.jdwp.listenerAddress"); if (property != null && property.indexOf(':') != -1) { - String command = agentProperties.getProperty("sun.java.command"); - if (!StringUtil.isEmpty(command)) { - command = StringUtil.replace(command, AppMainV2.class.getName(), "").trim(); - command = StringUtil.substringBefore(command, " "); - } - return new LocalAttachInfo(!"dt_shmem".equals(StringUtil.substringBefore(property, ":")), - StringUtil.substringAfter(property, ":"), - command); + return new DebuggerLocalAttachInfo(!"dt_shmem".equals(StringUtil.substringBefore(property, ":")), + StringUtil.substringAfter(property, ":"), + command, + pid); + } + if (SA_PID_ATTACH_AVAILABLE) { + return new LocalAttachInfo(command, pid); } } catch (AttachNotSupportedException | IOException ignored) { @@ -194,15 +193,143 @@ public class JavaAttachDebuggerProvider implements XLocalAttachDebuggerProvider return null; } - private static class LocalAttachInfo { + private static class DebuggerLocalAttachInfo extends LocalAttachInfo { final boolean myUseSocket; final String myAddress; - final String myClass; - private LocalAttachInfo(boolean socket, @NotNull String address, String aClass) { + public DebuggerLocalAttachInfo(boolean socket, @NotNull String address, String aClass, String pid) { + super(aClass, pid); myUseSocket = socket; myAddress = address; + } + + @Override + RemoteConnection createConnection() { + return new RemoteConnection(myUseSocket, DebuggerManagerImpl.LOCALHOST_ADDRESS_FALLBACK, myAddress, false); + } + + @Override + String getSessionName() { + return "localhost:" + myAddress; + } + + @Override + String getProcessDisplayText(String text) { + return text + " (" + myAddress + ")"; + } + } + + private static class LocalAttachInfo { + final String myClass; + final String myPid; + + private LocalAttachInfo(String aClass, String pid) { myClass = aClass; + myPid = pid; + } + + RemoteConnection createConnection() { + return new PidRemoteConnection(myPid); + } + + String getSessionName() { + return "pid " + myPid; + } + + String getProcessDisplayText(String text) { + return text; + } + } + + private static class ProcessAttachDebugExecutor extends DefaultDebugExecutor { + static ProcessAttachDebugExecutor INSTANCE = new ProcessAttachDebugExecutor(); + + private ProcessAttachDebugExecutor() { + } + + @NotNull + @Override + public String getId() { + return "ProcessAttachDebug"; + } + } + + public static class ProcessAttachDebuggerRunner extends GenericDebuggerRunner { + @NotNull + @Override + public String getRunnerId() { + return "ProcessAttachDebuggerRunner"; + } + + @Nullable + @Override + protected RunContentDescriptor createContentDescriptor(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) + throws ExecutionException { + return attachVirtualMachine(state, environment, ((RemoteState)state).getRemoteConnection(), false); + } + + @Override + public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) { + return executorId.equals(ProcessAttachDebugExecutor.INSTANCE.getId()); + } + } + + private static class ProcessAttachRunConfiguration extends RunConfigurationBase { + private LocalAttachInfo myAttachInfo; + + protected ProcessAttachRunConfiguration(@NotNull Project project) { + super(project, ProcessAttachRunConfigurationType.FACTORY, "ProcessAttachRunConfiguration"); + } + + @NotNull + @Override + public SettingsEditor getConfigurationEditor() { + throw new IllegalStateException("Editing is not supported"); + } + + @Nullable + @Override + public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws ExecutionException { + return new RemoteStateState(getProject(), myAttachInfo.createConnection()); + } + } + + private static class ProcessAttachRunConfigurationType implements ConfigurationType { + static final ProcessAttachRunConfigurationType INSTANCE = new ProcessAttachRunConfigurationType(); + static final ConfigurationFactory FACTORY = new ConfigurationFactory(INSTANCE) { + @NotNull + @Override + public RunConfiguration createTemplateConfiguration(@NotNull Project project) { + return new ProcessAttachRunConfiguration(project); + } + }; + + @Nls + @Override + public String getDisplayName() { + return getId(); + } + + @Nls + @Override + public String getConfigurationTypeDescription() { + return getId(); + } + + @Override + public Icon getIcon() { + return null; + } + + @NotNull + @Override + public String getId() { + return "ProcessAttachRunConfigurationType"; + } + + @Override + public ConfigurationFactory[] getConfigurationFactories() { + return new ConfigurationFactory[]{FACTORY}; } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/PidRemoteConnection.java b/java/debugger/impl/src/com/intellij/debugger/engine/PidRemoteConnection.java new file mode 100644 index 000000000000..abb3d1ccdc3a --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/PidRemoteConnection.java @@ -0,0 +1,20 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.debugger.engine; + +import com.intellij.execution.configurations.RemoteConnection; + +/** + * @author egor + */ +class PidRemoteConnection extends RemoteConnection { + private final String myPid; + + public PidRemoteConnection(String pid) { + super(false, null, null, false); + myPid = pid; + } + + public String getPid() { + return myPid; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java index fcde83e61691..804a9682e251 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java @@ -382,7 +382,9 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque @Override public void processAttached(DebugProcessImpl process) { - myEventRequestManager = myDebugProcess.getVirtualMachineProxy().eventRequestManager(); + if (myDebugProcess.getVirtualMachineProxy().canBeModified()) { + myEventRequestManager = myDebugProcess.getVirtualMachineProxy().eventRequestManager(); + } } public void processClassPrepared(final ClassPrepareEvent event) { diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java index 17b620af80ad..0198a3c90096 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java @@ -221,6 +221,9 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { } public void suspend() { + if (!canBeModified()) { + return; + } DebuggerManagerThreadImpl.assertIsManagerThread(); myPausePressedCount++; myVirtualMachine.suspend(); @@ -228,6 +231,9 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { } public void resume() { + if (!canBeModified()) { + return; + } DebuggerManagerThreadImpl.assertIsManagerThread(); if (myPausePressedCount > 0) { myPausePressedCount--; @@ -556,6 +562,10 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { return myCanGetInstanceInfo.isAvailable(); } + public boolean canBeModified() { + return myVirtualMachine.canBeModified(); + } + @Override public final boolean versionHigher(String version) { return myVirtualMachine.version().compareTo(version) >= 0; diff --git a/resources-en/src/messages/DebuggerBundle.properties b/resources-en/src/messages/DebuggerBundle.properties index a95b01bc547f..94304ab2fb66 100644 --- a/resources-en/src/messages/DebuggerBundle.properties +++ b/resources-en/src/messages/DebuggerBundle.properties @@ -75,6 +75,7 @@ error.debug.connector.not.found=Required connector ''{0}'' not found. Check your error.no.debug.listen.port=The port to listen at unspecified error.no.debug.attach.port=The port to attach to unspecified error.no.shmem.address=Shared memory address unspecified +error.no.pid=Pid is not specified debugger.jdi.bootstrap.error={0}. Check your JDK installation. warning.jdk140.unstable=The debuggee VM version is "1.4.0".\nJ2SDK 1.4.0 documented bugs may cause unstable debugger behavior.\nWe recommend using J2SDK 1.4.0_01 or higher. title.jdk140.unstable=VM Version Warning diff --git a/resources/src/META-INF/JavaIdePlugin.xml b/resources/src/META-INF/JavaIdePlugin.xml index 8610c29e0fc7..a32e3a6229c8 100644 --- a/resources/src/META-INF/JavaIdePlugin.xml +++ b/resources/src/META-INF/JavaIdePlugin.xml @@ -321,6 +321,7 @@ +