mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
support SAPIDAttachingConnector for IDEA-168185
This commit is contained in:
@@ -157,7 +157,7 @@ public class ThreadDumpAction extends AnAction implements AnAction.TransparentUp
|
||||
hasEmptyStack = frames.size() == 0;
|
||||
|
||||
final TIntObjectHashMap<List<ObjectReference>> lockedAt = new TIntObjectHashMap<>();
|
||||
if (vmProxy.canGetMonitorFrameInfo()) {
|
||||
if (vmProxy.canGetMonitorFrameInfo() && vmProxy.canBeModified()) {
|
||||
for (MonitorInfo info : threadReference.ownedMonitorsAndFrames()) {
|
||||
final int stackDepth = info.stackDepth();
|
||||
List<ObjectReference> monitors;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+177
-50
@@ -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<String, LocalAttachInfo> 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<String, Integer> 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<? extends RunConfiguration> 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};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -321,6 +321,7 @@
|
||||
<debugger.nodeNameAdjuster implementation="com.intellij.debugger.ui.impl.watch.FieldOuterLocalNameAdjuster"/>
|
||||
|
||||
<programRunner id="defaultDebugRunner" implementation="com.intellij.debugger.impl.GenericDebuggerRunner" order="last"/>
|
||||
<programRunner implementation="com.intellij.debugger.engine.JavaAttachDebuggerProvider$ProcessAttachDebuggerRunner" order="last"/>
|
||||
<programRunner implementation="com.intellij.execution.jar.JarApplicationDebuggerRunner"/>
|
||||
|
||||
<iconLayerProvider implementation="com.intellij.compiler.CompilerIconLayerProvider"/>
|
||||
|
||||
Reference in New Issue
Block a user