From 322474d43b5dc4e81ec1a75146b2413a4386e946 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 8 Jul 2008 18:02:16 +0000 Subject: [PATCH] Bug 240044 New MI commands are being introduced in the new version of GDB to support multi-process debugging. -list-thread-groups -target-attach -target-detach --- .../command/commands/MIListThreadGroups.java | 82 +++++++++ .../command/commands/MITargetAttach.java | 31 ++++ .../command/commands/MITargetDetach.java | 31 ++++ .../output/MIListThreadGroupsInfo.java | 163 ++++++++++++++++++ 4 files changed, 307 insertions(+) create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIListThreadGroups.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetAttach.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetDetach.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIListThreadGroupsInfo.java diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIListThreadGroups.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIListThreadGroups.java new file mode 100644 index 00000000000..c56b1bbd01f --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIListThreadGroups.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import java.util.ArrayList; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIListThreadGroupsInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * -list-thread-groups [--available] [GROUP] + * + * When used without GROUP parameter, this will list top-level + * thread groups that are been debugged. When used with the GROUP + * parameter, the children of the specified group will be listed. + * The children can be either threads, or other groups. At present, + * GDB will not report both threads and groups as children at the + * same time, but it may change in future. + * + * With the --available option, instead of reporting groups that are + * been debugged, GDB will report all thread groups available on the + * target, not only the presently debugged ones. Using the --available + * option together with explicit GROUP is not likely to work on all targets. + * + * The output of the command is: + * + * ^done,threads=[],groups=[] + * + * where each thread group is like this: + * + * {id="xxx",type="process",pid="yyy",num_children="1"} + * + * The id of a thread group should be considered an opaque string. + * + */ +public class MIListThreadGroups extends MICommand { + + + public MIListThreadGroups(IDMContext ctx) { + this(ctx, false); + } + + public MIListThreadGroups(IDMContext ctx, String threadGroupId) { + this(ctx, threadGroupId, false); + } + + public MIListThreadGroups(IDMContext ctx, boolean listAll) { + this(ctx, "", listAll); //$NON-NLS-1$ + } + + public MIListThreadGroups(IDMContext ctx, String threadGroupId, boolean listAll) { + super(ctx, "-list-thread-groups"); //$NON-NLS-1$ + + final ArrayList arguments = new ArrayList(); + if (listAll) { + arguments.add("--available"); //$NON-NLS-1$ + } + + if (threadGroupId != null && threadGroupId.length() > 0) { + arguments.add(threadGroupId); + } + + if (!arguments.isEmpty()) { + setParameters(arguments.toArray(new String[0])); + } + } + + @Override + public MIListThreadGroupsInfo getResult(MIOutput out) { + return new MIListThreadGroupsInfo(out); + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetAttach.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetAttach.java new file mode 100644 index 00000000000..5b6dbd9d6ef --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetAttach.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * -target-attach < --pid PID | THREAD_GROUP_ID > + * + * This command attaches to the process specified by the PID + * or THREAD_GROUP_ID + */ +public class MITargetAttach extends MICommand { + + public MITargetAttach(IDMContext ctx, String threadGroupId) { + super(ctx, "-target-attach", new String[] {threadGroupId}); //$NON-NLS-1$ + } + + public MITargetAttach(IDMContext ctx, int pid) { + super(ctx, "-target-attach" , new String[] {"--pid " + pid}); //$NON-NLS-1$//$NON-NLS-2$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetDetach.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetDetach.java new file mode 100644 index 00000000000..b2e56274e14 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetDetach.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * -target-detach < --pid PID | THREAD_GROUP_ID > + * + * This command detaches from the process specified by the PID + * or THREAD_GROUP_ID + */ +public class MITargetDetach extends MICommand { + + public MITargetDetach(IDMContext ctx, String threadGroupId) { + super(ctx, "-target-detach", new String[] {threadGroupId}); //$NON-NLS-1$ + } + + public MITargetDetach(IDMContext ctx, int pid) { + super(ctx, "-target-detach" , new String[] {"--pid " + pid}); //$NON-NLS-1$//$NON-NLS-2$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIListThreadGroupsInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIListThreadGroupsInfo.java new file mode 100644 index 00000000000..b715d421d36 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIListThreadGroupsInfo.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import org.eclipse.cdt.core.IProcessInfo; + +/** + * GDB/MI thread group parsing. + * + * ^done,groups=[{id="p133",type="process",pid="133"},{id="p162",type="process",pid="162"}] + * or + * ^done,threads=[{id="1",target-id="Thread 162.32942",details="JUnitProcess_PT (Ready) 1275938023 3473",frame={level="0",addr="0x00000000",func="??",args=[]}}] + */ +public class MIListThreadGroupsInfo extends MIInfo { + + public class ThreadGroupInfo implements IProcessInfo { + int pid; + String name; + + public ThreadGroupInfo(String name, String pidStr) { + try { + pid = Integer.parseInt(pidStr); + } catch (NumberFormatException e) { + } + this.name = name; + } + + public ThreadGroupInfo(int pid, String name) { + this.pid = pid; + this.name = name; + } + + /** + * @see org.eclipse.cdt.core.IProcessInfo#getName() + */ + public String getName() { + return name; + } + + /** + * @see org.eclipse.cdt.core.IProcessInfo#getPid() + */ + public int getPid() { + return pid; + } + } + + public class ThreadId { + String fId; + + public ThreadId(String id) { + fId = id; + } + public String getId() { + return fId; + } + } + + IProcessInfo[] fProcessList; + ThreadId[] fThreadList; + + public MIListThreadGroupsInfo(MIOutput out) { + super(out); + parse(); + } + + public IProcessInfo[] getGroupList() { + return fProcessList; + } + + public ThreadId[] getThreadList() { + return fThreadList; + } + + private void parse() { + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("groups")) { //$NON-NLS-1$ + MIValue val = results[i].getMIValue(); + if (val instanceof MIList) { + parseGroups((MIList)val); + } + } else if (var.equals("threads")) { //$NON-NLS-1$ + MIValue val = results[i].getMIValue(); + if (val instanceof MIList) { + parseThreads((MIList)val); + } + } + + } + } + } + if (fProcessList == null) { + fProcessList = new ThreadGroupInfo[0]; + } + if (fThreadList == null) { + fThreadList = new ThreadId[0]; + } + } + + private void parseGroups(MIList list) { + MIValue[] values = list.getMIValues(); + fProcessList = new ThreadGroupInfo[values.length]; + for (int i = 0; i < values.length; i++) { + MIResult[] results = ((MITuple)values[i]).getMIResults(); + String name = "", pid = "";//$NON-NLS-1$//$NON-NLS-2$ + + for (MIResult result : results) { + String var = result.getVariable(); + if (var.equals("id")) { //$NON-NLS-1$ + MIValue value = result.getMIValue(); + if (value instanceof MIConst) { + String str = ((MIConst)value).getCString(); + name = str.trim(); + + } + } else if (var.equals("pid")) { //$NON-NLS-1$ + MIValue value = result.getMIValue(); + if (value instanceof MIConst) { + String str = ((MIConst)value).getCString(); + pid = str.trim(); + + } + } + } + fProcessList[i] = new ThreadGroupInfo(name, pid); + } + } + + private void parseThreads(MIList list) { + MIValue[] values = list.getMIValues(); + fThreadList = new ThreadId[values.length]; + for (int i = 0; i < values.length; i++) { + MIResult[] results = ((MITuple)values[i]).getMIResults(); + + for (MIResult result : results) { + String var = result.getVariable(); + if (var.equals("id")) { //$NON-NLS-1$ + MIValue value = result.getMIValue(); + if (value instanceof MIConst) { + String str = ((MIConst)value).getCString(); + fThreadList[i] = new ThreadId(str.trim()); + break; + } + } + } + } + } +}