Interface TraceObject
- All Superinterfaces:
TraceUniqueObject
- All Known Implementing Classes:
DBTraceObject
This object supports querying for and obtaining the interfaces which constitute what the object is and define how the client may interact with it. The object may also have children, e.g., a process should likely have threads.
This interface is the focal point of the "debug target model." A debugger may present itself as
an arbitrary directory of "target objects." The root object is typically the debugger's session,
and one its attributes is a collection for its attached targets. These objects, including the
root object, may implement any number of interfaces extending TraceObjectInterface. These
interfaces comprise the type and behavior of the object. An object's children comprise its
elements (for collection-like objects) and attributes. Every object in the directory has a path.
Each element ("key") in the path identifies an index (if the child is an element) or a name (if
the child is an attribute). It is the implementation's responsibility to ensure each object's
path correctly identifies that same object in the model directory. The root has the empty path.
Every object must have a unique path; thus, every object must have a unique key among its
sibling.
The objects are arranged in a directory with links permitted. Links come in the form of object-valued attributes or elements where the path does not match the object value's path. Thus, the overall structure remains a tree, but by resolving links, the model may be treated as a directed graph, likely containing cycles.
The implementation must guarantee that distinct TraceObjects from the same model do not
share the same path. That is, checking for object identity is sufficient to check that two
variables refer to the same object.
Various conventions govern where the client/user should search to obtain a given interface in the
context of some target object. For example, if the user is interacting with a thread, and wishes
to access that thread's memory, it needs to follow a given search order to find the appropriate
target object(s), if they exist, implementing the desired interface. See
TraceObjectSchema.searchForSuitable(TraceObjectSchema, KeyPath) for details. In summary,
the order is:
- The object itself: Test if the context target object supports the desired interface. If it does, take it.
- Aggregate objects: If the object is marked with
TraceAggregate, collect all attributes supporting the desired interface. If there are any, take them. This step is applied recursively if any child attribute is also marked withTraceAggregate. - Ancestry: Apply these same steps to the object's (canonical) parent, recursively.
For some situations, exactly one object is required. In that case, take the first obtained by applying the above rules. In other situations, multiple objects may be acceptable. Again, apply the rules until a sufficient collection of objects is obtained. If an object is in conflict with another, take the first encountered. This situation may be appropriate if, e.g., multiple target memories present disjoint regions. There should not be conflicts among sibling. If there are, then either the model or the query is not sound. The order siblings considered should not matter.
This relatively free structure and corresponding conventions allow for debuggers to present a model which closely reflects the structure of its session. For example, the following structure may be presented by a user-space debugger for a desktop operating system:
- "Session" :
TraceObject- "Process 789" :
TraceProcess,TraceAggregate- "Threads" :
TraceObject- "Thread 1" :
TraceThread,TraceExecutionStateful,TraceAggregate- "Registers" :
TraceRegisterContainer- "r1" :
TraceRegister - ...
- "r1" :
- "Registers" :
- ...more threads
- "Thread 1" :
- "Memory" :
TraceMemory- "[0x00400000:0x00401234]" :
TraceMemoryRegion - ...more regions
- "[0x00400000:0x00401234]" :
- "Modules" :
TraceObject- "/usr/bin/echo" :
TraceModule- ".text" :
TraceSection - ...more sections
- ".text" :
- ...more modules
- "/usr/bin/echo" :
- "Threads" :
- "Environment":
TraceEnvironment- "Process 321" :
TraceObject - ...more processes
- "Process 321" :
- "Process 789" :
Note that this interface does not provide target-related operations, but only a means of modifying the database. The target connector, if this trace is still "live," should have a handle to this same trace and so can update the records as events occur in the debugger session and keep the target state up to date. Commands for manipulating the target and/or session itself are provided by that connector.
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic enumSpecifies a strategy for resolving duplicate keys -
Field Summary
Fields -
Method Summary
Modifier and TypeMethodDescriptionvoiddelete()Delete this object along with parent and child value entries referring to itStream<? extends TraceObjectValPath> findAncestorsInterface(Lifespan span, Class<? extends TraceObjectInterface> iface) Search for ancestors having the given interfaceStream<? extends TraceObject> findCanonicalAncestorsInterface(Class<? extends TraceObjectInterface> iface) Search for ancestors on the canonical path having the given interfacedefault TraceObjectfindRegisterContainer(int frameLevel) Search for a suitable register containerStream<? extends TraceObjectValPath> findSuccessorsInterface(Lifespan span, Class<? extends TraceObjectInterface> iface, boolean requireCanonical) Search for successors having the given interfacedefault TraceObjectfindSuitableContainerInterface(Class<? extends TraceObjectInterface> iface) Search for a suitable canonical container of the given interfacedefault TraceObjectfindSuitableInterface(Class<? extends TraceObjectInterface> iface) Search for a suitable object having the given interfacedefault TraceObjectfindSuitableSchema(TraceObjectSchema schema) Search for a suitable object having the given schemaStream<? extends TraceObjectValPath> getAllPaths(Lifespan span) Get all paths actually leading to this object, from the root, within the given spanStream<? extends TraceObjectValPath> getAncestors(Lifespan span, PathFilter relativeFilter) Stream all ancestor values of this object matching the given filter, intersecting the given spanStream<? extends TraceObjectValPath> getAncestorsRoot(Lifespan span, PathFilter rootFilter) Stream all ancestor values of this object matching the given filter, intersecting the given spangetAttribute(long snap, String name) Get the value for the given snap and attribute nameCollection<? extends TraceObjectValue> getAttributes(Lifespan span) Get all attributes of this object intersecting the given spangetCanonicalParent(long snap) Get the parent value along this object's canonical path for a given snapshotStream<? extends TraceObjectValue> getCanonicalParents(Lifespan lifespan) Get the parent values along this object's canonical path for a given lifespanGet the canonical path of this objectStream<? extends TraceObjectValPath> getCanonicalSuccessors(PathFilter relativeFilter) Stream all canonical successor values of this object matching the given filtergetElement(long snap, long index) Get the value for the given snap and element indexgetElement(long snap, String index) Get the value for the given snap and element indexCollection<? extends TraceObjectValue> getElements(Lifespan span) Get all elements of this object intersecting the given spandefault TraceExecutionStategetExecutionState(long snap) Get the execution state, if applicable, of this objectCollection<Class<? extends TraceObjectInterface>> Get all the interface classes provided by this object, according to the schemalonggetKey()Get the database key for this objectgetLife()Get all ranges of this object's lifeStream<? extends TraceObjectValPath> getOrderedSuccessors(Lifespan span, KeyPath relativePath, boolean forward) Stream all successor values of this object at the given relative path, intersecting the given span, ordered by time.Stream<? extends TraceObjectValue> getOrderedValues(Lifespan span, String key, boolean forward) Get values with the given key intersecting the given span ordered by timeCollection<? extends TraceObjectValue> getParents(Lifespan span) Get all values intersecting the given span and whose child is this objectgetRoot()Get the root of the tree containing this objectGet the schema for this objectStream<? extends TraceObjectValPath> getSuccessors(Lifespan span, PathFilter relativeFilter) Stream all successor values of this object matching the given filter, intersecting the given spangetTrace()Get the trace containing this objectGet the value for the given snap and keyCollection<? extends TraceObjectValue> Get all values (elements and attributes) of this object intersecting the given spanCollection<? extends TraceObjectValue> Get values with the given key intersecting the given spaninsert(Lifespan lifespan, TraceObject.ConflictResolution resolution) Inserts this object at its canonical path for the given lifespanbooleanisAlive(long snap) Check if the object is alive at the given snapbooleanCheck if the object is alive at all in the given spanbooleanCheck if this object has been deleteddefault booleanisMethod(long snap) Check if the child represents a method at the given snapbooleanisRoot()Check if this object is the root<I extends TraceObjectInterface>
Stream<I> queryAncestorsInterface(Lifespan span, Class<I> iface) Search for ancestors having the given interface and retrieve those interfaces<I extends TraceObjectInterface>
Stream<I> queryCanonicalAncestorsInterface(Class<I> iface) Search for ancestors on the canonical path having the given interface and retrieve those interfaces<I extends TraceObjectInterface>
IqueryInterface(Class<I> iface) Request the specified interface provided by this object<I extends TraceObjectInterface>
Stream<I> querySuccessorsInterface(Lifespan span, Class<I> iface, boolean requireCanonical) Search for successors having the given interface and retrieve those interfacesvoidRemove this object from its canonical path for the given lifespanvoidremoveTree(Lifespan span) Remove this object and its successors from their canonical paths for the given spansetAttribute(Lifespan lifespan, String name, Object value) Set an attribute for the given lifespansetElement(Lifespan lifespan, long index, Object value) Set an element for the given lifespansetElement(Lifespan lifespan, String index, Object value) Set an element for the given lifespanSet a value for the given lifespan, truncating existing entriessetValue(Lifespan lifespan, String key, Object value, TraceObject.ConflictResolution resolution) Set a value for the given lifespanMethods inherited from interface ghidra.trace.model.TraceUniqueObject
getObjectKey
-
Field Details
-
EXTRA_INTERFACES_ATTRIBUTE_NAME
- See Also:
-
-
Method Details
-
getTrace
Trace getTrace()Get the trace containing this object- Returns:
- the trace
-
getKey
long getKey()Get the database key for this object- Returns:
- the key
-
getRoot
TraceObject getRoot()Get the root of the tree containing this object- Returns:
- the root
-
getCanonicalPath
KeyPath getCanonicalPath()Get the canonical path of this object- Returns:
- the path
-
getLife
Lifespan.LifeSet getLife()Get all ranges of this object's lifeEssentially, this is the union of the lifespans of all canonical parent values
- Returns:
- the range set for snaps at which this object is considered "inserted."
-
isAlive
boolean isAlive(long snap) Check if the object is alive at the given snapThis is preferable to
getLife(), when we only need to check one snap- Parameters:
snap- the snap- Returns:
- true if alive, false if not
-
isAlive
Check if the object is alive at all in the given span- Parameters:
span- the span- Returns:
- true if alive, false if not
-
insert
Inserts this object at its canonical path for the given lifespanAny ancestor which does not exist is created. Values' lifespans are added or expanded to contain the given lifespan. Only the canonical path is considered when looking for existing ancestry.
- Parameters:
lifespan- the minimum lifespan of edges from the root to this objectresolution- the rule for handling duplicate keys when setting values.- Returns:
- the value path from root to the newly inserted object
-
remove
Remove this object from its canonical path for the given lifespanTruncate the lifespans of this object's canonical parent value by the given span. If the parent value's lifespan is contained in the given span, the parent value will be deleted.
- Parameters:
span- the span during which this object should be removed
-
removeTree
Remove this object and its successors from their canonical paths for the given spanTruncate the lifespans of this object's parent values and all canonical values succeeding this object. If a truncated value's lifespan is contained in the given span, the value will be deleted.
- Parameters:
span- the span during which this object and its canonical successors should be removed
-
getCanonicalParent
Get the parent value along this object's canonical path for a given snapshotTo be the canonical parent value at a given snapshot, three things must be true: 1) The parent object must have this object's path with the final key removed. 2) The parent value's entry key must be equal to the final key of this object's path. 3) The value's lifespan must contain the given snapshot. If no value satisfies these, null is returned, and the object and its subtree are said to be "detached" at the given snapshot.
- Parameters:
snap- the snapshot key- Returns:
- the canonical parent value, or null
-
getCanonicalParents
Get the parent values along this object's canonical path for a given lifespanTo be a canonical parent in a given lifespan, three things must be true: 1) The parent object must have this object's path with the final key removed. 2) The parent value's entry key must be equal to the final key of this object's path. 3) The value's lifespan must intersect the given lifespan. If the result is empty, the object and its subtree are said to be "detatched" during the given lifespan.
- Parameters:
lifespan- the lifespan to consider- Returns:
- the stream of canonical parents
-
isRoot
boolean isRoot()Check if this object is the root- Returns:
- true if root
-
getAllPaths
Get all paths actually leading to this object, from the root, within the given spanAliased keys are excluded.
- Parameters:
span- the span which every value entry on each path must intersect- Returns:
- the paths
-
getInterfaces
Collection<Class<? extends TraceObjectInterface>> getInterfaces()Get all the interface classes provided by this object, according to the schema- Returns:
- the collection of interface classes
-
queryInterface
Request the specified interface provided by this object- Type Parameters:
I- the type of the interface- Parameters:
iface- the class of the interface- Returns:
- the interface, or null if not provided
-
getParents
Get all values intersecting the given span and whose child is this objectAliased keys are excluded.
- Parameters:
span- the span- Returns:
- the parent values
-
getValues
Get all values (elements and attributes) of this object intersecting the given spanAliased keys are excluded.
- Parameters:
span- the span- Returns:
- the values
-
getValues
Get values with the given key intersecting the given spanIf the key is an alias, the target key's values are retrieved instead.
- Parameters:
span- the spankey- the key- Returns:
- the collection of values
-
getOrderedValues
Get values with the given key intersecting the given span ordered by timeIf the key is an alias, the target key's values are retrieved instead.
- Parameters:
span- the spankey- the keyforward- true to order from least- to most-recent, false for most- to least-recent- Returns:
- the stream of values
-
getElements
Get all elements of this object intersecting the given span- Parameters:
span- the span- Returns:
- the element values
-
getAttributes
Get all attributes of this object intersecting the given spanAliased keys are excluded.
- Parameters:
span- the span- Returns:
- the attribute values
-
getValue
Get the value for the given snap and keyIf the key is an alias, the target key's value is retrieved instead.
- Parameters:
snap- the snapkey- the key- Returns:
- the value entry
-
getElement
Get the value for the given snap and element indexThis is equivalent to
getValue(long, String), but converts index to a key, i.e., adds brackets.- Parameters:
snap- the snapindex- the index- Returns:
- the value entry
-
getElement
Get the value for the given snap and element indexThis is equivalent to
getElement(long, String), but converts index to a string in decimal.- Parameters:
snap- the snapindex- the index- Returns:
- the value entry
-
getAttribute
Get the value for the given snap and attribute nameThis is equivalent to
getValue(long, String), except it validates that name is not an index.- Parameters:
snap- the snapname- the name- Returns:
- the value entry
-
getAncestorsRoot
Stream all ancestor values of this object matching the given filter, intersecting the given spanAliased keys are excluded. The filter should be formulated to use the aliases' target attributes.
- Parameters:
span- a span which values along the path must intersectrootFilter- the filter for matching path keys, relative to the root- Returns:
- the stream of matching paths to values
-
getAncestors
Stream all ancestor values of this object matching the given filter, intersecting the given spanAliased keys are excluded. The filter should be formulated to use the aliases' target attributes.
- Parameters:
span- a span which values along the path must intersectrelativeFilter- the filter for matching path keys, relative to this object- Returns:
- the stream of matching paths to values
-
getSuccessors
Stream all successor values of this object matching the given filter, intersecting the given spanAliased keys are excluded. The filter should be formulated to use the aliases' target attributes.
- Parameters:
span- a span which values along the path must intersectrelativeFilter- the filter for matching path keys, relative to this object- Returns:
- the stream of matching paths to values
-
getOrderedSuccessors
Stream<? extends TraceObjectValPath> getOrderedSuccessors(Lifespan span, KeyPath relativePath, boolean forward) Stream all successor values of this object at the given relative path, intersecting the given span, ordered by time.Aliased keys are excluded. The filter should be formulated to use the aliases' target attributes.
- Parameters:
span- the span which values along the path must intersectrelativePath- the path relative to this objectforward- true to order from least- to most-recent, false for most- to least-recent- Returns:
- the stream of value paths
-
getCanonicalSuccessors
Stream all canonical successor values of this object matching the given filterIf an object has a disjoint life, i.e., multiple canonical parents, then only the least-recent of those is traversed. Aliased keys are excluded; those can't be canonical anyway. By definition, a primitive value is not canonical, even if it is the final value in the path.
- Parameters:
relativeFilter- filter on the relative path from this object to desired successors- Returns:
- the stream of value paths
-
setValue
TraceObjectValue setValue(Lifespan lifespan, String key, Object value, TraceObject.ConflictResolution resolution) Set a value for the given lifespanIf the key is an alias, the target key's value is set instead.
- Parameters:
lifespan- the lifespan of the valuekey- the key to setvalue- the new valueresolution- determines how to resolve duplicate keys with intersecting lifespans- Returns:
- the created value entry
- Throws:
DuplicateKeyException- if there are denied duplicate keys
-
setValue
Set a value for the given lifespan, truncating existing entriesSetting a value of
nulleffectively deletes the value for the given lifespan and returnsnull. Values of the same key intersecting the given lifespan or either truncated or deleted. If the key is an alias, the target key's value is set instead.- Parameters:
lifespan- the lifespan of the valuekey- the key to setvalue- the new value- Returns:
- the created value entry, or null
-
setAttribute
Set an attribute for the given lifespanThis is equivalent to
setValue(Lifespan, String, Object), except it verifies the key is an attribute name.- Parameters:
lifespan- the lifespan of the attributename- the name to setvalue- the new value- Returns:
- the created value entry
-
setElement
Set an element for the given lifespanThis is equivalent to
setValue(Lifespan, String, Object), except it converts the index to a key, i.e., add brackets.- Parameters:
lifespan- the lifespan of the elementindex- the index to setvalue- the new value- Returns:
- the created value entry
-
setElement
Set an element for the given lifespan- Parameters:
lifespan- the lifespan of the elementindex- the index to setvalue- the new value- Returns:
- the created value entry
-
getSchema
TraceObjectSchema getSchema()Get the schema for this object- Returns:
- the schema
-
findAncestorsInterface
Stream<? extends TraceObjectValPath> findAncestorsInterface(Lifespan span, Class<? extends TraceObjectInterface> iface) Search for ancestors having the given interface- Parameters:
span- the span which the found objects must intersectiface- the interface class- Returns:
- the stream of found paths to values
-
queryAncestorsInterface
Search for ancestors having the given interface and retrieve those interfaces- Type Parameters:
I- the interface type- Parameters:
span- the span which the found objects must intersectiface- the interface class- Returns:
- the stream of interfaces
-
findCanonicalAncestorsInterface
Stream<? extends TraceObject> findCanonicalAncestorsInterface(Class<? extends TraceObjectInterface> iface) Search for ancestors on the canonical path having the given interfaceThe object may not yet be inserted at its canonical path.
- Parameters:
iface- the interface class- Returns:
- the stream of objects
-
queryCanonicalAncestorsInterface
Search for ancestors on the canonical path having the given interface and retrieve those interfacesThe object may not yet be inserted at its canonical path.
- Type Parameters:
I- the interface type- Parameters:
iface- the interface class- Returns:
- the stream of interfaces
-
findSuccessorsInterface
Stream<? extends TraceObjectValPath> findSuccessorsInterface(Lifespan span, Class<? extends TraceObjectInterface> iface, boolean requireCanonical) Search for successors having the given interface- Parameters:
span- the span which the found paths must intersectiface- the interface classrequireCanonical- if the objects must be found within their canonical container- Returns:
- the stream of found paths to values
-
querySuccessorsInterface
<I extends TraceObjectInterface> Stream<I> querySuccessorsInterface(Lifespan span, Class<I> iface, boolean requireCanonical) Search for successors having the given interface and retrieve those interfaces- Type Parameters:
I- the interface type- Parameters:
span- the span which the found objects must intersectiface- the interface classrequireCanonical- if the objects must be found within their canonical container- Returns:
- the stream of interfaces
-
delete
void delete()Delete this object along with parent and child value entries referring to itWarning: This will remove the object from the manager entirely, not just over a given span. In general, this is used for cleaning and maintenance. Consider
remove(Lifespan)orTraceObjectValue.delete()instead. Note, this does not delete the child objects or any successors. It is not recommended to invoke this on the root object, since it cannot be replaced without first clearing the manager. -
isDeleted
boolean isDeleted()Check if this object has been deleted- Specified by:
isDeletedin interfaceTraceUniqueObject- Returns:
- true if the object has been deleted
-
isMethod
default boolean isMethod(long snap) Check if the child represents a method at the given snap- Parameters:
snap- the snap- Returns:
- true if a method
-
findSuitableInterface
Search for a suitable object having the given interfaceThis operates by examining the schema for a unique suitable path, without regard to lifespans. If needed, the caller should inspect the object's life.
- Parameters:
iface- the interface- Returns:
- the suitable object, or null if not found
-
findSuitableContainerInterface
Search for a suitable canonical container of the given interface- Parameters:
iface- the interface- Returns:
- the container, or null if not found
-
findSuitableSchema
Search for a suitable object having the given schemaThis operates by examining the schema for a unique suitable path, without regard to lifespans. If needed, the caller should inspect the object's life.
- Parameters:
schema- the schema- Returns:
- the suitable object, or null if not found
-
findRegisterContainer
Search for a suitable register container- Parameters:
frameLevel- the frame level. Must be 0 if not applicable- Returns:
- the register container, or null
- See Also:
-
getExecutionState
Get the execution state, if applicable, of this objectThis searches for the conventional stateful object defining this object's execution state. If such an object does not exist, null is returned. If one does exist, then its execution state at the given snap is returned. If that state is null, it is assumed
TraceExecutionState.INACTIVE.- Parameters:
snap- the snap- Returns:
- the state or null
-