IDEA-199513 Attach to process (read only) does not work if it requires administrator privileges

This commit is contained in:
Egor Ushakov
2018-09-27 12:11:42 +03:00
parent 122f9a282c
commit 38e706bda2
6 changed files with 88 additions and 20 deletions

View File

@@ -1,12 +1,12 @@
<component name="libraryTable">
<library name="sa-jdwp" type="repository">
<properties maven-id="org.jetbrains.intellij.deps:sa-jdwp:1.0.3" />
<properties maven-id="org.jetbrains.intellij.deps:sa-jdwp:1.0.4" />
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/sa-jdwp/1.0.3/sa-jdwp-1.0.3.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/sa-jdwp/1.0.4/sa-jdwp-1.0.4.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/sa-jdwp/1.0.3/sa-jdwp-1.0.3-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/sa-jdwp/1.0.4/sa-jdwp-1.0.4-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -454,7 +454,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
if (myConnection instanceof PidRemoteConnection) {
PidRemoteConnection pidRemoteConnection = (PidRemoteConnection)myConnection;
Connector connector = pidRemoteConnection.getConnector();
Connector connector = pidRemoteConnection.getConnector(this);
String pid = pidRemoteConnection.getPid();
if (StringUtil.isEmpty(pid)) {
throw new CantRunException(DebuggerBundle.message("error.no.pid"));

View File

@@ -25,7 +25,7 @@ public class PidRemoteConnection extends RemoteConnection {
return myPid;
}
public Connector getConnector() throws ExecutionException {
public Connector getConnector(DebugProcessImpl debugProcess) throws ExecutionException {
return DebugProcessImpl.findConnector("com.sun.jdi.ProcessAttach");
}
}

View File

@@ -1,28 +1,32 @@
// 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.impl.attach;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.CapturingProcessAdapter;
import com.intellij.execution.process.CapturingProcessHandler;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.execution.util.ExecUtil;
import com.jetbrains.sa.SAJDWPListeningConnector;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.util.PathUtil;
import com.jetbrains.sa.SaJdwp;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.connect.Connector;
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
import com.sun.tools.jdi.SocketListeningConnector;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* @author egor
*/
public class SAJDWPRemoteConnection extends PidRemoteConnection {
static {
SaJdwp.setSudoCommandCreator(new SaJdwp.SudoCommandCreator() {
@Override
public List<String> createSudoCommand(List<String> cmds) throws Exception {
GeneralCommandLine commandLine = ExecUtil.sudoCommand(new GeneralCommandLine(cmds),
"Please enter your password to attach with su privileges: ");
return commandLine.getCommandLineList(null);
}
});
}
private static final Logger LOG = Logger.getInstance(SAJDWPRemoteConnection.class);
public SAJDWPRemoteConnection(String pid) {
super(pid, true);
@@ -30,11 +34,74 @@ public class SAJDWPRemoteConnection extends PidRemoteConnection {
}
@Override
public Connector getConnector() {
return new SAJDWPListeningConnector();
public Connector getConnector(DebugProcessImpl debugProcess) {
return new SAJDWPListeningConnector(debugProcess);
}
public static boolean isAvailable() {
return true;
}
public class SAJDWPListeningConnector extends SocketListeningConnector {
private final DebugProcessImpl myDebugProcess;
private String myCurrentAddress;
public SAJDWPListeningConnector(DebugProcessImpl process) {
myDebugProcess = process;
}
@Override
public String startListening(Map<String, ? extends Argument> arguments) throws IOException, IllegalConnectorArgumentsException {
myCurrentAddress = super.startListening(null, arguments);
return myCurrentAddress;
}
@Override
public VirtualMachine accept(Map<String, ? extends Argument> map) throws IOException, IllegalConnectorArgumentsException {
try {
List<String> commands = SaJdwp.getServerProcessCommand(getPid(), myCurrentAddress, false, PathUtil.getJarPathForClass(SaJdwp.class));
GeneralCommandLine commandLine = new GeneralCommandLine(commands);
startServer(commandLine, false);
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException("Unable to start sa-jdwp server", e);
}
return super.accept(map);
}
private void startServer(GeneralCommandLine commandLine, boolean sudo) throws Exception {
if (sudo) {
commandLine = ExecUtil.sudoCommand(commandLine, "Please enter your password to attach with su privileges: ");
}
GeneralCommandLine finalCommandLine = commandLine;
new CapturingProcessHandler(commandLine) {
@Override
protected CapturingProcessAdapter createProcessAdapter(ProcessOutput processOutput) {
return new CapturingProcessAdapter(processOutput) {
@Override
public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) {
myDebugProcess.printToConsole(event.getText());
}
@Override
public void processTerminated(@NotNull ProcessEvent event) {
if (!sudo && myDebugProcess.isInInitialState()) {
try {
startServer(finalCommandLine, true);
}
catch (Exception e) {
LOG.error(e);
}
}
else {
myDebugProcess.stop(true);
}
}
};
}
}.startNotify();
}
}
}

View File

@@ -1,6 +1,7 @@
// 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.impl.attach;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.execution.ExecutionException;
import com.intellij.util.SystemProperties;
import com.sun.jdi.connect.AttachingConnector;
@@ -28,7 +29,7 @@ public class SAPidRemoteConnection extends PidRemoteConnection {
}
@Override
public AttachingConnector getConnector() throws ExecutionException {
public AttachingConnector getConnector(DebugProcessImpl debugProcess) throws ExecutionException {
try {
Path saJarPath = Paths.get(mySAJarPath);
Class<?> connectorClass = Class.forName("sun.jvm.hotspot.jdi.SAPIDAttachingConnector",

View File

@@ -387,7 +387,7 @@ class CommunityLibraryLicenses {
licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
new LibraryLicense(name: "Roboto", attachedTo: "intellij.platform.resources", version: "1.100141", license: "Apache 2.0",
url: "https://github.com/google/roboto/blob/master/LICENSE"),
new LibraryLicense(name: "sa-jdwp", version: "1.0.3", license: "GPL 2.0 + Classpath", url: "https://github.com/JetBrains/jdk-sa-jdwp",
new LibraryLicense(name: "sa-jdwp", version: "1.0.4", license: "GPL 2.0 + Classpath", url: "https://github.com/JetBrains/jdk-sa-jdwp",
licenseUrl: "https://raw.githubusercontent.com/JetBrains/jdk-sa-jdwp/master/LICENSE.txt"),
new LibraryLicense(name: "Saxon-6.5.5", version: "6.5.5", license: "Mozilla Public License", url: "http://saxon.sourceforge.net/",
licenseUrl: "http://www.mozilla.org/MPL/"),