mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
java local debugger attach - initial
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.engine;
|
||||
|
||||
import com.intellij.debugger.DebugEnvironment;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.DefaultDebugEnvironment;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.RunManager;
|
||||
import com.intellij.execution.RunnerAndConfigurationSettings;
|
||||
import com.intellij.execution.configurations.ConfigurationTypeUtil;
|
||||
import com.intellij.execution.configurations.RemoteConnection;
|
||||
import com.intellij.execution.executors.DefaultDebugExecutor;
|
||||
import com.intellij.execution.process.ProcessInfo;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
|
||||
import com.intellij.internal.DebugAttachDetector;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.UserDataHolder;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.xdebugger.XDebugProcess;
|
||||
import com.intellij.xdebugger.XDebugProcessStarter;
|
||||
import com.intellij.xdebugger.XDebugSession;
|
||||
import com.intellij.xdebugger.XDebuggerManager;
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author egor
|
||||
*/
|
||||
public class JavaAttachDebuggerProvider implements XLocalAttachDebuggerProvider {
|
||||
private static final XLocalAttachDebugger ourAttachDebugger = new XLocalAttachDebugger() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDebuggerDisplayName() {
|
||||
return "Java Debugger";
|
||||
}
|
||||
|
||||
@Override
|
||||
public XDebugSession attachDebugSession(@NotNull Project project, @NotNull ProcessInfo processInfo) throws ExecutionException {
|
||||
Pair<String, Integer> address = getAttachAddress(processInfo);
|
||||
assert address != null;
|
||||
|
||||
// TODO: first need to remove circular dependency with 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;
|
||||
//
|
||||
//ProgramRunnerUtil.executeConfiguration(project, runSettings, DefaultDebugExecutor.getDebugExecutorInstance());
|
||||
|
||||
String name = StringUtil.notNullize(address.first) + ":" + address.second;
|
||||
RunnerAndConfigurationSettings runSettings = RunManager.getInstance(project)
|
||||
.createRunConfiguration(name, ConfigurationTypeUtil.findConfigurationType("Remote").getConfigurationFactories()[0]);
|
||||
|
||||
RemoteConnection remoteConnection = new RemoteConnection(true, address.first, String.valueOf(address.second), false);
|
||||
ExecutionEnvironment env = new ExecutionEnvironmentBuilder(project, DefaultDebugExecutor.getDebugExecutorInstance())
|
||||
.runProfile(runSettings.getConfiguration())
|
||||
.build();
|
||||
DebugEnvironment environment = new DefaultDebugEnvironment(env, new RemoteStateState(project, remoteConnection), remoteConnection, 0);
|
||||
final DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(env.getProject()).attachVirtualMachine(environment);
|
||||
if (debuggerSession == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return XDebuggerManager.getInstance(project).startSessionAndShowTab(name, null, new XDebugProcessStarter() {
|
||||
@Override
|
||||
@NotNull
|
||||
public XDebugProcess start(@NotNull XDebugSession session) {
|
||||
return JavaDebugProcess.create(session, debuggerSession);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private static final XLocalAttachGroup ourAttachGroup = new XDefaultLocalAttachGroup() {
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getGroupName() {
|
||||
return "Java";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getProcessDisplayText(@NotNull Project project, @NotNull ProcessInfo info) {
|
||||
return info.getCommandLine();
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public XLocalAttachGroup getAttachGroup() {
|
||||
return ourAttachGroup;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<XLocalAttachDebugger> getAvailableDebuggers(@NotNull Project project,
|
||||
@NotNull ProcessInfo processInfo,
|
||||
@NotNull UserDataHolder contextHolder) {
|
||||
Pair<String, Integer> address = getAttachAddress(processInfo);
|
||||
if (address != null) {
|
||||
return Collections.singletonList(ourAttachDebugger);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static Pair<String, Integer> getAttachAddress(ProcessInfo processInfo) {
|
||||
return DebugAttachDetector.getAttachAddress(StringUtil.split(processInfo.getCommandLine(), " "));
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,11 @@ import com.intellij.notification.Notifications;
|
||||
import com.intellij.openapi.application.ex.ApplicationEx;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.net.NetUtils;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -40,14 +42,10 @@ public class DebugAttachDetector {
|
||||
private boolean myAttached;
|
||||
private boolean myReady;
|
||||
|
||||
public DebugAttachDetector() {
|
||||
ApplicationEx app = ApplicationManagerEx.getApplicationEx();
|
||||
if (!app.isInternal()
|
||||
|| app.isUnitTestMode()
|
||||
|| app.isHeadlessEnvironment()
|
||||
|| "true".equals(System.getProperty("idea.debug.mode"))) return;
|
||||
|
||||
for (String argument : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
|
||||
public static Pair<String, Integer> getAttachAddress(List<String> arguments) {
|
||||
String host = null;
|
||||
int port = -1;
|
||||
for (String argument : arguments) {
|
||||
if (argument.startsWith("-agentlib:jdwp") && argument.contains("transport=dt_socket")) {
|
||||
String[] params = argument.split(",");
|
||||
for (String param : params) {
|
||||
@@ -55,16 +53,16 @@ public class DebugAttachDetector {
|
||||
try {
|
||||
String[] address = param.split("=")[1].split(":");
|
||||
if (address.length == 1) {
|
||||
myPort = Integer.parseInt(address[0]);
|
||||
port = Integer.parseInt(address[0]);
|
||||
}
|
||||
else {
|
||||
myHost = address[0];
|
||||
myPort = Integer.parseInt(address[1]);
|
||||
host = address[0];
|
||||
port = Integer.parseInt(address[1]);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -72,8 +70,23 @@ public class DebugAttachDetector {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (port > -1) {
|
||||
return Pair.create(host, port);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (myPort < 0) return;
|
||||
public DebugAttachDetector() {
|
||||
ApplicationEx app = ApplicationManagerEx.getApplicationEx();
|
||||
if (!app.isInternal()
|
||||
|| app.isUnitTestMode()
|
||||
|| app.isHeadlessEnvironment()
|
||||
|| "true".equals(System.getProperty("idea.debug.mode"))) return;
|
||||
|
||||
Pair<String, Integer> attachAddress = getAttachAddress(ManagementFactory.getRuntimeMXBean().getInputArguments());
|
||||
if (attachAddress == null) return;
|
||||
myHost = attachAddress.first;
|
||||
myPort = attachAddress.second;
|
||||
|
||||
myTask = JobScheduler.getScheduler().scheduleWithFixedDelay(() -> {
|
||||
boolean attached = !NetUtils.canConnectToRemoteSocket(myHost, myPort);
|
||||
|
||||
@@ -1610,6 +1610,7 @@
|
||||
|
||||
<xdebugger.debuggerSupport implementation="com.intellij.debugger.ui.JavaDebuggerSupport"/>
|
||||
<xdebugger.settings implementation="com.intellij.debugger.settings.JavaDebuggerSettings"/>
|
||||
<xdebugger.localAttachDebuggerProvider implementation="com.intellij.debugger.engine.JavaAttachDebuggerProvider"/>
|
||||
|
||||
<xdebugger.breakpointType implementation="com.intellij.debugger.ui.breakpoints.JavaMethodBreakpointType"/>
|
||||
<xdebugger.breakpointType implementation="com.intellij.debugger.ui.breakpoints.JavaWildcardMethodBreakpointType"/>
|
||||
|
||||
Reference in New Issue
Block a user