Time-Travel Debugging for Javascript/Node.Js

Time-Travel Debugging for Javascript/Node.Js

Time-Travel Debugging for JavaScript/Node.js Earl T. Barr Mark Marron Ed Maurer University College London, UK Microsoft Research, USA Microsoft, USA [email protected] [email protected] [email protected] Dan Moseley Gaurav Seth Microsoft, USA Microsoft, USA [email protected] [email protected] ABSTRACT Time-traveling in the execution history of a program during de- bugging enables a developer to precisely track and understand the sequence of statements and program values leading to an error. To provide this functionality to real world developers, we embarked on a two year journey to create a production quality time-traveling de- bugger in Microsoft’s open-source ChakraCore JavaScript engine and the popular Node.js application framework. CCS Concepts •Software and its engineering ! Software testing and debug- Figure 1: Visual Studio Code with extra time-travel functional- ging; ity (Step-Back button in top action bar) at a breakpoint. Keywords • Options for both using time-travel during local debugging Time-Travel Debugging, JavaScript, Node.js and for recording a trace in production for postmortem de- bugging or other analysis (Section 2.1). 1. INTRODUCTION • Reverse-Step Local and Dynamic operations (Section 2.2) Modern integrated development environments (IDEs) provide a that allow the developer to step-back in time to the previously range of tools for setting breakpoints, examining program state, and executed statement in the current function or to step-back in manually logging execution. These features enable developers to time to the previously executed statement in any frame in- quickly track down localized bugs, provided all of the relevant val- cluding exception throws or callee returns. ues remain on the call-stack and the root cause of the failure is • Reverse to Callback Origin operation (Section 2.3) that re- close to where the error manifests itself. However, they provide verses time to the line that registered the currently executing only rudimentary support to iteratively track down more difficult callback e.g. the call to setTimeout(...) where the cur- errors: developers often resort to repeatedly setting breakpoints and rently executing function was registered. rerunning the program. The dynamic nature of JavaScript and the extensive use of callbacks/promises in Node.js can make this pro- In combination with the low-overhead imposed by JARDIS (un- cess especially tedious and time-consuming. der 2% runtime increase in Section 4), these features provide a Time-traveling debuggers offer an attractive alternative to the it- system that is suitable for use as both the default debugger for erative process of debugging nontrivial errors using a traditional Node.js applications and for collecting execution histories from in- debugger. Instead of requiring developers to stop debugging, set a production deployments. Thus, JARDIS represents a major advance new breakpoint, and then reproduce the desired execution to hit that in state of the art debugging tools and provides an enabling technol- breakpoint, time-traveling debuggers allow a developer to simply ogy for related research areas including interrogative debugging, press a button to step-back in a program’s execution. We present automated fault localization, and performance profiling. JARDIS, a time-traveling debugger for JavaScript; it provides a rich set of functionality for recording and navigating the execution his- 2. FEATURES tory of a program including: JARDIS provides a range of features for debugging programs us- ing JavaScript/Node.js and improves developer productivity in both local and postmortem debugging scenarios1. 2.1 Local Debugging and Offline Recording JARDIS starts by augmenting the conventional graphical debug- ger, including its variable and call stack displays, breakpoints, and single-stepping, with the ability to reverse step through code exe- cution via its Reverse-Step button as shown in Figure 1. Preprint: This is the author’s version of the work. It is posted here for 1 personal use. The definitive version can be found at http://dl.acm.org. A video demo of JARDIS is available at [12]. 1 f u n c t i o n b a r(x){ 2 return x.g; 3 } 4 5 f u n c t i o n foo(){ 6 var v= undefined ; 7 t r y 8 { bar(v);} 9 catch (e) 10 { /*bp2*/ c o n s o l e.log( ’fail’ +e);} 11 } 12 13 b a r({g: 10 }); 14 /*bp1*/ c o n s o l e.log( ’success’ ); Figure 2: Remote recording with a telemetry service, followed 15 16 s e t T i m e o u t(foo, 10); by postmortem debugging at full fidelity. Figure 3: Reverse-Step (rs) vs. Reverse-Step Dynamic (rsd). JARDIS also supports postmortem debugging, as shown in the workflow in Figure 2. In this scenario, the developer runs their application under JARDIS’s record mode when deployed to their 2.3 Callback Reverse to Origin users, given their consent. When an error occurs, the execution JavaScript and Node.js code use callbacks (also called promises trace is sent to the specified location for debugging later. The col- or continuations) extensively. Debugging this code can be chal- lected trace has sufficient information to replay the execution of lenging as the control flow is difficult to reconstruct: code regis- the program exactly, including any non-determinism, and show the tered at one point in a program’s execution is invoked by the event value of any JavaScript program variable that the developer might loop later, sometimes much later. When a developer is at a break- be interested in. Thus, the debugging experience is the same as if point in some callback code, they may not, therefore, know where the developer had a debugger attached to the remote Node.js pro- or why this callback code was registered, what the program state cess when the trace was collected. was at that time, or why the callback was was eventually invoked. To record the trace, the developer simply invokes Node with an To address this challenge, JARDIS provides its reverse to callback additional command line flag, -TTRecord:[uri], where the uri origin (rcbo) operation. This operation allows the developer to parameter indicates the location (a file or remote server) to save the travel back from the currently executing callback to the point in trace. By default, we continuously record approximately the most time when the callback was registered. To illustrate this operation, recent 2–4 seconds of execution in a ring buffer and save the data if consider the code in Figure 3. If current break statement is at line an unhandled exception occurs, a call to process.exit is made, 10, labeled bp2, then the rcbo operation reverse-executes to the or a dump is explicitly requested by the the application. All of these line with the setTimeout where the callback to foo was registered parameters can be adjusted as desired. (line 16). Later, the developer can load and debug the serialized trace by invoking the replay host with TTDebugHost [uri] and attaching 3. IMPLEMENTATION a debugger. In Figure 2, Visual Studio Code [23] is configured to JARDIS is part of Microsoft’s ChakraCore JavaScript engine [7] do this and execute the code/trace to the point where the exception and a fork of the Node.js runtime environment [18]. The overall is thrown. When this point is reached, the debugging experience system design is a record-replay-snapshot architecture [2, 10, 16]. is virtually identical to the standard local debugging scenario: the The snapshot algorithm is based on [2] with the record-replay work developer can inspect any value of interest, view the stack frame, done in the JsRT hosting API layer [14] that Node.js uses to in- set breakpoints, step forward/back in the code, and even evaluate terface with the JavaScript runtime. The snapshot code and the expressions in the watch window. record-replay code involves approximately 20 kloc in the Chakra- Core codebase. We added less than 100 lines of code to the Node.js 2.2 Reverse-Step Operations codebase. Source code is available online [7, 18]. The first type of reverse-step operation, and most commonly use- As Figure 4 shows, a Node.js process consists of the Chakra- ful operation, provided by the JARDIS tool is a reverse-step (rs) to Core JavaScript engine and the Node.js runtime hosting environ- the previously executed line in the current call frame. This is sim- ment. The ChakraCore engine executes the application JavaScript ply the reverse version of the forward step provided by existing code, while the Node host manages all interactions with the envi- graphical and command line debuggers. The next type of reverse ronment including, file and network IO, callback scheduling, and operation provided by JARDIS is reverse-step dynamic (rsd) which OS resources. The Node host interacts with the ChakraCore engine acts as the reverse version of step-into operations in existing debug- via the JsRT API, which allows the Node host to create/inspect ob- gers. This operation steps-back in time to the previously executed jects, invoke JavaScript functions, and create JavaScript function statement in any frame. wrappers that call back into native host code when invoked. To illustrate the various use cases for these operations and how they differ, consider the code in Figure 3. If the current breakpoint 3.1 Record and Replay is at line 14, labeled bp1, then the rsd operation reverse-executes To record the full range of events needed to replay the execu- to the return statement of the previously called method (line 2 in tion of the JavaScript component of the program, we added logging bar) while the rs operation reverse-executes to line 13.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    5 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us