This document describes object-centric debugging. Traditional debuggers step through code and set breakpoints in the source code. However, they have no awareness of objects. Object-centric debuggers intercept access to object runtime state and monitor object interactions. They support live interaction centered on individual objects, like halting on the next message to an object or state change of an object. This approach redefines the debugger UI and requires adaptation through reflection and explicit meta-objects to organize debugging at the meta-level.
34. When during the execution is this method called? (Q.13)
Where are instances of this class created? (Q.14)
Where is this variable or data structure being accessed?
(Q.15)
What are the values of the argument at runtime? (Q.19)
What data is being modified in this code? (Q.20)
How are these types or objects related? (Q.22)
How can data be passed to (or accessed at) this point
in the code? (Q.28)
What parts of this data structure are accessed in this
code? (Q.33)
35. When during the execution is this method called? (Q.13)
Where are instances of this class created? (Q.14)
Where is this variable or data structure being accessed?
(Q.15)
What are the values of the argument at runtime? (Q.19)
What data is being modified in this code? (Q.20)
How are these types or objects related? (Q.22)
How can data be passed to (or accessed at) this point
in the code? (Q.28)
What parts of this data structure are accessed in this
code? (Q.33) llito
Si etal. g softwar
e
ask durin
gr ammers s. 2008
Questi ons pro ution task
evol
39. Which is the relationship?
When during the execution is this method called? (Q.13)
?
Where are instances of this class created? (Q.14)
Where is this variable or data structure being accessed? (Q.15)
What are the values of the argument at runtime? (Q.19)
What data is being modified in this code? (Q.20)
How are these types or objects related? (Q.22)
How can data be passed to (or accessed at) this point in the code? (Q.28)
What parts of this data structure are accessed in this code? (Q.33)
58. stack-centric debugging
InstructionStream class>>on:
InstructionStream class>>new
InstructionStream>>initialize
step into, CompiledMethod>>initialPC
step over, InstructionStream>>method:pc:
resume InstructionStream>>nextInstruction
MessageCatcher class>>new
InstructionStream>>interpretNextInstructionFor:
...
object-centric debugging
centered on centered on
the InstructionStream class the InstructionStream object
initialize
on:
next message, next message, method:pc:
new next change nextInstruction ...
next change
interpretNextInstructionFor:
...
65. Halt on next message
Halt on next message/s named
Halt on state change
Halt on state change named
Halt on next inherited message
Halt on next overloaded message
Halt on object/s in call
Halt on next message from
package
78. Object-Centric
Objects
Debuggers
Source Traditional
Code Debuggers
scg.unibe.ch/research/bifrost/OCD
Editor's Notes
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
is a framework for drawing graphs\n
width = the number of attributes of the class\nheight = the number of methods of the class\ncolor = the number of lines of code of the class\n\n
\n
double dispatch\n
one of the nodes was not correctly rendered\n
\n
\n
\n
Why do I need to write code?\nWhy do I need to know about object id?\nI want to grab the object, it is there\n
Why do I need to write code?\nWhy do I need to know about object id?\nI want to grab the object, it is there\n
\n
\n
\n
\n
\n
Which questions do these debuggers try to answer?\n
Sillito\n
Which questions do these debuggers try to answer?\n
We have to go back to the code\n
\n
new dimension of problem-domain\n
new dimension of problem-domain\n
Which questions do these debuggers try to answer?\n
We have to go back to the code\n
We have to go back to the code\n
\n
Questions 15, 19, 20, 28 and 33 all have to do with tracking state at runtime. Consider in particular question 15: Where is this variable or data structure being accessed? Let us assume that we want to know where an instance variable of an object is being modified. This is known as keeping track of side-effects [3]. One approach is to use step-wise operations until we reach the modification. However, this can be time-consuming and unreliable. Another approach is to place breakpoints in all assignments related to the instance variable in question. Finding all these assignments might be troublesome depending on the size of the use case, as witnessed by our own experience.\nTracking down the source of this side effect is highly challenging: 31 of the 38 methods defined on InstructionStream access the variable, comprising 12 assignments; the instance variable is written 9 times in InstructionStream’s subclasses. In addition, the variable pc has an accessor that is referenced by 5 intensively-used classes.\n\n
Question 22 poses further difficulties for the debugging approach: How are these types or objects related? In statically typed languages this question can be partially answered by finding all the references to a particular type in another type. Due to polymorphism, however, this may still yield many false positives. (An instance variable of type Object could be potentially bound to instances of any type we are interested in.) Only by examining the runtime behavior can we learn precisely which types are instantiated and bound to which variables. The debugging approach would, however, require heavy use of conditional breakpoints (to filter out types that are not of interest), and might again entail the setting of breakpoints in a large number of call sites.\n\n
Back-in-time debugging [4], [5] can potentially be used to answer many of these questions, since it works by maintain- ing a complete execution history of a program run. There are two critical drawbacks, however, which limit the practical application of back-in-time debugging. First, the approach is inherently post mortem. One cannot debug a running system, but only the history of completed run. Interaction is therefore strictly limited, and extensive exploration may require many runs to be performed. Second, the approach entails considerable overhead both in terms of runtime performance and in terms of memory requirements to build and explore the history.\n\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
double dispatch\n
one of the nodes was not correctly rendered\n
We have more commands that the ones in the debugger, but we did not know how to put them there.\n
one of the nodes was not correctly rendered\n
halt on next specific messages\n
\n
\n
\n
\n
\n
\n
\n
We see that there are many different ways of doing reflection, adaptation, instrumentation, many are low level.\nAnd the ones that are highly flexible cannot break free from the limitations of the language.\n
Adaptation semantic abstraction for composing meta-level structure and behavior.\n