31
31
import ghidra .trace .database .DBTraceUtils ;
32
32
import ghidra .trace .model .Trace ;
33
33
import ghidra .trace .model .program .TraceProgramView ;
34
+ import ghidra .trace .model .stack .TraceObjectStackFrame ;
35
+ import ghidra .trace .model .target .TraceObject ;
36
+ import ghidra .trace .model .target .TraceObjectKeyPath ;
37
+ import ghidra .trace .model .thread .TraceObjectThread ;
34
38
import ghidra .trace .model .thread .TraceThread ;
35
39
import ghidra .trace .model .time .TraceSnapshot ;
36
40
import ghidra .trace .model .time .schedule .TraceSchedule ;
40
44
import ghidra .util .NotOwnerException ;
41
45
42
46
public class DebuggerCoordinates {
47
+
43
48
public static final DebuggerCoordinates NOWHERE =
44
- new DebuggerCoordinates (null , null , null , null , TraceSchedule .ZERO , 0 ) {
45
- @ Override
46
- public void writeDataState (PluginTool tool , SaveState saveState , String key ) {
47
- // Write nothing
48
- }
49
- };
49
+ new DebuggerCoordinates (null , null , null , null , TraceSchedule .ZERO , 0 , null );
50
50
51
51
private static final String KEY_TRACE_PROJ_LOC = "TraceProjLoc" ;
52
52
private static final String KEY_TRACE_PROJ_NAME = "TraceProjName" ;
@@ -55,35 +55,38 @@ public void writeDataState(PluginTool tool, SaveState saveState, String key) {
55
55
private static final String KEY_THREAD_KEY = "ThreadKey" ;
56
56
private static final String KEY_TIME = "Time" ;
57
57
private static final String KEY_FRAME = "Frame" ;
58
+ private static final String KEY_OBJ_PATH = "ObjectPath" ;
58
59
59
60
public static DebuggerCoordinates all (Trace trace , TraceRecorder recorder , TraceThread thread ,
60
- TraceProgramView view , TraceSchedule time , Integer frame ) {
61
+ TraceProgramView view , TraceSchedule time , Integer frame , TraceObject object ) {
61
62
if (trace == NOWHERE .trace && recorder == NOWHERE .recorder && thread == NOWHERE .thread &&
62
- view == NOWHERE .view && time == NOWHERE .time && frame == NOWHERE .frame ) {
63
+ view == NOWHERE .view && time == NOWHERE .time && frame == NOWHERE .frame &&
64
+ object == NOWHERE .object ) {
63
65
return NOWHERE ;
64
66
}
65
- return new DebuggerCoordinates (trace , recorder , thread , view , time , frame );
67
+ return new DebuggerCoordinates (trace , recorder , thread , view , time , frame , object );
66
68
}
67
69
68
70
public static DebuggerCoordinates trace (Trace trace ) {
69
71
if (trace == null ) {
70
72
return NOWHERE ;
71
73
}
72
- return all (trace , null , null , null , null , null );
74
+ return all (trace , null , null , null , null , null , null );
73
75
}
74
76
75
77
public static DebuggerCoordinates recorder (TraceRecorder recorder ) {
76
78
return all (recorder == null ? null : recorder .getTrace (), recorder ,
77
- null , null , recorder == null ? null : TraceSchedule .snap (recorder .getSnap ()), null );
79
+ null , null , recorder == null ? null : TraceSchedule .snap (recorder .getSnap ()), null ,
80
+ null );
78
81
}
79
82
80
83
public static DebuggerCoordinates thread (TraceThread thread ) {
81
- return all (thread == null ? null : thread .getTrace (), null , thread ,
82
- null , null , null );
84
+ return all (thread == null ? null : thread .getTrace (), null , thread , null , null , null , null );
83
85
}
84
86
85
87
public static DebuggerCoordinates rawView (TraceProgramView view ) {
86
- return all (view .getTrace (), null , null , view , TraceSchedule .snap (view .getSnap ()), null );
88
+ return all (view .getTrace (), null , null , view , TraceSchedule .snap (view .getSnap ()), null ,
89
+ null );
87
90
}
88
91
89
92
public static DebuggerCoordinates view (TraceProgramView view ) {
@@ -107,24 +110,39 @@ public static DebuggerCoordinates view(TraceProgramView view) {
107
110
}
108
111
109
112
public static DebuggerCoordinates snap (long snap ) {
110
- return all (null , null , null , null , TraceSchedule .snap (snap ), null );
113
+ return all (null , null , null , null , TraceSchedule .snap (snap ), null , null );
111
114
}
112
115
113
116
public static DebuggerCoordinates time (String time ) {
114
117
return time (TraceSchedule .parse (time ));
115
118
}
116
119
117
120
public static DebuggerCoordinates time (TraceSchedule time ) {
118
- return all (null , null , null , null , time , null );
121
+ return all (null , null , null , null , time , null , null );
119
122
}
120
123
121
124
public static DebuggerCoordinates frame (int frame ) {
122
- return all (null , null , null , null , null , frame );
125
+ return all (null , null , null , null , null , frame , null );
126
+ }
127
+
128
+ public static DebuggerCoordinates object (TraceObject object ) {
129
+ if (object == null ) {
130
+ return NOWHERE ;
131
+ }
132
+ TraceObjectThread thread = object .queryCanonicalAncestorsInterface (TraceObjectThread .class )
133
+ .findFirst ()
134
+ .orElse (null );
135
+ TraceObjectStackFrame frame =
136
+ object .queryCanonicalAncestorsInterface (TraceObjectStackFrame .class )
137
+ .findFirst ()
138
+ .orElse (null );
139
+ return all (object .getTrace (), null , thread , null , null ,
140
+ frame == null ? null : frame .getLevel (), object );
123
141
}
124
142
125
143
public static DebuggerCoordinates threadSnap (TraceThread thread , long snap ) {
126
144
return all (thread == null ? null : thread .getTrace (), null , thread , null ,
127
- TraceSchedule .snap (snap ), null );
145
+ TraceSchedule .snap (snap ), null , null );
128
146
}
129
147
130
148
public static boolean equalsIgnoreRecorderAndView (DebuggerCoordinates a ,
@@ -150,29 +168,31 @@ public static boolean equalsIgnoreRecorderAndView(DebuggerCoordinates a,
150
168
private final TraceProgramView view ;
151
169
private final TraceSchedule time ;
152
170
private final Integer frame ;
171
+ private final TraceObject object ;
153
172
154
173
private final int hash ;
155
174
156
175
private Long viewSnap ;
157
176
private DefaultTraceTimeViewport viewport ;
158
177
159
178
protected DebuggerCoordinates (Trace trace , TraceRecorder recorder , TraceThread thread ,
160
- TraceProgramView view , TraceSchedule time , Integer frame ) {
179
+ TraceProgramView view , TraceSchedule time , Integer frame , TraceObject object ) {
161
180
this .trace = trace ;
162
181
this .recorder = recorder ;
163
182
this .thread = thread ;
164
183
this .view = view ;
165
184
this .time = time ;
166
185
this .frame = frame ;
186
+ this .object = object ;
167
187
168
- this .hash = Objects .hash (trace , recorder , thread , view , time , frame );
188
+ this .hash = Objects .hash (trace , recorder , thread , view , time , frame , object );
169
189
}
170
190
171
191
@ Override
172
192
public String toString () {
173
193
return String .format (
174
- "Coords(trace=%s,recorder=%s,thread=%s,view=%s,time=%s,frame=%d)" ,
175
- trace , recorder , thread , view , time , frame );
194
+ "Coords(trace=%s,recorder=%s,thread=%s,view=%s,time=%s,frame=%d,object=%d )" ,
195
+ trace , recorder , thread , view , time , frame , object );
176
196
}
177
197
178
198
@ Override
@@ -199,6 +219,10 @@ public boolean equals(Object obj) {
199
219
if (!Objects .equals (this .frame , that .frame )) {
200
220
return false ;
201
221
}
222
+ if (!Objects .equals (this .object , that .object )) {
223
+ return false ;
224
+ }
225
+
202
226
return true ;
203
227
}
204
228
@@ -216,7 +240,7 @@ public TraceRecorder getRecorder() {
216
240
}
217
241
218
242
public DebuggerCoordinates withRecorder (TraceRecorder newRecorder ) {
219
- return all (trace , newRecorder , thread , view , time , frame );
243
+ return all (trace , newRecorder , thread , view , time , frame , object );
220
244
}
221
245
222
246
public TraceThread getThread () {
@@ -235,7 +259,7 @@ public DebuggerCoordinates withReFoundThread() {
235
259
}
236
260
237
261
public DebuggerCoordinates withThread (TraceThread newThread ) {
238
- return all (trace , recorder , newThread , view , time , frame );
262
+ return all (trace , recorder , newThread , view , time , frame , object );
239
263
}
240
264
241
265
public TraceProgramView getView () {
@@ -254,15 +278,19 @@ public Long getSnap() {
254
278
*/
255
279
public DebuggerCoordinates withSnap (Long newSnap ) {
256
280
return all (trace , recorder , thread , view ,
257
- newSnap == null ? time : TraceSchedule .snap (newSnap ), frame );
281
+ newSnap == null ? time : TraceSchedule .snap (newSnap ), frame , object );
258
282
}
259
283
260
284
public DebuggerCoordinates withTime (TraceSchedule newTime ) {
261
- return all (trace , recorder , thread , view , newTime , frame );
285
+ return all (trace , recorder , thread , view , newTime , frame , object );
262
286
}
263
287
264
288
public DebuggerCoordinates withView (TraceProgramView newView ) {
265
- return all (trace , recorder , thread , newView , time , frame );
289
+ return all (trace , recorder , thread , newView , time , frame , object );
290
+ }
291
+
292
+ public DebuggerCoordinates withObject (TraceObject newObject ) {
293
+ return all (trace , recorder , thread , view , time , frame , newObject );
266
294
}
267
295
268
296
public TraceSchedule getTime () {
@@ -273,6 +301,10 @@ public Integer getFrame() {
273
301
return frame ;
274
302
}
275
303
304
+ public TraceObject getObject () {
305
+ return object ;
306
+ }
307
+
276
308
public synchronized long getViewSnap () {
277
309
if (viewSnap != null ) {
278
310
return viewSnap ;
@@ -304,6 +336,9 @@ public synchronized TraceTimeViewport getViewport() {
304
336
}
305
337
306
338
public void writeDataState (PluginTool tool , SaveState saveState , String key ) {
339
+ if (this == NOWHERE ) {
340
+ return ;
341
+ }
307
342
SaveState coordState = new SaveState ();
308
343
// for NOWHERE, key should be completely omitted
309
344
if (trace != null ) {
@@ -410,9 +445,21 @@ public static DebuggerCoordinates readDataState(PluginTool tool, SaveState saveS
410
445
if (coordState .hasValue (KEY_FRAME )) {
411
446
frame = coordState .getInt (KEY_FRAME , 0 );
412
447
}
448
+ TraceObject object = null ;
449
+ if (trace != null && coordState .hasValue (KEY_OBJ_PATH )) {
450
+ String pathString = coordState .getString (KEY_OBJ_PATH , "" );
451
+ try {
452
+ TraceObjectKeyPath path = TraceObjectKeyPath .parse (pathString );
453
+ object = trace .getObjectManager ().getObjectByCanonicalPath (path );
454
+ }
455
+ catch (Exception e ) {
456
+ Msg .error (DebuggerCoordinates .class , "Could not restore object: " + pathString , e );
457
+ object = trace .getObjectManager ().getRootObject ();
458
+ }
459
+ }
413
460
414
461
DebuggerCoordinates coords =
415
- DebuggerCoordinates .all (trace , null , thread , null , time , frame );
462
+ DebuggerCoordinates .all (trace , null , thread , null , time , frame , object );
416
463
if (!resolve ) {
417
464
return coords ;
418
465
}
0 commit comments