mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-2177: schema fix for missing registers
GP-2177(SQRB): fire threadCreated GP-2177_SQRB: spare the VM on E_NOINTERFACE GP-2177_SQRB: check id plus pid/tid GP-2177_SQRB: init for dbgmodel RegisterBanks plus bandaid for recorder GP-2177_SQRB: filter nulls from traceToTarget GP-2177: extraneous cleanup GP-2177: clear bpts on process death GP-2968: fixes from review GP-2177: not directly related, but... GP-2177: CACHE needs to be cleared and must follow actual native delete GP-2177: first pass at bpt errors
This commit is contained in:
parent
ba0b42dc82
commit
dee3de5672
19 changed files with 171 additions and 57 deletions
|
@ -132,4 +132,6 @@ public interface DebugBreakpoint {
|
||||||
void setDataParameters(int size, BitmaskSet<BreakAccess> access);
|
void setDataParameters(int size, BitmaskSet<BreakAccess> access);
|
||||||
|
|
||||||
void setDataParameters(int size, BreakAccess... access);
|
void setDataParameters(int size, BreakAccess... access);
|
||||||
|
|
||||||
|
void dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,14 @@ public class DebugBreakpointImpl1 implements DebugBreakpointInternal {
|
||||||
@Override
|
@Override
|
||||||
public void remove() {
|
public void remove() {
|
||||||
control.removeBreakpoint(jnaBreakpoint);
|
control.removeBreakpoint(jnaBreakpoint);
|
||||||
|
// If we do this here, dispose will fail
|
||||||
|
//jnaBreakpoint = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
// Prevent accidental access. Will be released during GC. NPE is better than segfault.
|
// Prevent accidental access. Will be released during GC. NPE is better than segfault.
|
||||||
|
CACHE.remove(jnaBreakpoint.getPointer());
|
||||||
jnaBreakpoint = null;
|
jnaBreakpoint = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,4 +191,5 @@ public class DebugBreakpointImpl1 implements DebugBreakpointInternal {
|
||||||
public void setDataParameters(int size, BreakAccess... access) {
|
public void setDataParameters(int size, BreakAccess... access) {
|
||||||
setDataParameters(size, BitmaskSet.of(access));
|
setDataParameters(size, BitmaskSet.of(access));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,20 @@ import com.sun.jna.platform.win32.COM.COMUtils;
|
||||||
import agent.dbgeng.jna.dbgeng.breakpoint.IDebugBreakpoint2;
|
import agent.dbgeng.jna.dbgeng.breakpoint.IDebugBreakpoint2;
|
||||||
|
|
||||||
public class DebugBreakpointImpl2 extends DebugBreakpointImpl1 {
|
public class DebugBreakpointImpl2 extends DebugBreakpointImpl1 {
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final IDebugBreakpoint2 jnaBreakpoint;
|
private IDebugBreakpoint2 jnaBreakpoint;
|
||||||
|
|
||||||
public DebugBreakpointImpl2(IDebugBreakpoint2 jnaBreakpoint) {
|
public DebugBreakpointImpl2(IDebugBreakpoint2 jnaBreakpoint) {
|
||||||
super(jnaBreakpoint);
|
super(jnaBreakpoint);
|
||||||
this.jnaBreakpoint = jnaBreakpoint;
|
this.jnaBreakpoint = jnaBreakpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
jnaBreakpoint = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getOffsetExpression() {
|
public String getOffsetExpression() {
|
||||||
ULONGByReference pulExpressionSize = new ULONGByReference();
|
ULONGByReference pulExpressionSize = new ULONGByReference();
|
||||||
|
|
|
@ -19,10 +19,16 @@ import agent.dbgeng.jna.dbgeng.breakpoint.IDebugBreakpoint3;
|
||||||
|
|
||||||
public class DebugBreakpointImpl3 extends DebugBreakpointImpl2 {
|
public class DebugBreakpointImpl3 extends DebugBreakpointImpl2 {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private final IDebugBreakpoint3 jnaBreakpoint;
|
private IDebugBreakpoint3 jnaBreakpoint;
|
||||||
|
|
||||||
public DebugBreakpointImpl3(IDebugBreakpoint3 jnaBreakpoint) {
|
public DebugBreakpointImpl3(IDebugBreakpoint3 jnaBreakpoint) {
|
||||||
super(jnaBreakpoint);
|
super(jnaBreakpoint);
|
||||||
this.jnaBreakpoint = jnaBreakpoint;
|
this.jnaBreakpoint = jnaBreakpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
jnaBreakpoint = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,9 @@ public class DebugDataSpacesImpl2 extends DebugDataSpacesImpl1 {
|
||||||
if (hr.equals(COMUtilsExtra.E_NOTIMPLEMENTED)) {
|
if (hr.equals(COMUtilsExtra.E_NOTIMPLEMENTED)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (hr.equals(COMUtilsExtra.E_NOINTERFACE)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
COMUtils.checkRC(hr);
|
COMUtils.checkRC(hr);
|
||||||
|
|
||||||
return new DebugMemoryBasicInformation(pInfo.BaseAddress.longValue(),
|
return new DebugMemoryBasicInformation(pInfo.BaseAddress.longValue(),
|
||||||
|
|
|
@ -19,12 +19,11 @@ import com.sun.jna.Pointer;
|
||||||
import com.sun.jna.platform.win32.Guid.IID;
|
import com.sun.jna.platform.win32.Guid.IID;
|
||||||
import com.sun.jna.platform.win32.WinDef.*;
|
import com.sun.jna.platform.win32.WinDef.*;
|
||||||
import com.sun.jna.platform.win32.WinNT.HRESULT;
|
import com.sun.jna.platform.win32.WinNT.HRESULT;
|
||||||
|
import com.sun.jna.platform.win32.COM.IUnknown;
|
||||||
|
|
||||||
import agent.dbgeng.jna.dbgeng.DbgEngNative.DEBUG_BREAKPOINT_PARAMETERS;
|
import agent.dbgeng.jna.dbgeng.DbgEngNative.DEBUG_BREAKPOINT_PARAMETERS;
|
||||||
import agent.dbgeng.jna.dbgeng.UnknownWithUtils.VTableIndex;
|
import agent.dbgeng.jna.dbgeng.UnknownWithUtils.VTableIndex;
|
||||||
|
|
||||||
import com.sun.jna.platform.win32.COM.IUnknown;
|
|
||||||
|
|
||||||
public interface IDebugBreakpoint extends IUnknown {
|
public interface IDebugBreakpoint extends IUnknown {
|
||||||
final IID IID_IDEBUG_BREAKPOINT = new IID("5bd9d474-5975-423a-b88b-65a8e7110e65");
|
final IID IID_IDEBUG_BREAKPOINT = new IID("5bd9d474-5975-423a-b88b-65a8e7110e65");
|
||||||
|
|
||||||
|
@ -101,4 +100,6 @@ public interface IDebugBreakpoint extends IUnknown {
|
||||||
HRESULT SetOffsetExpression(String Expression);
|
HRESULT SetOffsetExpression(String Expression);
|
||||||
|
|
||||||
HRESULT GetParameters(DEBUG_BREAKPOINT_PARAMETERS.ByReference Params);
|
HRESULT GetParameters(DEBUG_BREAKPOINT_PARAMETERS.ByReference Params);
|
||||||
|
|
||||||
|
Pointer getPointer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -299,7 +299,12 @@ public class DbgBreakpointInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public long getAddressAsLong() {
|
public void remove() {
|
||||||
return locations.get(0).addrAsLong();
|
bpt.remove();
|
||||||
}*/ // getOffset instead
|
}
|
||||||
|
|
||||||
|
public void dispose() {
|
||||||
|
bpt.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ package agent.dbgeng.manager.cmd;
|
||||||
|
|
||||||
import agent.dbgeng.dbgeng.DebugBreakpoint;
|
import agent.dbgeng.dbgeng.DebugBreakpoint;
|
||||||
import agent.dbgeng.dbgeng.DebugControl;
|
import agent.dbgeng.dbgeng.DebugControl;
|
||||||
import agent.dbgeng.manager.DbgCause;
|
|
||||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,9 +35,10 @@ public class DbgDeleteBreakpointsCommand extends AbstractDbgCommand<Void> {
|
||||||
public void invoke() {
|
public void invoke() {
|
||||||
DebugControl control = manager.getControl();
|
DebugControl control = manager.getControl();
|
||||||
for (long id : numbers) {
|
for (long id : numbers) {
|
||||||
manager.doBreakpointDeleted(id, DbgCause.Causes.UNCLAIMED);
|
|
||||||
DebugBreakpoint bp = control.getBreakpointById((int) id);
|
DebugBreakpoint bp = control.getBreakpointById((int) id);
|
||||||
bp.remove();
|
if (bp != null) {
|
||||||
|
bp.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,15 +144,19 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
public DbgThreadImpl getThreadComputeIfAbsent(DebugThreadId id, DbgProcessImpl process,
|
public DbgThreadImpl getThreadComputeIfAbsent(DebugThreadId id, DbgProcessImpl process,
|
||||||
int tid, boolean fire) {
|
int tid, boolean fire) {
|
||||||
synchronized (threads) {
|
synchronized (threads) {
|
||||||
if (!threads.containsKey(id)) {
|
if (threads.containsKey(id)) {
|
||||||
DbgThreadImpl thread = new DbgThreadImpl(this, process, id, tid);
|
DbgThreadImpl existingThread = threads.get(id);
|
||||||
thread.add();
|
if (existingThread.getTid() == tid) {
|
||||||
if (fire) {
|
return existingThread;
|
||||||
Causes cause = DbgCause.Causes.UNCLAIMED;
|
|
||||||
getEventListeners().fire.threadCreated(thread, cause);
|
|
||||||
getEventListeners().fire.threadSelected(thread, null, cause);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DbgThreadImpl thread = new DbgThreadImpl(this, process, id, tid);
|
||||||
|
thread.add();
|
||||||
|
if (fire) {
|
||||||
|
Causes cause = DbgCause.Causes.UNCLAIMED;
|
||||||
|
getEventListeners().fire.threadCreated(thread, cause);
|
||||||
|
getEventListeners().fire.threadSelected(thread, null, cause);
|
||||||
|
}
|
||||||
return threads.get(id);
|
return threads.get(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,13 +222,17 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
|
|
||||||
public DbgProcessImpl getProcessComputeIfAbsent(DebugProcessId id, int pid, boolean fire) {
|
public DbgProcessImpl getProcessComputeIfAbsent(DebugProcessId id, int pid, boolean fire) {
|
||||||
synchronized (processes) {
|
synchronized (processes) {
|
||||||
if (!processes.containsKey(id)) {
|
if (processes.containsKey(id)) {
|
||||||
DbgProcessImpl process = new DbgProcessImpl(this, id, pid);
|
DbgProcessImpl existingProc = processes.get(id);
|
||||||
process.add();
|
if (existingProc.getPid() == pid) {
|
||||||
if (fire) {
|
return existingProc;
|
||||||
getEventListeners().fire.processAdded(process, DbgCause.Causes.UNCLAIMED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DbgProcessImpl process = new DbgProcessImpl(this, id, pid);
|
||||||
|
process.add();
|
||||||
|
if (fire) {
|
||||||
|
getEventListeners().fire.processAdded(process, DbgCause.Causes.UNCLAIMED);
|
||||||
|
}
|
||||||
return processes.get(id);
|
return processes.get(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -730,7 +738,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
int tid = so.getCurrentThreadSystemId();
|
int tid = so.getCurrentThreadSystemId();
|
||||||
DbgThreadImpl thread = getThreadComputeIfAbsent(eventId, process, tid, true);
|
DbgThreadImpl thread = getThreadComputeIfAbsent(eventId, process, tid, true);
|
||||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||||
//getEventListeners().fire.threadCreated(thread, DbgCause.Causes.UNCLAIMED);
|
getEventListeners().fire.threadCreated(thread, DbgCause.Causes.UNCLAIMED);
|
||||||
getEventListeners().fire.threadSelected(thread, null, evt.getCause());
|
getEventListeners().fire.threadSelected(thread, null, evt.getCause());
|
||||||
|
|
||||||
String key = Integer.toHexString(eventId.id);
|
String key = Integer.toHexString(eventId.id);
|
||||||
|
@ -1105,6 +1113,11 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
long bptId = evt.getId();
|
long bptId = evt.getId();
|
||||||
if (bptId == DbgEngUtil.DEBUG_ANY_ID.longValue()) {
|
if (bptId == DbgEngUtil.DEBUG_ANY_ID.longValue()) {
|
||||||
changeBreakpoints();
|
changeBreakpoints();
|
||||||
|
for (DbgBreakpointInfo bptInfo : breakpoints.values()) {
|
||||||
|
if (bptInfo.getProc().equals(currentProcess)) {
|
||||||
|
doBreakpointDeleted(bptInfo.getNumber(), evt.getCause());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DebugBreakpoint bpt = getControl().getBreakpointById((int) bptId);
|
DebugBreakpoint bpt = getControl().getBreakpointById((int) bptId);
|
||||||
|
@ -1112,17 +1125,27 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
doBreakpointDeleted(bptId, evt.getCause());
|
doBreakpointDeleted(bptId, evt.getCause());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DbgBreakpointInfo knownBreakpoint = getKnownBreakpoint(bptId);
|
DbgBreakpointInfo knownBreakpoint = breakpoints.get(bptId);
|
||||||
if (knownBreakpoint == null) {
|
if (knownBreakpoint == null) {
|
||||||
breakpointInfo = new DbgBreakpointInfo(bpt, getCurrentProcess());
|
breakpointInfo = new DbgBreakpointInfo(bpt, getCurrentProcess());
|
||||||
if (breakpointInfo.getOffset() != null) {
|
if (breakpointInfo.getOffset() != null) {
|
||||||
doBreakpointCreated(breakpointInfo, evt.getCause());
|
addKnownBreakpoint(breakpointInfo, false);
|
||||||
|
// NB: we don't want to create this here as the address is 0s
|
||||||
|
//doBreakpointCreated(breakpointInfo, evt.getCause());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
breakpointInfo = knownBreakpoint;
|
breakpointInfo = knownBreakpoint;
|
||||||
|
Long initOffset = breakpointInfo.getOffset();
|
||||||
breakpointInfo.setBreakpoint(bpt);
|
breakpointInfo.setBreakpoint(bpt);
|
||||||
doBreakpointModified(breakpointInfo, evt.getCause());
|
if (!breakpointInfo.getOffset().equals(0L)) {
|
||||||
|
if (initOffset.equals(0L)) {
|
||||||
|
doBreakpointCreated(breakpointInfo, evt.getCause());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
doBreakpointModified(breakpointInfo, evt.getCause());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1145,7 +1168,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
*/
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
public void doBreakpointCreated(DbgBreakpointInfo newInfo, DbgCause cause) {
|
public void doBreakpointCreated(DbgBreakpointInfo newInfo, DbgCause cause) {
|
||||||
addKnownBreakpoint(newInfo, false);
|
addKnownBreakpoint(newInfo, true);
|
||||||
getEventListeners().fire.breakpointCreated(newInfo, cause);
|
getEventListeners().fire.breakpointCreated(newInfo, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1174,6 +1197,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getEventListeners().fire.breakpointDeleted(oldInfo, cause);
|
getEventListeners().fire.breakpointDeleted(oldInfo, cause);
|
||||||
|
oldInfo.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doBreakpointModifiedSameLocations(DbgBreakpointInfo newInfo,
|
protected void doBreakpointModifiedSameLocations(DbgBreakpointInfo newInfo,
|
||||||
|
|
|
@ -59,16 +59,22 @@ public interface DbgModelTargetBreakpointSpec extends //
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public default String getExpression() {
|
public default String getExpression() {
|
||||||
return getBreakpointInfo().getExpression();
|
DbgBreakpointInfo info = getBreakpointInfo();
|
||||||
|
return info == null ? null : info.getExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
public default long getNumber() {
|
public default long getNumber() {
|
||||||
return getBreakpointInfo().getNumber();
|
DbgBreakpointInfo info = getBreakpointInfo();
|
||||||
|
return info == null ? null : info.getNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public default TargetBreakpointKindSet getKinds() {
|
public default TargetBreakpointKindSet getKinds() {
|
||||||
switch (getBreakpointInfo().getType()) {
|
DbgBreakpointInfo info = getBreakpointInfo();
|
||||||
|
if (info == null) {
|
||||||
|
return TargetBreakpointKindSet.of();
|
||||||
|
}
|
||||||
|
switch (info.getType()) {
|
||||||
case BREAKPOINT:
|
case BREAKPOINT:
|
||||||
return TargetBreakpointKindSet.of(TargetBreakpointKind.SW_EXECUTE);
|
return TargetBreakpointKindSet.of(TargetBreakpointKind.SW_EXECUTE);
|
||||||
case HW_BREAKPOINT:
|
case HW_BREAKPOINT:
|
||||||
|
|
|
@ -23,8 +23,10 @@ import com.sun.jna.platform.win32.OleAuto;
|
||||||
import com.sun.jna.platform.win32.WTypes.BSTR;
|
import com.sun.jna.platform.win32.WTypes.BSTR;
|
||||||
import com.sun.jna.platform.win32.WTypes.BSTRByReference;
|
import com.sun.jna.platform.win32.WTypes.BSTRByReference;
|
||||||
import com.sun.jna.platform.win32.WinDef.*;
|
import com.sun.jna.platform.win32.WinDef.*;
|
||||||
|
import com.sun.jna.platform.win32.WinNT.HRESULT;
|
||||||
import com.sun.jna.platform.win32.COM.COMUtils;
|
import com.sun.jna.platform.win32.COM.COMUtils;
|
||||||
|
|
||||||
|
import agent.dbgeng.dbgeng.COMUtilsExtra;
|
||||||
import agent.dbgmodel.dbgmodel.DbgModel;
|
import agent.dbgmodel.dbgmodel.DbgModel;
|
||||||
import agent.dbgmodel.dbgmodel.DbgModel.OpaqueCleanable;
|
import agent.dbgmodel.dbgmodel.DbgModel.OpaqueCleanable;
|
||||||
import agent.dbgmodel.dbgmodel.debughost.DebugHostContext;
|
import agent.dbgmodel.dbgmodel.debughost.DebugHostContext;
|
||||||
|
@ -55,8 +57,11 @@ public class DebugHostMemoryImpl1 implements DebugHostMemoryInternal {
|
||||||
Pointer pContext = context.getPointer();
|
Pointer pContext = context.getPointer();
|
||||||
ULONGLONG pulBufferSize = new ULONGLONG(bufferSize);
|
ULONGLONG pulBufferSize = new ULONGLONG(bufferSize);
|
||||||
ULONGLONGByReference pulBytesRead = new ULONGLONGByReference();
|
ULONGLONGByReference pulBytesRead = new ULONGLONGByReference();
|
||||||
COMUtils.checkRC(
|
HRESULT hr = jnaData.ReadBytes(pContext, location, buffer, pulBufferSize, pulBytesRead);
|
||||||
jnaData.ReadBytes(pContext, location, buffer, pulBufferSize, pulBytesRead));
|
if (hr.equals(COMUtilsExtra.E_NOTIMPLEMENTED)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
COMUtils.checkRC(hr);
|
||||||
long read = pulBytesRead.getValue().longValue();
|
long read = pulBytesRead.getValue().longValue();
|
||||||
buffer.position((int) (read + buffer.position()));
|
buffer.position((int) (read + buffer.position()));
|
||||||
return read;
|
return read;
|
||||||
|
|
|
@ -156,6 +156,10 @@ public class ModelObjectImpl implements ModelObjectInternal {
|
||||||
Msg.debug(this, searchKey + " cannot be read");
|
Msg.debug(this, searchKey + " cannot be read");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (hr.equals(COMUtilsExtra.E_NOINTERFACE)) {
|
||||||
|
Msg.debug(this, searchKey + " missing interface");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
COMUtils.checkRC(hr);
|
COMUtils.checkRC(hr);
|
||||||
|
|
||||||
ModelObject retval = getObjectWithMetadata(ppObject, ppMetadata);
|
ModelObject retval = getObjectWithMetadata(ppObject, ppMetadata);
|
||||||
|
|
|
@ -249,15 +249,9 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
||||||
}
|
}
|
||||||
if (proxy instanceof TargetExecutionStateful) {
|
if (proxy instanceof TargetExecutionStateful) {
|
||||||
if (isValid()) {
|
if (isValid()) {
|
||||||
if (attributes.containsKey(TargetExecutionStateful.STATE_ATTRIBUTE_NAME)) {
|
TargetExecutionStateful stateful = (TargetExecutionStateful) proxy;
|
||||||
TargetExecutionStateful stateful = (TargetExecutionStateful) proxy;
|
TargetExecutionState state = stateful.getExecutionState();
|
||||||
TargetExecutionState state = stateful.getExecutionState();
|
attrs.put(TargetExecutionStateful.STATE_ATTRIBUTE_NAME, state);
|
||||||
attrs.put(TargetExecutionStateful.STATE_ATTRIBUTE_NAME, state);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
attrs.put(TargetExecutionStateful.STATE_ATTRIBUTE_NAME,
|
|
||||||
TargetExecutionState.INACTIVE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (proxy instanceof TargetAttacher) {
|
if (proxy instanceof TargetAttacher) {
|
||||||
|
|
|
@ -285,8 +285,9 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
||||||
List<String> xpath = new ArrayList<>();
|
List<String> xpath = new ArrayList<>();
|
||||||
xpath.addAll(objPath);
|
xpath.addAll(objPath);
|
||||||
xpath.addAll(ext);
|
xpath.addAll(ext);
|
||||||
|
// NB: fetchModelObject may have to be called with false
|
||||||
return AsyncUtils.sequence(TypeSpec.cls(DbgModelTargetObject.class)).then(seq -> {
|
return AsyncUtils.sequence(TypeSpec.cls(DbgModelTargetObject.class)).then(seq -> {
|
||||||
getModel().fetchModelObject(xpath).handle(seq::next);
|
getModel().fetchModelObject(xpath, false).handle(seq::next);
|
||||||
}, TypeSpec.cls(TargetObject.class)).then((pobj, seq) -> {
|
}, TypeSpec.cls(TargetObject.class)).then((pobj, seq) -> {
|
||||||
if (pobj == null) {
|
if (pobj == null) {
|
||||||
seq.exit();
|
seq.exit();
|
||||||
|
|
|
@ -263,7 +263,14 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (proxy instanceof TargetExecutionStateful) {
|
if (proxy instanceof TargetExecutionStateful) {
|
||||||
setExecutionState(exec, "Refreshed");
|
if (proxy instanceof DbgModelTargetSession) {
|
||||||
|
if (state != DbgState.EXIT) {
|
||||||
|
setExecutionState(exec, "Refreshed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setExecutionState(exec, "Refreshed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,6 +313,7 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (proxy instanceof DbgModelTargetRegisterContainer || //
|
if (proxy instanceof DbgModelTargetRegisterContainer || //
|
||||||
|
proxy instanceof DbgModelTargetRegisterBank || //
|
||||||
proxy.getName().equals("Stack") ||
|
proxy.getName().equals("Stack") ||
|
||||||
proxy.getName().equals("Debug")) {
|
proxy.getName().equals("Debug")) {
|
||||||
requestAttributes(false);
|
requestAttributes(false);
|
||||||
|
@ -403,9 +411,11 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
||||||
List<DelegateDbgModel2TargetObject> delegates = new ArrayList<>();
|
List<DelegateDbgModel2TargetObject> delegates = new ArrayList<>();
|
||||||
TargetObject stack =
|
TargetObject stack =
|
||||||
(TargetObject) getCachedAttribute("Stack");
|
(TargetObject) getCachedAttribute("Stack");
|
||||||
DbgModelTargetStack frames =
|
if (stack != null) {
|
||||||
(DbgModelTargetStack) stack.getCachedAttribute("Frames");
|
DbgModelTargetStack frames =
|
||||||
delegates.add((DelegateDbgModel2TargetObject) frames.getDelegate());
|
(DbgModelTargetStack) stack.getCachedAttribute("Frames");
|
||||||
|
delegates.add((DelegateDbgModel2TargetObject) frames.getDelegate());
|
||||||
|
}
|
||||||
DbgModelTargetRegisterContainer container =
|
DbgModelTargetRegisterContainer container =
|
||||||
(DbgModelTargetRegisterContainer) getCachedAttribute("Registers");
|
(DbgModelTargetRegisterContainer) getCachedAttribute("Registers");
|
||||||
delegates.add((DelegateDbgModel2TargetObject) container.getDelegate());
|
delegates.add((DelegateDbgModel2TargetObject) container.getDelegate());
|
||||||
|
|
|
@ -454,6 +454,7 @@
|
||||||
<attribute name="rdi" schema="RegisterDescriptor" required="yes" />
|
<attribute name="rdi" schema="RegisterDescriptor" required="yes" />
|
||||||
<attribute name="rsi" schema="RegisterDescriptor" required="yes" />
|
<attribute name="rsi" schema="RegisterDescriptor" required="yes" />
|
||||||
<attribute name="rip" schema="RegisterDescriptor" required="yes" />
|
<attribute name="rip" schema="RegisterDescriptor" required="yes" />
|
||||||
|
<attribute name="rbp" schema="RegisterDescriptor" required="yes" />
|
||||||
<attribute name="rsp" schema="RegisterDescriptor" required="yes" />
|
<attribute name="rsp" schema="RegisterDescriptor" required="yes" />
|
||||||
<attribute name="r8" schema="RegisterDescriptor" required="yes" />
|
<attribute name="r8" schema="RegisterDescriptor" required="yes" />
|
||||||
<attribute name="r9" schema="RegisterDescriptor" required="yes" />
|
<attribute name="r9" schema="RegisterDescriptor" required="yes" />
|
||||||
|
@ -464,6 +465,31 @@
|
||||||
<attribute name="r14" schema="RegisterDescriptor" required="yes" />
|
<attribute name="r14" schema="RegisterDescriptor" required="yes" />
|
||||||
<attribute name="r15" schema="RegisterDescriptor" required="yes" />
|
<attribute name="r15" schema="RegisterDescriptor" required="yes" />
|
||||||
<attribute name="efl" schema="RegisterDescriptor" required="yes" />
|
<attribute name="efl" schema="RegisterDescriptor" required="yes" />
|
||||||
|
<attribute name="dr0" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="dr1" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="dr2" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="dr3" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="dr6" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="dr7" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="cs" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="ds" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="es" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="fs" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="gs" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="ss" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="af" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="cf" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="df" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="if" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="of" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="pf" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="sf" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="tf" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="zf" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="iopl" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="vif" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="vip" schema="RegisterDescriptor" required="no" />
|
||||||
|
<attribute name="rflags" schema="RegisterDescriptor" required="no" />
|
||||||
<attribute schema="OBJECT" />
|
<attribute schema="OBJECT" />
|
||||||
</schema>
|
</schema>
|
||||||
<schema name="Stack" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
|
<schema name="Stack" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
|
||||||
|
|
|
@ -52,6 +52,8 @@ public class DebuggerPlaceBreakpointDialog extends DialogComponentProvider {
|
||||||
private JTextField fieldLength;
|
private JTextField fieldLength;
|
||||||
private JComboBox<String> fieldKinds;
|
private JComboBox<String> fieldKinds;
|
||||||
private JTextField fieldName;
|
private JTextField fieldName;
|
||||||
|
private PluginTool tool;
|
||||||
|
private String statusText = null;
|
||||||
|
|
||||||
public DebuggerPlaceBreakpointDialog() {
|
public DebuggerPlaceBreakpointDialog() {
|
||||||
super(AbstractSetBreakpointAction.NAME, true, true, true, false);
|
super(AbstractSetBreakpointAction.NAME, true, true, true, false);
|
||||||
|
@ -150,10 +152,12 @@ public class DebuggerPlaceBreakpointDialog extends DialogComponentProvider {
|
||||||
this.fieldLength.setText(Long.toUnsignedString(length));
|
this.fieldLength.setText(Long.toUnsignedString(length));
|
||||||
this.fieldKinds.setSelectedItem(TraceBreakpointKindSet.encode(kinds));
|
this.fieldKinds.setSelectedItem(TraceBreakpointKindSet.encode(kinds));
|
||||||
this.fieldName.setText("");
|
this.fieldName.setText("");
|
||||||
|
this.tool = tool;
|
||||||
|
|
||||||
validateAddress();
|
validateAddress();
|
||||||
|
|
||||||
setTitle(title);
|
setTitle(title);
|
||||||
|
statusText = null;
|
||||||
tool.showDialog(this);
|
tool.showDialog(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,13 +185,20 @@ public class DebuggerPlaceBreakpointDialog extends DialogComponentProvider {
|
||||||
name = fieldName.getText();
|
name = fieldName.getText();
|
||||||
|
|
||||||
ProgramLocation loc = new ProgramLocation(program, address);
|
ProgramLocation loc = new ProgramLocation(program, address);
|
||||||
service.placeBreakpointAt(loc, length, kinds, name).thenAccept(__ -> {
|
service.placeBreakpointAt(loc, length, kinds, name).exceptionally(ex -> {
|
||||||
close();
|
|
||||||
}).exceptionally(ex -> {
|
|
||||||
ex = AsyncUtils.unwrapThrowable(ex);
|
ex = AsyncUtils.unwrapThrowable(ex);
|
||||||
setStatusText(ex.getMessage(), MessageType.ERROR, true);
|
statusText = ex.getMessage(); // will be set when dialog is shown later
|
||||||
|
tool.showDialog(this);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void dialogShown() {
|
||||||
|
if (statusText != null) {
|
||||||
|
setStatusText(statusText, MessageType.ERROR, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* testing */
|
/* testing */
|
||||||
|
|
|
@ -164,15 +164,17 @@ public class DefaultThreadRecorder implements ManagedThreadRecorder {
|
||||||
if (regMapper == null) {
|
if (regMapper == null) {
|
||||||
throw new IllegalStateException("Have not found register descriptions for " + thread);
|
throw new IllegalStateException("Have not found register descriptions for " + thread);
|
||||||
}
|
}
|
||||||
if (!regMapper.getRegistersOnTarget().containsAll(registers)) {
|
List<TargetRegister> tRegs = registers.stream()
|
||||||
throw new IllegalArgumentException(
|
.map(regMapper::traceToTarget)
|
||||||
"All given registers must be recognized by the target");
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (tRegs.size() < registers.size()) {
|
||||||
|
Msg.warn(this,
|
||||||
|
"All requested registers must be recognized by the model as registers");
|
||||||
}
|
}
|
||||||
if (registers.isEmpty()) {
|
if (registers.isEmpty()) {
|
||||||
return CompletableFuture.completedFuture(Map.of());
|
return CompletableFuture.completedFuture(Map.of());
|
||||||
}
|
}
|
||||||
List<TargetRegister> tRegs =
|
|
||||||
registers.stream().map(regMapper::traceToTarget).collect(Collectors.toList());
|
|
||||||
|
|
||||||
Set<TargetRegisterBank> banks = getTargetRegisterBank(thread, frameLevel);
|
Set<TargetRegisterBank> banks = getTargetRegisterBank(thread, frameLevel);
|
||||||
if (banks == null) {
|
if (banks == null) {
|
||||||
|
|
|
@ -416,7 +416,7 @@ public class MarkerManager implements MarkerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color getBackgroundColor(Program program, MarkerSetCacheEntry entry, Address address) {
|
private Color getBackgroundColor(Program program, MarkerSetCacheEntry entry, Address address) {
|
||||||
return entry.getBackgroundColor(address);
|
return entry == null ? null : entry.getBackgroundColor(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GoToService getGoToService() {
|
public GoToService getGoToService() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue