1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-03 14:25:37 +02:00

[309234] DSF not as helpful as CDI on SEGV

This commit is contained in:
John Cortell 2010-04-19 12:47:48 +00:00
parent 959e7d3658
commit f8d7eee520
7 changed files with 161 additions and 23 deletions

View file

@ -76,7 +76,9 @@ public class ThreadVMNode extends AbstractThreadVMNode
IGdbLaunchVMConstants.PROP_OS_ID,
ILaunchVMConstants.PROP_IS_SUSPENDED,
ExecutionContextLabelText.PROP_STATE_CHANGE_REASON_KNOWN,
ILaunchVMConstants.PROP_STATE_CHANGE_REASON }),
ILaunchVMConstants.PROP_STATE_CHANGE_REASON,
ExecutionContextLabelText.PROP_STATE_CHANGE_DETAILS_KNOWN,
ILaunchVMConstants.PROP_STATE_CHANGE_DETAILS}),
new LabelText(MessagesForGdbLaunchVM.ThreadVMNode_No_columns__Error__label, new String[0]),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_THREAD_RUNNING)) {
{ setPropertyNames(new String[] { ILaunchVMConstants.PROP_IS_SUSPENDED }); }

View file

@ -18,7 +18,9 @@
# {6} - 0=running/1=suspended
# {7} - state change reason available, 0=not available/1=available
# {8} - state change reason
ThreadVMNode_No_columns__text_format={0,choice,0#Thread|1#{1}}{2,choice,0#|1# [{3}]}{4,choice,0#|1# {5}} ({6,choice,0#Running|1#Suspended}{7,choice,0#|1# : {8}})
# {9} - state change details available, 0=not available/1=available
# {10}- state change details
ThreadVMNode_No_columns__text_format={0,choice,0#Thread|1#{1}}{2,choice,0#|1# [{3}]}{4,choice,0#|1# {5}} ({6,choice,0#Running|1#Suspended}{7,choice,0#|1# : {8}}{9,choice,0#|1# : {10}})
ThreadVMNode_No_columns__Error__label=<unavailable>

View file

@ -93,12 +93,16 @@ import org.osgi.framework.BundleContext;
public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunControl, ICachingService
{
@Immutable
private static class ExecutionData implements IExecutionDMData {
private static class ExecutionData implements IExecutionDMData2 {
private final StateChangeReason fReason;
ExecutionData(StateChangeReason reason) {
private final String fDetails;
ExecutionData(StateChangeReason reason, String details) {
fReason = reason;
fDetails = details;
}
public StateChangeReason getStateChangeReason() { return fReason; }
public String getDetails() { return fDetails; }
}
/**
@ -153,6 +157,23 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
return StateChangeReason.USER_REQUEST;
}
}
public String getDetails() {
MIStoppedEvent event = getMIEvent();
if (event instanceof MICatchpointHitEvent) { // must precede MIBreakpointHitEvent
return ((MICatchpointHitEvent)event).getReason();
} else if (event instanceof MISharedLibEvent) {
return ((MISharedLibEvent)event).getLibrary();
} else if (event instanceof MISignalEvent) {
return ((MISignalEvent)event).getName() + ':' + ((MISignalEvent)event).getMeaning();
} else if (event instanceof MIWatchpointTriggerEvent) {
return ((MIWatchpointTriggerEvent)event).getExpression();
} else if (event instanceof MIErrorEvent) {
return ((MIErrorEvent)event).getMessage();
}
return null;
}
}
/**
@ -227,7 +248,19 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
boolean fSuspended = false;
boolean fResumePending = false;
boolean fStepping = false;
/**
* What caused the state change. E.g., a signal was thrown.
*/
StateChangeReason fStateChangeReason;
/**
* Further detail on what caused the state change. E.g., the specific signal
* that was throw was a SIGINT. The exact string comes from gdb in the mi
* event. May be null, as not all types of state change have additional
* detail of interest.
*/
String fStateChangeDetails;
}
private static class RunToLineActiveOperation {
@ -783,7 +816,7 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
}
if (dmc instanceof IMIExecutionDMContext) {
rm.setData(new ExecutionData(threadState.fSuspended ? threadState.fStateChangeReason : null));
rm.setData(new ExecutionData(threadState.fSuspended ? threadState.fStateChangeReason : null, threadState.fStateChangeDetails));
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE,
"Given context: " + dmc + " is not a recognized execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
@ -817,6 +850,7 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
threadState.fSuspended = false;
threadState.fResumePending = false;
threadState.fStateChangeReason = reason;
threadState.fStateChangeDetails = null; // we have no details of interest for a resume
threadState.fStepping = isStepping;
}
@ -831,6 +865,7 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
threadState.fResumePending = false;
threadState.fStepping = false;
threadState.fStateChangeReason = reason;
threadState.fStateChangeDetails = event.getDetails();
}

View file

@ -130,12 +130,15 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
}
@Immutable
private static class ExecutionData implements IExecutionDMData {
private static class ExecutionData implements IExecutionDMData2 {
private final StateChangeReason fReason;
ExecutionData(StateChangeReason reason) {
private final String fDetails;
ExecutionData(StateChangeReason reason, String details) {
fReason = reason;
fDetails = details;
}
public StateChangeReason getStateChangeReason() { return fReason; }
public String getDetails() { return fDetails; }
}
/**
@ -190,6 +193,26 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
return StateChangeReason.USER_REQUEST;
}
}
/**
* @since 3.0
*/
public String getDetails() {
MIStoppedEvent event = getMIEvent();
if (event instanceof MICatchpointHitEvent) { // must precede MIBreakpointHitEvent
return ((MICatchpointHitEvent)event).getReason();
} else if (event instanceof MISharedLibEvent) {
return ((MISharedLibEvent)event).getLibrary();
} else if (event instanceof MISignalEvent) {
return ((MISignalEvent)event).getName() + ':' + ((MISignalEvent)event).getMeaning();
} else if (event instanceof MIWatchpointTriggerEvent) {
return ((MIWatchpointTriggerEvent)event).getExpression();
} else if (event instanceof MIErrorEvent) {
return ((MIErrorEvent)event).getMessage();
}
return null;
}
}
/**
@ -324,7 +347,20 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
private boolean fStepping = false;
private boolean fTerminated = false;
/**
* What caused the state change. E.g., a signal was thrown.
*/
private StateChangeReason fStateChangeReason;
/**
* Further detail on what caused the state change. E.g., the specific signal
* that was throw was a SIGINT. The exact string comes from gdb in the mi
* event. May be null, as not all types of state change have additional
* detail of interest.
*/
private String fStateChangeDetails;
private IExecutionDMContext fStateChangeTriggeringContext;
/**
* Indicates that the next MIRunning event should be silenced.
@ -526,6 +562,7 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
fSuspended = false;
fResumePending = false;
fStateChangeReason = e.getReason();
fStateChangeDetails = null; // we have no details of interest for a resume
fMICommandCache.setContextAvailable(e.getDMContext(), false);
//fStateChangeTriggeringContext = e.getTriggeringContext();
if (e.getReason().equals(StateChangeReason.STEP)) {
@ -544,6 +581,7 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
fMICommandCache.setContextAvailable(e.getDMContext(), true);
fMICommandCache.reset();
fStateChangeReason = e.getReason();
fStateChangeDetails = e.getDetails();
fStateChangeTriggeringContext = e.getTriggeringContexts().length != 0
? e.getTriggeringContexts()[0] : null;
fSuspended = true;
@ -793,10 +831,12 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm){
if (dmc instanceof IContainerDMContext) {
rm.setData( new ExecutionData(fStateChangeReason) );
rm.setData( new ExecutionData(fStateChangeReason, fStateChangeDetails) );
} else if (dmc instanceof IMIExecutionDMContext) {
StateChangeReason reason = dmc.equals(fStateChangeTriggeringContext) ? fStateChangeReason : StateChangeReason.CONTAINER;
rm.setData(new ExecutionData(reason));
boolean thisThreadCausedStateChange = dmc.equals(fStateChangeTriggeringContext);
StateChangeReason reason = thisThreadCausedStateChange ? fStateChangeReason : StateChangeReason.CONTAINER;
String details = thisThreadCausedStateChange ? fStateChangeDetails : null;
rm.setData(new ExecutionData(reason, details));
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Given context: " + dmc + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
}

View file

@ -68,12 +68,22 @@ public class MIBreakpointHitEvent extends MIStoppedEvent {
}
MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results);
for (MIStreamRecord streamRecord : miStreamRecords) {
String log = streamRecord.getString();
if (log.startsWith("Catchpoint ")) { //$NON-NLS-1$
return new MICatchpointHitEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), bkptno);
}
}
// We might be here because of a catchpoint hit; in gdb >= 7.0,
// catchpoints are reported as breakpoints. Unfortunately, there's
// nothing in the stopped event indicating it's a catchpoint, and unlike
// gdb < 7.0, there are no stream records that reveal it's a catchpoint.
// The only way to determine it's a catchpoint is to map the gdb breakpoint
// number back to the CBreakpoint (platform) instance, and that *will* reveal
// whether it's a catchpoint or not, and even which kind of catchpoint
// TODO:
/*
CBreakpoint cbkpt = FromSomewhere.getCBreakpointForGdbBreakpoint(bkptno); <== this method doesn't exist yet
if (cbkpt instanceof CEventBreakpoint) {
String eventTypeID = ((CEventBreakpoint)cbkpt).getEventType();
String gdbKeyword = GdbCatchpoints.eventToGdbCatchpointKeyword(eventTypeID)
return MICatchpointHitEvent.parse(stoppedEvent.getDMContext(), token, results, gdbKeyword);
}
*/
return new MIBreakpointHitEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), bkptno);
}

View file

@ -12,9 +12,25 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIStreamRecord;
*/
public class MICatchpointHitEvent extends MIBreakpointHitEvent {
/**
* See {@link #getReason()}
*/
private String fReason;
protected MICatchpointHitEvent(IExecutionDMContext ctx, int token,
MIResult[] results, MIFrame frame, int bkptno) {
MIResult[] results, MIFrame frame, int bkptno, String reason) {
super(ctx, token, results, frame, bkptno);
fReason = reason;
}
/**
* Returns the event the cachpoint caught. E.g., a C++ exception was thrown.
* This string comes either from gdb when the catchpoint is hit, or it's the
* gdb catchpoint keyword ('catch', 'throw', 'fork', etc) that was used to
* set the catchpoint (to be done for gdb >= 7.0)
*/
public String getReason() {
return fReason;
}
/**
@ -31,9 +47,27 @@ public class MICatchpointHitEvent extends MIBreakpointHitEvent {
StringTokenizer tokenizer = new StringTokenizer(streamRecord.getString());
tokenizer.nextToken(); // "Catchpoint"
try {
int bkptNumber = Integer.parseInt(tokenizer.nextToken()); // "1" (e.g.,)
int bkptNumber = Integer.parseInt(tokenizer.nextToken()); // "1"
StringBuilder reason = new StringBuilder();
boolean first = true;
while (tokenizer.hasMoreElements()) {
if (!first) {
reason.append(" "); //$NON-NLS-1$ ok; technically, the delim could be any whitespace, but we know it's s a space char
}
reason.append(tokenizer.nextElement());
first = false;
}
// remove the parentheses
if (reason.charAt(0) == '(') {
reason.deleteCharAt(0);
}
if (reason.charAt(reason.length()-1) == ')') {
reason.deleteCharAt(reason.length()-1);
}
MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results);
return new MICatchpointHitEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), bkptNumber);
return new MICatchpointHitEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), bkptNumber, reason.toString());
}
catch (NumberFormatException exc) {
assert false : "unexpected catchpoint stream record format: " + streamRecord.getString(); //$NON-NLS-1$

View file

@ -23,13 +23,28 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIResult;
@Immutable
public class MISharedLibEvent extends MIStoppedEvent {
protected MISharedLibEvent(IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame) {
/** See {@link #getLibrary()} */
private String fLibrary;
/**
* @since 3.0
*/
protected MISharedLibEvent(IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame, String library) {
super(ctx, token, results, frame);
fLibrary = library;
}
/** The library that was loaded, as reported by gdb.
* @since 3.0*/
public String getLibrary() {
return fLibrary;
}
public static MIStoppedEvent parse(IExecutionDMContext dmc, int token, MIResult[] results)
{
/**
* @since 3.0
*/
public static MIStoppedEvent parse(IExecutionDMContext dmc, int token, MIResult[] results, String library) {
MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results);
return new MISharedLibEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame());
return new MISharedLibEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), library);
}
}