Hi Anton,
Looking at the JDWP specification, it seems that the underlying JDWP
protocol
does support looking up objects using just their id:
Maybe this is just a terminology issue, but I'm not sure what you mean
by "lookup". JDWP doesn't lookup ObjectIDs. It returns them any place
where there is an object reference. For example, if a field of a java
object or stack local refer to a java object, it will be represented by
an ObjectID.
At the JDI level, an ObjectReference tracks the underlying JDWP
ObjectID. So in this sense there are two different ways to represent a
java object; the ObjectReference or the underlying JDWP ObjectID. You've
pointed out that you can map from an ObjectReference to an ObjectID, but
not the other way around. There is not a 1-to-1 relationship between
ObjectReference instances and ObjectIDs. You can have multiple
ObjectReference objects that reference the same ObjectID. So there is no
way to map from an ObjectID to an ObjectReference (since there can be
more than one).
/My question now is:/
Is there a specific reason that there is no public factory method to
construct
an ObjectReference from an object id?
Or would it be "safe" to create a custom `ObjectReference`
implementation that
allows this, as long as it deals with the `INVALID_OBJECT` error case
of JDWP?
I think the main issue would be validation. Currently the JDI
implementation creates ObjectReference instances based on the ObjectID
it got from JDWP. You're proposing that the user supply the ObjectID.
The assumption is that it came from another ObjectReference so should be
valid, but not only is it possible that the ObjectID could have been
fabricated, but it also could have been valid at one point but no longer
is (the referred to object may have been GC'd). So the question about
safety here is somewhat relative. I assume it can be done and should for
the most part work, but you could possibly run into issues in some error
conditions.
One question I have is why do you want to do this? It sounds like you
want to cache or store ObjectIDs instead of ObjectReferences, but later
want to map the ObjectID back to an ObjectReference. Why not just store
the ObjectReference?
Is there a specific reason, why this location information is not
exposed in the
public interface?
Why do you want the slot? If it is so you can later map the slot to a
LocalVariable, you'll run into issues if more than one LocalVariable can
use that slot. This is why LocalVariables have scopeStart and scopeEnd
fields. You would need to also specify a bytecode index when doing the
lookup if there is more than one LocalVariable that maps to the same slot.
cheers,
Chris
On 11/23/21 1:25 AM, Anton W. Haubner wrote:
Hello!
I am working on a new kind of debugger which extracts information
about the
state of Java programs through the JDI to build RDF knowledge graphs.
While working on the project, I noticed that there is certain
information about
the program state that is accessible through JDWP, but which is hidden
by the
JDI interfaces (see below for examples).
I am curious, whether this was done to simplify the interface, or if
there is
a deeper reason behind this, e.g. because the information in question is
unreliable etc.
If there is no such reason, I might try to modify the JDI reference
implementation to provide this information to me.
*First Example: Retrieving Objects by ID*
The ObjectReference JDI interface does allow to retrieve the unique id
assigned to
an object by the JDWP agent.
However, it seems it is not possible to construct an ObjectReference
from such
an id. That is, one can not quickly look up an object by its id, but
has to
search through all objects to find it again.
Looking at the JDWP specification, it seems that the underlying JDWP
protocol
does support looking up objects using just their id:
https://docs.oracle.com/en/java/javase/17/docs/specs/jdwp/jdwp-protocol.html#JDWP_ObjectReference
The reference implementation of the `ObjectReference` interface also
seems to
only require this id to retrieve all required information:
https://github.com/openjdk/jdk/blob/dfacda488bfbe2e11e8d607a6d08527710286982/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java#L109
/My question now is:/
Is there a specific reason that there is no public factory method to
construct
an ObjectReference from an object id?
Or would it be "safe" to create a custom `ObjectReference`
implementation that
allows this, as long as it deals with the `INVALID_OBJECT` error case
of JDWP?
*Second Example: Variable Locations*
The JDWP `VariableTable` command reply does contain the code index of
variables.
Nevertheless, it is neither possible to retrieve the code index of a
variable
through the `LocalVariable` JDI interface, nor through the `Method`
interface.
Meanwhile, internally, the `LocalVariable` reference implementation
does seem
to store the scope of a variable:
https://github.com/openjdk/jdk/blob/dfacda488bfbe2e11e8d607a6d08527710286982/src/jdk.jdi/share/classes/com/sun/tools/jdi/LocalVariableImpl.java#L56
The Eclipse JDI implementation also stores the plain code index value:
https://git.eclipse.org/c/jdt/eclipse.jdt.debug.git/tree/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/LocalVariableImpl.java#n63
Is there a specific reason, why this location information is not
exposed in the
public interface?
Thank you very much for reading my questions.
Can you help me to answer them?
Best regards,
Anton Haubner