Fork me on GitHub

What is Jalangi

Jalangi is a Dynamic Analysis Framework for both front-end and back-end JavaScript. It allows you to monitor every operation of a JavaScript program and write your own program analysis code.

Technical Details

Jalangi Firefox extension intercepts and transforms every line of JavaScript code in the webpage and external files. The code transformation adds hooks that allows you to monitor almost every operation (e.g., variable read/write, unary/binary operation, function/method call, etc.) performed by the execution. Simply overriding the API exposed allows you to perform your own dynamic analysis. Your dynamic analysis code will be executed side-by-side with the target program's execution.

Broad Impact and Applications

JavaScript is a loosely typed language which is often error-prune. Based on this framework, you can quickly build a analysis module to check different kinds of correctness bugs and performance bugs, doing various program analysis (e.g., debugging, Performance analysis, Monitoring dynamic behaviours, Record and replay, runtime call graph etc.)

Jalangi in a Nutshell:

Jalangi Firefox extension intercepts and transforms every line of JavaScript code loaded by the browser to expose hooks to facilitate program analysis.

The figure on the right-hand side shows the original code snippet and transformed code snippet. Function J$.W and J$.R are callback functions (i.e., hooks) for notifying the read and write operation of variables, the parameters of the callback function include the variable name and value. Similarly callback function. Those callback functions invoke specially designed dummy functions which will be exposed as API to facilitate user-defined dynamic analysis. Overriding those API functions will allow analysis code to be executed along the original execution.

Jalangi Firefox Extension

Different from server-side JavaScript (Node.js), in a web browser, a JavaScript statement can be added at any time in various ways (as shown on the left). Our Firefox Extension handles all those possibilities and we are confident that every line of JavaScript code in a web page has been intercepted and transformed. Moreover, our extension also work well with web pages that use HTML5 webworker which is multi-threading API for front-end JavaScript. See more about this extension here.

API Exposed:

To quickly prototype and test a dynamic analysis, use the interactive demo page. To install Jalangi on your local machine (Mac OS or Linux is recommended), please visit the project's GitHub repository. More detailed Documentation of each Jalangi API is available here. To use Jalangi on Node.js with command line, please read the document here.
To use Jalangi2, see Jalangi2 API.

API Description
invokeFun(iid, f, base, args, val, isConstructor) callback when invoking a function or method
getFieldPre(iid, base, offset) callback before getting field of an object
getField(iid, base, offset, val); callback when getting field of an object, need return value val
putFieldPre(iid, base, offset, val) callback before putting field of an object, need return value val
putField(iid, base, offset, val) callback when putting field of an object, need return value val
return_(ret) callback when returning function without a return value, need return value ret
return_Rt(iid, val) callback when returning function with a return value, need return value val
scriptEnter(iid, val) callback when entering a script file
scriptExit(iid) callback when exitting a script file
literalPre(iid, val) callback before creating a literal object
literal(iid, val) callback when creating a literal object
readPre(iid, name, val, isGlobal) callback before before reading a variable
read(iid, name, val, isGlobal) callback when reading a variable, need return value val
writePre(iid, name, val, lhs) callback before writing a variable
write(iid, name, val, lhs) callback when writing a variable
declare(iid, name, val, isArgumentSync) callback when declaring a variable
binaryPre(iid, op, left, right) callback before doing a binary operation
binary(iid, op, left, right, result_c) callback when doing a binary operating, need return value result_c
unaryPre(iid, op, left) callback before doing a unary operation
unary(iid, op, left, result_c) callback when doing a unary operation, need return value result_c
conditionalPre(iid, left) callback before evaluating a conditional statement
conditional(iid, left, ret) callback when evaluating a conditional statement

Publication

Liang Gong, Michael Pradel, and Koushik Sen, "JITProf: Pinpointing JIT-unfriendly JavaScript Code", FSE, 2015 (To Appear). preprint | technical report

Koushik Sen, George Necula, Liang Gong, and Wontae Choi, "MultiSE: Multi-path Symbolic Execution Using Value Summaries", FSE 2015 (To Appear). pdf | slides

Liang Gong, Michael Pradel, Manu Sridharan, and Koushik Sen, "DLint: Dynamically Checking Bad Coding Practices in JavaScript", ISSTA. 2015. pdf | slides

Michael Pradel, and Koushik Sen, "The Good, the Bad, and the Ugly: An Empirical Study of Implicit Type Conversions in JavaScript", ECOOP, 2015.

Michael Pradel, Parker Schuh, and Koushik Sen, "TypeDevil: Dynamic Type Inconsistency Analysis for JavaScript", ICSE, 2015. pdf

Michael Pradel, Parker Schuh, George Necula, and Koushik Sen, "EventBreak: Analyzing the Responsiveness of User Interfaces through Performance-Guided Test Generation", OOPSLA 2015. pdf

Koushik Sen, Swaroop Kalasapur, Tasneem Brutch, and Simon Gibbs, "Jalangi: A Selective Record-Replay and Dynamic Analysis Framework for JavaScript," in Proc. 9th joint meeting of the European Software Engineering Conference and the ACM SIGSOFT Symposium on the Foundations of Software Engineering (ESEC/FSE'13), 2013. pdf

Koushik Sen, Swaroop Kalasapur, Tasneem Brutch, and Simon Gibbs, "Jalangi: A Tool Framework for Concolic Testing, Selective Record-Replay, and Dynamic Analysis of JavaScript," in Proc. 9th joint meeting of the European Software Engineering Conference and the ACM SIGSOFT Symposium on the Foundations of Software Engineering (ESEC/FSE'13), 2013. (Tool Paper) pdf

Download source code:

Source code of Jalangi are available at the Github Repository.

Jalangi Firefox Extension Project Members

Koushik Sen
ksen (at) cs.berkeley.edu

Liang Gong
gongliang13 (at) eecs.berkeley.edu

How to Install:

To install the tool, install Mozilla Firefox and then download the XPI package.

Note: A recent change in Firefox API breaks the firefox extension, use this firefox extension with Firefox 33 or ealier.
Remember to disable the automatic update.

Another option is using DLint which includes a modified version of Firefox to do instrumentation before JavaScript code is compiled in the SpiderMonkey engine.

Drag the XPI file into Firefox Addon Manager.

Now you are good to go!

A Simple Tutorial:

In most JavaScript engines, generating a NaN error does not raise an exception, sometimes this kind of bugs can be subtle and hard to diagnose. Based on Jalangi analysis framework, this tutorial shows how to write a analysis module that detects NaN (Not a Number) bugs.

A Simple NaN error check module:
                                 
J$.analysis = {    
    putFieldPre: function (iid, base, offset, val) {
        if(typeof base != 'undefined' && base != null && (typeof val == 'number') && isNaN(val) == true){
            console.log('[NaN iid: ' + iid +'] ' + base + '.' + offset + ':' + val);
        }
        return val;
    }
}
                        
                    

In the code above, we override the J$.analysis method putFieldPre which is the callback function whenever after the target code access a field of an object or a function. In the callback function, we just check if the field we read has a NaN value, if it is, then we generate a warning indicating the location information (Index ID, short name iid), object and field information for manual checking and debugging. With similar checking code, we also override callback functions to monitor object field write, variable read and variable write to detect NaN values.

Now visit a website using the Firefox with Jalangi extension installed (Note that every line of code has been transformed):

Copy and paste the analysis module shown above into the web console, this will plug the analysis module we wrote into the transformed program:

After integrating the analysis module into our framework (after pasting it into web console), we can start checking NaN bugs on any websites by interacting with the current loaded page. We found a bug in jQuery-1.8.3 by running a popular UI framework website with the analysis module and the following warning periodically pops out in the console:

Looking into its source code and tracing to its root cause shows that this commercial website used an early version of jQuery. In the jQuery external file, the following statement gets executed periodically to update the now field of an object.

this.now=(this.end-this.start)*t;

The field was supposed to be a number and to record the time elapsed by substrate the start timestamps from the end timestamps, further diagnosis shows that sometimes this.end could return a string value (e.g., '30\% 0'). Consequently (this.end-this.start)*t becomes NaN which propagates to this.now.