diff options
author | Eugene Tarassov | 2014-05-09 03:57:19 +0000 |
---|---|---|
committer | Eugene Tarassov | 2014-05-09 03:57:19 +0000 |
commit | 2e02e6d9183791cad801cb9bffc37efff857095e (patch) | |
tree | 8070a045008e8d5f2cfdd3368163d97dc0edd9d7 | |
parent | 49edf762196ac440cd7c69233e12d207fbc51468 (diff) | |
download | org.eclipse.tcf-2e02e6d9183791cad801cb9bffc37efff857095e.tar.gz org.eclipse.tcf-2e02e6d9183791cad801cb9bffc37efff857095e.tar.xz org.eclipse.tcf-2e02e6d9183791cad801cb9bffc37efff857095e.zip |
TCF Debugger: Launch Configuration dialog: added option to launch and use TCF symbols server
3 files changed, 200 insertions, 116 deletions
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java index 85db70e74..0ff305613 100644 --- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java +++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java @@ -46,6 +46,7 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.tcf.core.TransientPeer; import org.eclipse.tcf.internal.debug.launch.TCFLaunchDelegate; import org.eclipse.tcf.internal.debug.launch.TCFLocalAgent; import org.eclipse.tcf.internal.debug.launch.TCFUserDefPeer; @@ -54,6 +55,7 @@ import org.eclipse.tcf.internal.debug.ui.Activator; import org.eclipse.tcf.internal.debug.ui.ImageCache; import org.eclipse.tcf.internal.debug.ui.launch.PeerListControl.PeerInfo; import org.eclipse.tcf.internal.debug.ui.launch.setup.SetupWizardDialog; +import org.eclipse.tcf.protocol.IChannel; import org.eclipse.tcf.protocol.IPeer; import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.services.IMemoryMap; @@ -69,6 +71,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab { private static final String TAB_ID = "org.eclipse.tcf.launch.targetTab"; + private Button run_local_server_button; private Button run_local_agent_button; private Button use_local_agent_button; private Text peer_id_text; @@ -108,6 +111,15 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab { GridData gd = new GridData(GridData.FILL_HORIZONTAL); local_agent_comp.setLayoutData(gd); + run_local_server_button = createCheckButton(local_agent_comp, "Run TCF symbols server on the local host"); + run_local_server_button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent evt) { + updateLaunchConfigurationDialog(); + } + }); + run_local_server_button.setEnabled(true); + run_local_agent_button = createCheckButton(local_agent_comp, "Run instance of TCF agent on the local host"); run_local_agent_button.addSelectionListener(new SelectionAdapter() { @Override @@ -308,7 +320,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab { if (use_local_agent_button.getSelection()) { peer_tree.setEnabled(false); peer_tree.deselectAll(); - String id = TCFLocalAgent.getLocalAgentID(); + String id = TCFLocalAgent.getLocalAgentID(TCFLocalAgent.AGENT_NAME); if (id == null) id = ""; peer_id_text.setText(id); peer_id_text.setEnabled(false); @@ -346,6 +358,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab { String id = configuration.getAttribute(TCFLaunchDelegate.ATTR_PEER_ID, ""); peer_id_text.setText(id); peer_list.setInitialSelection(id); + run_local_server_button.setSelection(configuration.getAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_SERVER, false)); run_local_agent_button.setSelection(configuration.getAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_AGENT, false)); use_local_agent_button.setSelection(configuration.getAttribute(TCFLaunchDelegate.ATTR_USE_LOCAL_AGENT, true)); mem_map_cfg = configuration.getAttribute(TCFLaunchDelegate.ATTR_MEMORY_MAP, "null"); @@ -365,11 +378,13 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab { else { configuration.setAttribute(TCFLaunchDelegate.ATTR_PEER_ID, peer_id_text.getText()); } + configuration.setAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_SERVER, run_local_server_button.getSelection()); configuration.setAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_AGENT, run_local_agent_button.getSelection()); configuration.setAttribute(TCFLaunchDelegate.ATTR_USE_LOCAL_AGENT, use_local_agent_button.getSelection()); } public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { + configuration.setAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_SERVER, false); configuration.setAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_AGENT, false); configuration.setAttribute(TCFLaunchDelegate.ATTR_USE_LOCAL_AGENT, true); configuration.removeAttribute(TCFLaunchDelegate.ATTR_PEER_ID); @@ -396,8 +411,8 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab { IPeer peer = null; if (use_local_agent_button.getSelection()) { try { - if (run_local_agent_button.getSelection()) TCFLocalAgent.runLocalAgent(); - final String id = TCFLocalAgent.getLocalAgentID(); + if (run_local_agent_button.getSelection()) TCFLocalAgent.runLocalAgent(TCFLocalAgent.AGENT_NAME); + final String id = TCFLocalAgent.getLocalAgentID(TCFLocalAgent.AGENT_NAME); peer = new TCFTask<IPeer>() { public void run() { done(Protocol.getLocator().getPeers().get(id)); @@ -419,6 +434,33 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab { peer = info.peer; } if (peer == null) return; + if (run_local_server_button.getSelection()) { + try { + final IPeer agent = peer; + final String id = TCFLocalAgent.runLocalAgent(TCFLocalAgent.SERVER_NAME); + IPeer server = new TCFTask<IPeer>() { + public void run() { + done(Protocol.getLocator().getPeers().get(id)); + } + }.get(); + peer = new TransientPeer(server.getAttributes()) { + public IChannel openChannel() { + assert Protocol.isDispatchThread(); + IChannel c = super.openChannel(); + c.redirect(agent.getAttributes()); + return c; + } + }; + } + catch (Throwable err) { + String msg = err.getLocalizedMessage(); + if (msg == null || msg.length() == 0) msg = err.getClass().getName(); + MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK); + mb.setText("Error"); + mb.setMessage("Cannot start symbols server:\n" + msg); + mb.open(); + } + } final Shell shell = new Shell(getShell(), SWT.TITLE | SWT.PRIMARY_MODAL); GridLayout layout = new GridLayout(); layout.verticalSpacing = 0; diff --git a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java index bdfc3deae..f1f7bff0f 100644 --- a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java +++ b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java @@ -59,6 +59,7 @@ public class TCFLaunchDelegate extends LaunchConfigurationDelegate { ATTR_STOP_AT_MAIN = ITCFConstants.ID_TCF_DEBUG_MODEL + ".StopAtMain", ATTR_DISCONNECT_ON_CTX_EXIT = ITCFConstants.ID_TCF_DEBUG_MODEL + ".DisconnectOnCtxExit", ATTR_USE_TERMINAL = ITCFConstants.ID_TCF_DEBUG_MODEL + ".UseTerminal", + ATTR_RUN_LOCAL_SERVER = ITCFConstants.ID_TCF_DEBUG_MODEL + ".RunLocalServer", ATTR_RUN_LOCAL_AGENT = ITCFConstants.ID_TCF_DEBUG_MODEL + ".RunLocalAgent", ATTR_USE_LOCAL_AGENT = ITCFConstants.ID_TCF_DEBUG_MODEL + ".UseLocalAgent", ATTR_SIGNALS_DONT_STOP = ITCFConstants.ID_TCF_DEBUG_MODEL + ".SignalsDontStop", @@ -348,23 +349,31 @@ public class TCFLaunchDelegate extends LaunchConfigurationDelegate { String local_id = null; if (configuration.getAttribute(ATTR_RUN_LOCAL_AGENT, false)) { if (monitor != null) monitor.subTask("Starting TCF Agent"); //$NON-NLS-1$ - local_id = TCFLocalAgent.runLocalAgent(); + local_id = TCFLocalAgent.runLocalAgent(TCFLocalAgent.AGENT_NAME); } else if (configuration.getAttribute(ATTR_USE_LOCAL_AGENT, true)) { if (monitor != null) monitor.subTask("Searching TCF Agent"); //$NON-NLS-1$ - local_id = TCFLocalAgent.getLocalAgentID(); + local_id = TCFLocalAgent.getLocalAgentID(TCFLocalAgent.AGENT_NAME); if (local_id == null) throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Cannot find TCF agent on the local host", null)); } - final String id = configuration.getAttribute(ATTR_USE_LOCAL_AGENT, true) ? + String id = configuration.getAttribute(ATTR_USE_LOCAL_AGENT, true) ? local_id : configuration.getAttribute(ATTR_PEER_ID, ""); + if (configuration.getAttribute(ATTR_RUN_LOCAL_SERVER, false)) { + if (monitor != null) monitor.subTask("Starting TCF Server"); //$NON-NLS-1$ + String server_id = TCFLocalAgent.runLocalAgent(TCFLocalAgent.SERVER_NAME); + id = server_id + "/" + id; + } + + final String agent_id = id; + new TCFTask<Boolean>() { public void run() { - ((TCFLaunch)launch).launchTCF(mode, id, this, monitor); + ((TCFLaunch)launch).launchTCF(mode, agent_id, this, monitor); } }.getE(); } diff --git a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLocalAgent.java b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLocalAgent.java index d30176e84..cb06ca638 100644 --- a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLocalAgent.java +++ b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLocalAgent.java @@ -18,6 +18,8 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.net.URL; import java.net.URLConnection; +import java.util.HashMap; +import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; @@ -38,158 +40,190 @@ import org.osgi.framework.Bundle; */ public class TCFLocalAgent { - private static final String - AGENT_HOST = "127.0.0.1", - AGENT_PORT = "1534"; + public static final String + LOCAL_HOST = "127.0.0.1", + AGENT_NAME = "agent", + SERVER_NAME = "server"; + + private static final Map<String,String> ports = new HashMap<String,String>(); + private static final Map<String,Process> agents = new HashMap<String,Process>(); + + static { + ports.put(AGENT_NAME, "1534"); + ports.put(SERVER_NAME, "1535"); + } - private static Process agent; private static boolean destroed; - private static String getAgentFileName() { + private static String getSysName() { String os = System.getProperty("os.name"); String arch = System.getProperty("os.arch"); - String fnm = "agent"; if (arch.equals("x86")) arch = "i386"; if (arch.equals("i686")) arch = "i386"; if (os.startsWith("Windows")) { os = "Windows"; - fnm = "agent.exe"; } if (os.equals("Linux")) os = "GNU/Linux"; - return "agent/" + os + "/" + arch + "/" + fnm; + return os + "/" + arch; } - public static synchronized String runLocalAgent() throws CoreException { + private static Path getDevelAgentFileName(String nm) { + try { + String fnm = nm; + String sys = getSysName(); + if (sys.startsWith("Windows")) { + sys = "MSVC/Win32"; + fnm += ".exe"; + } + Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID); + File plugin = FileLocator.getBundleFile(bundle); + File agent = new File(plugin, "../../../org.eclipse.tcf.agent/" + nm + "/obj/" + sys + "/Debug/" + fnm); + if (!agent.exists()) return null; + return new Path(agent.getAbsolutePath()); + } + catch (Exception x) { + Activator.log("Cannot find bundle location", x); + } + return null; + } + + private static Path getAgentFileName(String fnm) { + String sys = getSysName(); + if (sys.startsWith("Windows")) fnm += ".exe"; + return new Path("agent/" + sys + "/" + fnm); + } + + public static synchronized String runLocalAgent(final String nm) throws CoreException { if (destroed) return null; - String id = getLocalAgentID(); + String id = getLocalAgentID(nm); if (id != null) return id; - if (agent != null) { - agent.destroy(); - agent = null; + if (agents.containsKey(nm)) { + agents.remove(nm).destroy(); } - Path fnm = new Path(getAgentFileName()); + Path fnm = getDevelAgentFileName(nm); + if (fnm == null) fnm = getAgentFileName(nm); try { - Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID); - URL url = FileLocator.find(bundle, fnm, null); - if (url != null) { - URLConnection ucn = url.openConnection(); - ucn.setRequestProperty("Method", "HEAD"); - ucn.connect(); - long mtime = ucn.getLastModified(); - File f = Activator.getDefault().getStateLocation().append(fnm).toFile(); - if (!f.exists() || mtime != f.lastModified()) { - f.getParentFile().mkdirs(); - InputStream inp = url.openStream(); - OutputStream out = new FileOutputStream(f); - byte[] buf = new byte[0x1000]; - for (;;) { - int len = inp.read(buf); - if (len < 0) break; - out.write(buf, 0, len); - } - out.close(); - inp.close(); - if (!"exe".equals(fnm.getFileExtension())) { - String[] cmd = { - "chmod", - "a+x", - f.getAbsolutePath() - }; - Runtime.getRuntime().exec(cmd).waitFor(); + if (!fnm.isAbsolute()) { + Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID); + URL url = FileLocator.find(bundle, fnm, null); + if (url != null) { + URLConnection ucn = url.openConnection(); + ucn.setRequestProperty("Method", "HEAD"); + ucn.connect(); + long mtime = ucn.getLastModified(); + File f = Activator.getDefault().getStateLocation().append(fnm).toFile(); + if (!f.exists() || mtime != f.lastModified()) { + f.getParentFile().mkdirs(); + InputStream inp = url.openStream(); + OutputStream out = new FileOutputStream(f); + byte[] buf = new byte[0x1000]; + for (;;) { + int len = inp.read(buf); + if (len < 0) break; + out.write(buf, 0, len); + } + out.close(); + inp.close(); + if (!"exe".equals(fnm.getFileExtension())) { + String[] cmd = { + "chmod", + "a+x", + f.getAbsolutePath() + }; + Runtime.getRuntime().exec(cmd).waitFor(); + } + f.setLastModified(mtime); + fnm = new Path(f.getAbsolutePath()); } - f.setLastModified(mtime); } - String[] cmd = { - f.getAbsolutePath(), - "-s", - "TCP:" + AGENT_HOST + ":" + AGENT_PORT - }; - final Process prs = agent = Runtime.getRuntime().exec(cmd); - final TCFTask<String> waiting = waitAgentReady(); - Thread t = new Thread() { - public void run() { - try { - final int n = prs.waitFor(); - final StringBuffer sbf = new StringBuffer(); - if (n != 0) { - char cbf[] = new char[256]; - InputStreamReader r = new InputStreamReader(prs.getErrorStream()); - for (;;) { - try { - int rd = r.read(cbf); - if (rd < 0) break; - sbf.append(cbf, 0, rd); - } - catch (IOException x) { - break; - } - } + } + String[] cmd = { + fnm.toOSString(), + "-s", + "TCP:" + LOCAL_HOST + ":" + ports.get(nm) + }; + final Process prs = Runtime.getRuntime().exec(cmd); + agents.put(nm, prs); + final TCFTask<String> waiting = waitAgentReady(nm); + Thread t = new Thread() { + public void run() { + try { + final int n = prs.waitFor(); + final StringBuffer sbf = new StringBuffer(); + if (n != 0) { + char cbf[] = new char[256]; + InputStreamReader r = new InputStreamReader(prs.getErrorStream()); + for (;;) { try { - r.close(); + int rd = r.read(cbf); + if (rd < 0) break; + sbf.append(cbf, 0, rd); } catch (IOException x) { + break; } - sbf.append("TCF Agent exited with code "); - sbf.append(n); - Protocol.invokeLater(new Runnable() { - public void run() { - if (waiting.isDone()) return; - waiting.error(new IOException(sbf.toString())); - } - }); } - synchronized (TCFLocalAgent.class) { - if (agent == prs) { - if (n != 0 && !destroed) { - Activator.log(sbf.toString(), null); - } - agent = null; - } + try { + r.close(); } + catch (IOException x) { + } + sbf.append("TCF " + nm + " exited with code "); + sbf.append(n); + Protocol.invokeLater(new Runnable() { + public void run() { + if (waiting.isDone()) return; + waiting.error(new IOException(sbf.toString())); + } + }); } - catch (InterruptedException x) { - Activator.log("TCF Agent Monitor interrupted", x); + synchronized (TCFLocalAgent.class) { + if (agents.get(nm) == prs) { + if (n != 0 && !destroed) { + Activator.log(sbf.toString(), null); + } + agents.remove(nm); + } } } - }; - t.setDaemon(true); - t.setName("TCF Agent Monitor"); - t.start(); - return waiting.getIO(); - } + catch (InterruptedException x) { + Activator.log("TCF " + nm + " monitor interrupted", x); + } + } + }; + t.setDaemon(true); + t.setName("TCF Agent Monitor"); + t.start(); + return waiting.getIO(); } catch (Throwable x) { - agent = null; + agents.remove(nm); throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, - "Cannot start local TCF agent.", + "Cannot start local TCF " + nm + ".", x)); } - throw new CoreException(new Status(IStatus.ERROR, - Activator.PLUGIN_ID, 0, - "Cannot start local TCF agent: file not available:\n" + fnm, - null)); } - private static boolean isLocalAgent(IPeer p) { + private static boolean isLocalAgent(IPeer p, String nm) { String prot = p.getTransportName(); if (prot.equals("PIPE")) return true; if (prot.equals("UNIX")) { String port = p.getAttributes().get(IPeer.ATTR_IP_PORT); - return AGENT_PORT.equals(port); + return ports.get(nm).equals(port); } String host = p.getAttributes().get(IPeer.ATTR_IP_HOST); String port = p.getAttributes().get(IPeer.ATTR_IP_PORT); - return AGENT_HOST.equals(host) && AGENT_PORT.equals(port); + return LOCAL_HOST.equals(host) && ports.get(nm).equals(port); } - public static synchronized String getLocalAgentID() { + public static synchronized String getLocalAgentID(final String nm) { return new TCFTask<String>() { int cnt; public void run() { final ILocator locator = Protocol.getLocator(); for (IPeer p : locator.getPeers().values()) { - if (isLocalAgent(p)) { + if (isLocalAgent(p, nm)) { done(p.getID()); return; } @@ -204,19 +238,19 @@ public class TCFLocalAgent { }.getE(); } - private static TCFTask<String> waitAgentReady() { + private static TCFTask<String> waitAgentReady(final String nm) { return new TCFTask<String>() { public void run() { final ILocator locator = Protocol.getLocator(); for (IPeer p : locator.getPeers().values()) { - if (isLocalAgent(p)) { + if (isLocalAgent(p, nm)) { done(p.getID()); return; } } final ILocator.LocatorListener listener = new ILocator.LocatorListener() { public void peerAdded(IPeer p) { - if (!isDone() && isLocalAgent(p)) { + if (!isDone() && isLocalAgent(p, nm)) { done(p.getID()); locator.removeListener(this); } @@ -242,9 +276,8 @@ public class TCFLocalAgent { } public static synchronized void destroy() { - if (agent != null) { - destroed = true; - agent.destroy(); - } + destroed = true; + for (Process prs : agents.values()) prs.destroy(); + agents.clear(); } } |