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
|
||||
* Samuel Hultgren (STMicroelectronics) - Bug 533771
|
||||
* John Dallaway - Add CLI version command (#1186)
|
||||
* John Dallaway - Add CLI address size command (#1191)
|
||||
*******************************************************************************/
|
||||
|
||||
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.mi.service.IMIContainerDMContext;
|
||||
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.CLIAttach;
|
||||
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.MIVarShowFormat;
|
||||
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.CLICatchInfo;
|
||||
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 {
|
||||
|
||||
/** @since 7.2 */
|
||||
public ICommand<CLIAddressSizeInfo> createCLIAddressSize(IMemoryDMContext ctx) {
|
||||
return new CLIAddressSize(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -10,10 +10,16 @@
|
|||
*
|
||||
* Contributors:
|
||||
* 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;
|
||||
|
||||
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
|
||||
* <br>"p/x (char)-1"
|
||||
|
@ -26,6 +32,8 @@ package org.eclipse.cdt.dsf.mi.service.command.output;
|
|||
*/
|
||||
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;
|
||||
|
||||
public CLIAddressableSizeInfo(MIOutput record) {
|
||||
|
@ -51,13 +59,13 @@ public class CLIAddressableSizeInfo extends MIInfo {
|
|||
|
||||
private int hexToOctetCount(String hexString) {
|
||||
// Receiving format is expected in hex form e.g. "$n = 0xffff" or "$n = 0xff"
|
||||
//which shall result in 2 and 1 octets respectively
|
||||
int starts = hexString.indexOf("x"); //$NON-NLS-1$
|
||||
assert (starts > 0);
|
||||
String hexDigits = hexString.substring(starts + 1);
|
||||
assert hexDigits.length() > 1;
|
||||
int octets = hexDigits.length() / 2;
|
||||
|
||||
return octets;
|
||||
// which shall result in 2 and 1 octets respectively.
|
||||
// Also accommodate "(char) 0xff -1 '\\xff'\n" returned by LLDB-MI.
|
||||
Matcher matcher = HEX_DIGITS_PATTERN.matcher(hexString);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1).length() / 2;
|
||||
}
|
||||
ILog.get().error("CLIAddressableSizeInfo response not handled: " + hexString); //$NON-NLS-1$
|
||||
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
|
||||
* 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/
|
||||
*
|
||||
* 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;
|
||||
|
||||
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.IRunControl;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
|
||||
|
@ -56,4 +61,10 @@ public class LLDBServiceFactory extends GdbDebugServicesFactory {
|
|||
protected IProcesses createProcessesService(DsfSession session) {
|
||||
return new LLDBProcesses(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IMemory createMemoryService(DsfSession session) {
|
||||
return new LLDBMemory(session);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue