mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-02 06:35:28 +02:00
Implement LLDB memory service
We use CLI to read address size, replacing MI expression evaluation which is not supported by LLDB-MI outside the context of a running process. We accommodate the LLDB response format when reading addressable size. We assume little-endian since CLI 'show endian' is not supported.
This commit is contained in:
parent
931051edfe
commit
fec29d7713
6 changed files with 215 additions and 11 deletions
|
@ -32,6 +32,7 @@
|
||||||
* Intel Corporation - Added Reverse Debugging BTrace support
|
* Intel Corporation - Added Reverse Debugging BTrace support
|
||||||
* Samuel Hultgren (STMicroelectronics) - Bug 533771
|
* Samuel Hultgren (STMicroelectronics) - Bug 533771
|
||||||
* John Dallaway - Add CLI version command (#1186)
|
* John Dallaway - Add CLI version command (#1186)
|
||||||
|
* John Dallaway - Add CLI address size command (#1191)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.dsf.mi.service.command;
|
package org.eclipse.cdt.dsf.mi.service.command;
|
||||||
|
@ -54,6 +55,7 @@ import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordDMContext;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
|
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAddressSize;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAddressableSize;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAddressableSize;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAttach;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAttach;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICatch;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICatch;
|
||||||
|
@ -206,6 +208,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarSetUpdateRange;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowAttributes;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowAttributes;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowFormat;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowFormat;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarUpdate;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarUpdate;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.output.CLIAddressSizeInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIAddressableSizeInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.CLIAddressableSizeInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLICatchInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.CLICatchInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoBreakInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoBreakInfo;
|
||||||
|
@ -269,6 +272,11 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MiSourceFilesInfo;
|
||||||
*/
|
*/
|
||||||
public class CommandFactory {
|
public class CommandFactory {
|
||||||
|
|
||||||
|
/** @since 7.2 */
|
||||||
|
public ICommand<CLIAddressSizeInfo> createCLIAddressSize(IMemoryDMContext ctx) {
|
||||||
|
return new CLIAddressSize(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 4.4
|
* @since 4.4
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2025 John Dallaway and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* John Dallaway - Initial implementation (#1191)
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.output.CLIAddressSizeInfo;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLI command to report address size where the MI expression evaluator is not available
|
||||||
|
*
|
||||||
|
* @since 7.2
|
||||||
|
*/
|
||||||
|
public class CLIAddressSize extends MIInterpreterExecConsole<CLIAddressSizeInfo> {
|
||||||
|
|
||||||
|
private static final String COMMAND = "p/x sizeof(void*)"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
public CLIAddressSize(IMemoryDMContext ctx) {
|
||||||
|
super(ctx, COMMAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CLIAddressSizeInfo getResult(MIOutput miResult) {
|
||||||
|
return new CLIAddressSizeInfo(miResult);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2025 John Dallaway and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* John Dallaway - Initial implementation (#1191)
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.ILog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the result of the CLI command "p/x sizeof(void*)"
|
||||||
|
*
|
||||||
|
* @since 7.2
|
||||||
|
*/
|
||||||
|
public class CLIAddressSizeInfo extends MIInfo {
|
||||||
|
|
||||||
|
private static final Pattern HEX_LITERAL_PATTERN = Pattern.compile("0x[0-9a-fA-F]+"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
private int fAddressSize = 0;
|
||||||
|
|
||||||
|
public CLIAddressSizeInfo(MIOutput record) {
|
||||||
|
super(record);
|
||||||
|
parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void parse() {
|
||||||
|
if (isDone()) {
|
||||||
|
MIOutput out = getMIOutput();
|
||||||
|
for (MIOOBRecord oob : out.getMIOOBRecords()) {
|
||||||
|
if (oob instanceof MIConsoleStreamOutput) {
|
||||||
|
String line = ((MIConsoleStreamOutput) oob).getString().trim();
|
||||||
|
fAddressSize = hexToValue(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAddressSize() {
|
||||||
|
return fAddressSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int hexToValue(String hexString) {
|
||||||
|
// Extract value from responses such as "(unsigned long) 0x0000000000000008\n"
|
||||||
|
Matcher matcher = HEX_LITERAL_PATTERN.matcher(hexString);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return Integer.decode(matcher.group());
|
||||||
|
}
|
||||||
|
ILog.get().error("CLIAddressSizeInfo response not handled: " + hexString); //$NON-NLS-1$
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2014 Ericsson AB and others.
|
* Copyright (c) 2014, 2025 Ericsson AB and others.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License 2.0
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
@ -10,10 +10,16 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||||
|
* John Dallaway - Accommodate LLDB response format (#1191)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.ILog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class takes care of parsing and providing the result of the CLI command
|
* This class takes care of parsing and providing the result of the CLI command
|
||||||
* <br>"p/x (char)-1"
|
* <br>"p/x (char)-1"
|
||||||
|
@ -26,6 +32,8 @@ package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||||
*/
|
*/
|
||||||
public class CLIAddressableSizeInfo extends MIInfo {
|
public class CLIAddressableSizeInfo extends MIInfo {
|
||||||
|
|
||||||
|
private static final Pattern HEX_DIGITS_PATTERN = Pattern.compile("0x([0-9a-fA-F]+)"); //$NON-NLS-1$
|
||||||
|
|
||||||
private int fAddressableSize = 1;
|
private int fAddressableSize = 1;
|
||||||
|
|
||||||
public CLIAddressableSizeInfo(MIOutput record) {
|
public CLIAddressableSizeInfo(MIOutput record) {
|
||||||
|
@ -50,14 +58,14 @@ public class CLIAddressableSizeInfo extends MIInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int hexToOctetCount(String hexString) {
|
private int hexToOctetCount(String hexString) {
|
||||||
//Receiving format is expected in hex form e.g. "$n = 0xffff" or "$n = 0xff"
|
// Receiving format is expected in hex form e.g. "$n = 0xffff" or "$n = 0xff"
|
||||||
//which shall result in 2 and 1 octets respectively
|
// which shall result in 2 and 1 octets respectively.
|
||||||
int starts = hexString.indexOf("x"); //$NON-NLS-1$
|
// Also accommodate "(char) 0xff -1 '\\xff'\n" returned by LLDB-MI.
|
||||||
assert (starts > 0);
|
Matcher matcher = HEX_DIGITS_PATTERN.matcher(hexString);
|
||||||
String hexDigits = hexString.substring(starts + 1);
|
if (matcher.find()) {
|
||||||
assert hexDigits.length() > 1;
|
return matcher.group(1).length() / 2;
|
||||||
int octets = hexDigits.length() / 2;
|
}
|
||||||
|
ILog.get().error("CLIAddressableSizeInfo response not handled: " + hexString); //$NON-NLS-1$
|
||||||
return octets;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2025 John Dallaway and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* John Dallaway - Initial implementation (#1191)
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.llvm.dsf.lldb.core.internal.service;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.service.GDBMemory;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.output.CLIAddressSizeInfo;
|
||||||
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LLDB memory service implementation
|
||||||
|
*/
|
||||||
|
public class LLDBMemory extends GDBMemory {
|
||||||
|
|
||||||
|
private IGDBControl fCommandControl;
|
||||||
|
|
||||||
|
public LLDBMemory(DsfSession session) {
|
||||||
|
super(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(final RequestMonitor requestMonitor) {
|
||||||
|
super.initialize(new ImmediateRequestMonitor(requestMonitor) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
doInitialize(requestMonitor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doInitialize(final RequestMonitor requestMonitor) {
|
||||||
|
fCommandControl = getServicesTracker().getService(IGDBControl.class);
|
||||||
|
requestMonitor.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readAddressSize(final IMemoryDMContext memContext, final DataRequestMonitor<Integer> drm) {
|
||||||
|
// use a CLI command - LLDB-MI does not support expression evaluation until a process is started
|
||||||
|
CommandFactory commandFactory = fCommandControl.getCommandFactory();
|
||||||
|
fCommandControl.queueCommand(commandFactory.createCLIAddressSize(memContext),
|
||||||
|
new DataRequestMonitor<CLIAddressSizeInfo>(ImmediateExecutor.getInstance(), drm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
Integer ptrBytes = getData().getAddressSize();
|
||||||
|
drm.setData(ptrBytes * getAddressableSize(memContext));
|
||||||
|
drm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readEndianness(IMemoryDMContext memContext, final DataRequestMonitor<Boolean> drm) {
|
||||||
|
// assume little-endian - LLDB-MI does not support the "show endian" CLI command
|
||||||
|
drm.setData(Boolean.FALSE);
|
||||||
|
drm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2016 Ericsson.
|
* Copyright (c) 2016, 2025 Ericsson and others.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License 2.0
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
@ -7,11 +7,16 @@
|
||||||
* https://www.eclipse.org/legal/epl-2.0/
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Ericsson - Initial implementation
|
||||||
|
* John Dallaway - Use LLDB memory service (#1191)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.llvm.dsf.lldb.core.internal.service;
|
package org.eclipse.cdt.llvm.dsf.lldb.core.internal.service;
|
||||||
|
|
||||||
import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
|
import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IMemory;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IProcesses;
|
import org.eclipse.cdt.dsf.debug.service.IProcesses;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
|
||||||
|
@ -56,4 +61,10 @@ public class LLDBServiceFactory extends GdbDebugServicesFactory {
|
||||||
protected IProcesses createProcessesService(DsfSession session) {
|
protected IProcesses createProcessesService(DsfSession session) {
|
||||||
return new LLDBProcesses(session);
|
return new LLDBProcesses(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IMemory createMemoryService(DsfSession session) {
|
||||||
|
return new LLDBMemory(session);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue