=Paper= {{Paper |id=Vol-3325/short1 |storemode=property |title=Towards Object-centric Time-traveling Debuggers |pdfUrl=https://ceur-ws.org/Vol-3325/short1.pdf |volume=Vol-3325 |authors=Maximilian Ignacio Willembrinck Santander,Steven Costiou,Adrien Vanègue,Anne Etien |dblpUrl=https://dblp.org/rec/conf/iwst/SantanderCVE22 }} ==Towards Object-centric Time-traveling Debuggers== https://ceur-ws.org/Vol-3325/short1.pdf
Towards Object-centric Time-traveling Debuggers
Maximilian Ignacio Willembrinck Santander1 , Steven Costiou1 , Adrien Vanègue1
and Anne Etien2
1
    Univ. Lille, Inria, CNRS, Centrale Lille, UMR 9189 CRIStAL
2
    Univ. Lille, CNRS, Inria, Centrale Lille, UMR 9189 CRIStAL


                                        Abstract
                                        Object-centric debugging aims at facilitating the debugging of object-oriented programs by
                                        focusing debugging operations on specific objects. This technique is tedious to use because
                                        developers have to manually find objects to debug, which is not straightforward.
                                            Time-traveling debuggers allows developers to explore executions back and forth in time.
                                        It has been shown that time-traveling features effectively facilitate debugging and program
                                        understanding.
                                            We propose to combine these techniques to benefit from both of them to debug object-
                                        oriented programs. Time-travel navigation could help finding and remembering objects by
                                        providing means to explore executions back and forth. Object-centric debugging could extend
                                        time-traveling debugging with object-centric exploration features. These techniques have never
                                        been combined, and the challenges and benefits of such combination have never been explored.
                                            We present SeekerOC, a time-traveling debugger prototype which provides object-centric
                                        debugging support. To combine both techniques, we use Time-Traveling Queries, a query system
                                        to automatically explore executions. We discuss the expected benefits of this combination,
                                        and we argue that exploring object-centric time-traveling debugging will open new research
                                        perspectives towards more effective debugging techniques and tools for object-oriented systems.

                                        Keywords
                                        Object-Centric Debugging, Time-Travel Debugging, Program Comprehension.


1. Introduction and Motivation: Debugging Objects
To debug their programs, developers use debuggers which traditionally provide a set of
standard debugging operations. Some of these debugging operations (e.g., breakpoints)
are defined for a class (e.g., in a method) and apply to all instances of that class.
Meanwhile, object-centric debugging is a technique proposed to improve the debugging
of object-oriented systems by scoping object-centric debugging operations to specific
objects [1]. This helps debugging by reducing user interactions to understand bugs [1, 2],
and by exposing and hot fixing buggy objects [3]. However in practice, object-centric
debugging is difficult to use. Developers have to manually explore their executions to
find objects to debug. This is tedious and error-prone. Developers have to repeat many
times the same program exploration process. Object-centric debugging operations also
generate false positives. For example, an object-centric breakpoint might halt the system
many times for a single object. Developers then need to go through numerous haltings


IWST’22: International Workshop on Smalltalk Technologies
                                       © 2022 Copyright for this paper by its authors. Use permitted under Creative Commons License Attribution 4.0 Interna-
                                       tional (CC BY 4.0).
    CEUR
    Workshop
    Proceedings
                  http://ceur-ws.org
                  ISSN 1613-0073
                                       CEUR Workshop Proceedings (CEUR-WS.org)
until finding useful information for debugging. This is as tedious as manually stepping
an execution with a standard debugger.
Time-traveling debugging to the rescue. With time-traveling debuggers, developers
are able to deterministically explore a program execution back and forth in time [4, 5, 6, 7].
When they miss a critical point, developers can rewind an execution and replay it from a
few steps back. This prevents developers from the hassle of having to restart the entire
execution and to repeat the same debugging investigation [8, 9].
   We argue that this capability of navigating through time could improve the application
of object-centric debugging. Developers would be able to explore the execution to find
which object to debug without the risk of missing an interesting moment, and to navigate
directly to events of interest for those objects. Furthermore, time-traveling debuggers
could provide new support for tracking objects to debug. For example, we could specify
what objects we are looking for by using a predicate expression eg., objects of a specific
class, or with specific instance variables values, and automatically explore the execution
back and forth to find those objects. However, to the best of our knowledge, time-traveling
debuggers do not support object-centric debugging and vice-versa.
Proposition: combining time-traveling and object-centric debugging. We argue that
enhancing object-centric debugging by time-traveling mechanisms would enable new de-
bugging tools (dedicated interfaces, requests, views...) that would improve the debugging
of object-oriented programs. In this paper, we illustrate our first probe combining both
techniques. We use our execution querying system named Time-Traveling Queries [10]
(TTQs), which automatically and systematically explore an execution to find objects
and to define time-traveling debugging operations on them. We present SeekerOC, our
time-traveling debugger prototype that implements object-centric queries. We discuss
the benefits of joining both techniques in terms of debugging capabilities and effect, and
why it is worth pushing this research perspective further on.


2. Identifying Particular Objects is Challenging: A Running
   Example
In the following, we illustrate the difficulties developers go through when they try to
comprehend objects behavior during debugging. We explain how object-centric debugging
and time-traveling debugging support these challenges, and their limitations. As an
example, we use a test method from the Pharo 11 code base:

                       Listing 1: The split-join test of collections in Pharo 11.
S p l i t J o i n T e s t >> t e s t S p l i t O r d e r e d C o l l e c t i o n O n O r d e r e d C o l l e c t i o n
  s e l f a s s e r t : ( ( ( 1 to : 10) asOrderedCollection ) splitOn : ((4 to : 5)
          asOrderedCollection ) )
          equals : {(1 to : 3) asOrderedCollection . (6 to : 10) asOrderedCollection }
                  asOrderedCollection

  In this test, an OrderedCollection of 10 elements is split by another
OrderedCollection with two elements. This operation is expected to produce a new
OrderedCollection containing both left and right sides of the split operation (each
side of the split is an OrderedCollection). The developer, trying to understand this
execution, wants to obtain information about the behavior and state of instances of
OrderedCollection during the execution of the test. The standard procedure is to step
the execution until the desired object is instantiated. This potentially requires numerous
and carefully executed steps before the observation of the desired object can take place.
Moreover, the execution of this test produces several instances of OrderedCollection,
and these instantiation calls are not immediately visible in the test code. It is difficult
to track each object, as none of them is seemly stored in a variable. This makes such
manual approach even more tedious.
   Using an object-centric debugger, developers can improve over such approach by
using specific breakpoints that halts the execution whenever a class is instantiated.
With this technique, developers need to halt a certain number of times to reach the
OrderedCollection of interest. Once the object of interest has been reached, developers
can use object-centric breakpoints to observe the object’s behavior and the evolution
of its state. One downside of this technique is that it might take many halts to reach
the object of interest in the first place, and then several other object-centric breakpoints
to observe a relevant information. If the developer accidentally misses that relevant
information, then all this procedure has to be restarted from scratch.
   By using a time-traveling debugger, we can enhance this approach by navigating back
and forth in the execution. If developers miss the observation of one of the collections, or
if they passed it and want to observe it again, they reverse the execution and look for
that collection, without the need to redoing everything from the beginning.
   Object-centric debugging and time-traveling debugging both provide enhancements
over standard debugging tools on their own. We argue that they can complement each
other to improve debugging further. In the following, we start to explore how these
techniques can benefit from each other, what is required to enable this new joint approach
and how could we materialize this approach into a tool.


3. Debugging Objects Through Time with SeekerOC
In this section we present our debugger SeekerOC. We explain how it helps solving the
difficulties identified by using debugging queries and new specialized tools.

3.1. SeekerOC: Debugging with Object-centric Time-Traveling Queries
Our debugger offers a list of general purpose queries that can be conveniently executed
from a context menu. We extended this menu with new queries to ease the task of
identifying and tracking objects, as described next.
   Figure 1 shows our debugger opened at the beginning of the execution of the code
from Listing 1. To find all collections created during the execution of that code, we
select the OrderedCollection string and we execute the query All instances creation
of class named as selection from the context menu (Figure 1(a)). Once the query has
been executed, the results are displayed in a table (Figure 1(b)). These results contain
Figure 1: SeekerOC interface. To the left, the Time-Traveling Queries menu(a) available in the code
presenter. To the right, the Query Results Table(b) and its context menu(c).

the complete list of all the OrderedCollection objects that are instantiated during the
execution of the debugged program.
   From the results table, we effortlessly have access to each one of these objects by
right clicking the corresponding result item, and choosing the command inspect object
about to be instantiated (Figure 1(c)). This command opens an inspector on the object
corresponding to the selected result row, and shows the object state in the execution
state from which we executed the query. If the object has not yet been instantiated, the
execution is advanced to such event, so the object can be inspected.
   Every result entry of TTQs includes a timestamp (the step number) of every registered
event. Clicking in the step column of any result item will advance or reverse the
execution, time-traveling to the registered timestamp. This feature makes queries results
act as bookmarks of an execution, providing a practical and precise alternative to using
breakpoints and tedious stepping operations for program exploration.

3.2. The SeekerOC Inspector : A Promising Object-centric Querying Hub
Pharo traditionally offers a graphical utility for object inspection — a view that displays
information about the state of an object, its API, and other useful information. During a
SeekerOC debugging session, inspecting any object of the debugged execution will open
an enhanced version of the Pharo Inspector.
   This specialized inspector synchronizes with the time-traveling debugger to keep an
updated view of the inspected object. Stepping the execution forward or backwards
triggers updates of the displayed information. This inspector contains a menu for
object-centric queries available for the inspected object (Figure 2):

   • Time travel to instantiation instruction.
   • List all messages sent to the inspected object.
Figure 2: Object-centric time-traveling queries menu in the SeekerOC inspector: a practical access
to relevant object-centric TTQs.


      • Submenu Specific message...: displays every message selector that the object
        responds to. Clicking any particular listed selector launches a query of the type:
        List all messages sent with that specific selector to the inspected object.
      • List all assignments to the instance variables of the inspected object.
      • Submenu Specific instance variable...: displays every instance variable of the object.
        Clicking any particular listed variable name launches a query of the type: List all
        assignments to that specific instance variables of the inspected object.
      • Find all readings of self.

   Every TTQ provides a set of timestamp-indexed results in the Query Results Table.
Therefore, by clicking on the step column of every result item, we time-travel to the
timestamp of each registered event, without the inconveniences of stepping or halting.
   By using TTQs, the relevant debugging information of the execution is collected
effortlessly. This information is now directly accessible from the Query Results Table,
instead of requiring developers to go through the traditional manual debugging process.


4. Implementation
We built our experimental object-centric prototype SeekerOC upon SeekerDebugger, our
queryable time-traveling debugger implemented for Pharo. SeekerDebugger provides
the base mechanism to perform general purpose Time-Traveling Queries[10] over an
execution. SeekerOC improves upon it, offering new specialized queries that focus on
objects and their events. SeekerOC and its implementation details are available online1 .

Determinism: A hard requirement. A requirement for object-centric queries to work
is that the program must be re-executed deterministically. Determinism is ensured by
our debugger backend. Instantiated objects’ identities will remain constant upon multiple
executions. We can therefore write queries about those objects without being concerned
that objects have a different identity after being reinstantiated during a re-execution.

1
    https://github.com/Willembrinck/SeekerOC-2022/
5. Discussion: Towards Object-centric Time-traveling
   Debuggers
Our work materializes an exploration step towards a new type of debugging tool: an
object-centric time-traveling debugger, based on debugging queries. In our proposition,
Time-Traveling Queries play the central role joining object-centric and time-traveling
debugging. Querying an execution offers a traced representation of it, granting easy access
to objects. The time-traveling back-end ensures that the execution can be re-executed
following the same trace. Therefore, if an object can be identified in such trace, it can be
referenced in any re-execution of the program. This generates opportunities to explore
object-centric debugging in an new joint debugging paradigm, enabling techniques and
features previously unfeasible.
   These opportunities open many questions. Are TTQs the only mechanism required to
connect both techniques? If not, what are the required properties and/or mechanisms to
build object-centric time-traveling debuggers? What precisely are the benefits of such
debugger, and to what extent do they benefit to the debugging activity? In future work,
we plan to investigate these questions by pursuing our implementation of object-centric
TTQs and analyzing their requirements and effectiveness through empirical experiments.


6. Related Work
Object-centric debugging and time traveling debugging have been the subject of research
in the recent years. However, and to the best of our knowledge, they have never been
combined to support each other. Here we discuss how some of these works relate to ours.

Object-centric debuggers. Object Miners [11] is a set of object-centric tools to acquire,
capture and replay objects from specific expressions of a program. Developers select
(sub)expressions from the program from which objects are automatically captured and
debugged during the execution. Specific objects’ state can be recorded, then replayed
and traversed to observe the evolution of that state. While the tool allows for exploring
the past state of an object, it does not support time-traveling operations.
   Other work [12, 13] keep track of changes in objects during the execution of programs.
Developers can visualize past states of objects and their behavior. This is a post-mortem
approach without time-traveling capabilities.
Time-traveling debuggers. Expositor [4] combines scripting and time-travel debugging
to allow programmers to automate complex debugging tasks. From an execution, Expositor
generates traces that developers manipulate as lists with operations such as map and filter.
Our query model provides a similar behavior, where execution traces can be created,
operated, and evaluated to generate results. However, Expositor does not provide a tool
to visualize and exploit results, and does not support object-centric operations.
   Whyline [14, 15] offers contextual queries for program comprehension. It offers certains
object-centric queries, but they are difficult to extend. In contrast, SeekerOC is extensible
through user defined TTQs, giving developers the means to create new specialized queries.
7. Conclusion and Perspectives
In this paper we argued that time-traveling debuggers could provide support to the
practical application of object-centric debugging. We explored this concept by building
SeekerOC, a time-traveling debugger using Time-Traveling Queries. TTQs provide the
means for quick execution exploration which enhances developers capabilities for seeking
the important object-related events during debugging. Our queries include information in
their results that facilitates object identification, enabling our new proposed specialized
object-centric tools, such as the improved object Inspector and its object-centric TTQs
menu. Due to the importance of TTQs in our proposition, an interesting prospect of
research is to explore what new queries can boost object-centric debugging activities.

Acknowledgments
This work is funded by the ANR project OCRE https://anr.fr/Projet-ANR-21-CE25-0004
and Inria.

References
 [1] J. Ressia, A. Bergel, O. Nierstrasz, Object-centric debugging, in: Proceeding of the 34rd international
     conference on Software engineering, ICSE ’12, 2012.
 [2] C. Corrodi, Towards efficient object-centric debugging with declarative breakpoints, in: SATToSE
     2016, 2016.
 [3] S. Costiou, Unanticipated behavior adaptation : application to the debugging of running programs,
     Ph.D. thesis, Université de Bretagne occidentale - Brest, 2018.
 [4] K. Y. Phang, J. S. Foster, M. Hicks, Expositor: Scriptable time-travel debugging with first-class
     traces, in: 2013 35th International Conference on Software Engineering (ICSE), 2013, pp. 352–361.
 [5] Y. Wang, H. Patil, C. Pereira, G. Lueck, R. Gupta, I. Neamtiu, Drdebug: Deterministic replay
     based cyclic debugging with dynamic slicing, in: Proceedings of annual IEEE/ACM international
     symposium on code generation and optimization, ACM, 2014, p. 98.
 [6] P. Montesinos, L. Ceze, J. Torrellas, Delorean: Recording and deterministically replaying shared-
     memory multiprocessor execution efficiently, ACM SIGARCH Computer Architecture News 36
     (2008) 289–300.
 [7] C. Zamfir, G. Altekar, G. Candea, Debug determinism: The sweet spot for {Replay-Based}
     debugging, in: 13th Workshop on Hot Topics in Operating Systems (HotOS XIII), 2011.
 [8] E. T. Barr, M. Marron, Tardis: Affordable time-travel debugging in managed runtimes, in:
     Proceedings of International Conference on OOPSLA’14, volume 49, ACM, 2014, pp. 67–82.
 [9] J. Hoey, I. Lanese, N. Nishida, I. Ulidowski, G. Vidal, A case study for reversible computing:
     Reversible debugging of concurrent programs., 2020.
[10] M. Willembrinck, S. Costiou, A. Etien, S. Ducasse, Time-traveling debugging queries: Faster
     program exploration, in: 2021 IEEE 21st International Conference on Software Quality, Reliability
     and Security (QRS), 2021, pp. 642–653.
[11] S. Costiou, M. Kerboeuf, C. Toullec, A. Plantec, S. Ducasse, Object miners: Acquire, capture and
     replay objects to track elusive bugs, Journal of Object Technology 19 (2020) 1:1–32.
[12] A. Lienhard, S. Ducasse, T. Gîrba, O. Nierstrasz, Capturing how objects flow at runtime, in:
     Proceedings International Workshop on PCODA’06, 2006, pp. 39–43.
[13] A. Lienhard, T. Gîrba, O. Nierstrasz, Practical object-oriented back-in-time debugging, in: Proceed-
     ings of the 22nd ECOOP’08, volume 5142 of LNCS, Springer, 2008, pp. 592–615.
[14] A. J. Ko, B. A. Myers, Designing the whyline: a debugging interface for asking questions about
     program behavior, in: Proceedings of the 2004 conference on Human factors in computing systems,
     ACM Press, 2004, pp. 151–158.
[15] A. J. Ko, B. A. Myers, Debugging reinvented: Asking and answering why and why not questions
     about program behavior, in: In Proceedings of the 30th ICSE 08, 2008.