js/src/gdb/README

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 This directory holds Python code to support debugging SpiderMonkey with
     2 GDB. It includes pretty-printers for common SpiderMonkey types like jsval,
     3 jsid, and JSObject, and makes GDB "see through" the SpiderMonkey rooting
     4 types like js::Rooted and JS::Handle. For example:
     6     (gdb) frame
     7     #0  js::baseops::SetPropertyHelper (cx=0xbf3460,
     8         obj=(JSObject * const) 0x7ffff150b060 [object global] delegate,
     9         receiver=(JSObject * const) 0x7ffff150b060 [object global] delegate,
    10         id=$jsid("x"), defineHow=4, vp=$jsval(1), strict=0)
    11         at /home/jimb/moz/archer/js/src/jsobj.cpp:4495
    12     4495	    JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_UNQUALIFIED)) == 0);
    13     (gdb)
    15 Things to note here:
    17 - obj, a JS::HandleObject, prints as:
    18       obj=(JSObject * const) 0x7ffff150b060 [object global] delegate,
    19   This immediately shows the handle's referent, along with a JavaScript-like summary
    20   of the object.
    22 - id, a JS::HandleId, prints as:
    23       id=$jsid("x"),
    24   We show the handle's referent, and print the identifier as a string.
    26 - vp, a JS::MutableHandleValue, prints as:
    27       vp=$jsval(1)
    28   We show the handle's referent, using the jsval's tag to print it in its
    29   JavaScript form.
    31 You can still see the raw form of a value with 'print/r':
    33     (gdb) p/r obj
    34     $1 = {<js::HandleBase<JSObject*>> = {<No data fields>}, ptr = 0x7fffffffca60}
    35     (gdb)
    37 You can also use GDB's 'disable pretty-printer' command to turn off
    38 individual pretty-printers; try 'info pretty-printer' first.
    40 GDB should pick these extensions up automatically when you debug the shell, by
    41 auto-loading the 'js-gdb.py' file that js/src/shell/Makefile.in places in the
    42 same directory as the 'js' executable. You may need to add a command like the
    43 following to your '$HOME/.gdbinit' file:
    45     # Tell GDB to trust auto-load files found under ~/moz.
    46     add-auto-load-safe-path ~/moz
    48 If you do need this, GDB will tell you.
    50 In general, pretty-printers for pointer types include a summary of the
    51 pointer's referent:
    53     (gdb) b math_atan2
    54     Breakpoint 1 at 0x542e0a: file /home/jimb/moz/archer/js/src/jsmath.cpp, line 214.
    55     (gdb) run
    56     js> Math.atan2('Spleen', 42)
    57     Breakpoint 1, math_atan2 (cx=0xbf3440, argc=2, vp=0x7ffff172f0a0)
    58     (gdb) print vp[0]
    59     $1 = $jsval((JSObject *) 0x7ffff151c0c0 [object Function "atan2"])
    60     (gdb) print vp[1]
    61     $2 = $jsval((JSObject *) 0x7ffff150d0a0 [object Math])
    62     (gdb) print vp[2]
    63     $3 = $jsval("Spleen")
    64     (gdb) print vp[3]
    65     $4 = $jsval(42)
    66     (gdb)
    68 We used to also have pretty-printers for the actual contents of a JSString
    69 struct, that knew which union branches were live and which were dead. These were
    70 more fragile than the summary pretty-printers, and harder to test, so I've
    71 removed them until we can see how to do better.
    73 There are unit tests; see 'Running the unit tests', below.
    75 I'd love for others to pitch in. GDB's Python API is documented in the GDB
    76 manual.
    78 I've recently rewritten the printers. The new code is simpler, and more
    79 robust; unit tests are easier to write; and the new test harness can run
    80 the tests in parallel. If a printer you'd contributed to in the past was
    81 dropped in the process, I apologize; I felt we should have good test
    82 coverage for any printer landed in-tree. You may also be interested in
    83 'Personal pretty-printers', below.
    85 Directory layout
    86 ----------------
    88 - js/src/gdb/mozilla: The actual SpiderMonkey support code. GDB auto-loads this
    89   when you debug an executable or shared library that contains SpiderMonkey.
    90 - js/src/gdb/tests: Unit tests for the above.
    91   - Each '.py' file is a unit test, to be run by js/src/gdb/run-tests.py.
    92   - Each '.cpp' file contains C++ code fragments for some unit test to use.
    93 - js/src/gdb/lib-for-tests: Python modules used by the unit tests.
    95 In js/src/gdb:
    97 - run-tests.py: test harness for GDB SpiderMonkey support unit tests. See
    98   'Running the unit tests', below.
    99 - taskpool.py, progressbar.py: Python modules used by run-tests.py.
   100 - gdb-tests.cpp, gdb-tests.h: Driver program for C++ code fragments.
   101 - gdb-tests-gdb.py.in: Template for GDB autoload file for gdb-tests.
   103 Personal pretty-printers
   104 ------------------------
   106 If you'd like to write your own pretty-printers, you can put them in a
   107 module named 'my_mozilla_printers' in a directory somewhere on your Python
   108 module search path. Our autoload code tries to import 'my_mozilla_printers'
   109 after importing our other SpiderMonkey support modules. For example:
   111     $ echo $PYTHONPATH
   112     /home/jimb/python
   113     $ cat ~/python/my_mozilla_printers.py
   114     import gdb
   115     from mozilla.prettyprinters import ptr_pretty_printer
   117     # Simple jschar * printer. Doesn't show address; chases null pointers.
   118     @ptr_pretty_printer('jschar')
   119     class jscharPtr(object):
   120         def __init__(self, value, cache): self.value = value
   121         def display_hint(self): return 'string'
   122         def to_string(self):
   123             c = u''
   124             for i in xrange(50):
   125                 if self.value[i] == 0: break
   126                 c += unichr(self.value[i])
   127             return c
   128     $
   129     ...
   130     (gdb) whatis sample
   131     type = jschar [4]
   132     (gdb) print &sample[0]
   133     $1 = "Hi!"
   135 Running the unit tests
   136 ----------------------
   138 These extensions have unit tests, invoked as follows:
   140 $ python run-tests.py [OPTIONS] LIBDIR [TESTS...]
   142 where LIBDIR is a directory containing a compiled SpiderMonkey library,
   143 libmozjs.so; TESTS are names of selected tests to run (if omitted, we run
   144 them all); and OPTIONS are drawn from the list below.
   146 --gdb=EXECUTABLE
   147   Instead of running whatever 'gdb' we find in our search path, use
   148   EXECUTABLE to run the tests.
   150 --srcdir=SRCDIR
   151   Find the sources corresponding to LIBDIR/libmozjs.so in SRCDIR. Without
   152   this option, we use the parent of the directory containing
   153   'run-tests.py'. Note that SRCDIR must be a complete SpiderMonkey source
   154   directory, as our tests #include internal SpiderMonkey header files (to
   155   test pretty-printers for internal types, like parse nodes.)
   157 --testdir=TESTDIR
   158   Search for Python scripts and any accompanying C++ source code in
   159   TESTDIR. If omitted, we use the 'tests' directory in the directory
   160   containing 'run-tests.py'.
   162 --builddir=BUILDDIR
   163   Build the C++ executable that GDB debugs to run the tests in BUILDDIR.
   164   If omitted, create a 'gdb-tests' subdirectory of LIBDIR.
   166 (It is safe to use relative paths for LIBDIR, SRCDIR, and so on. They are
   167 always interpreted relative to the directory that was current when
   168 run-tests.py was started.)
   170 For example, since I build in a subdirectory 'obj~' of the 'js/src'
   171 directory, I use this command from 'js/src' to run the pretty-printer unit
   172 tests:
   174   $ python gdb/run-tests.py obj~
   176 Writing new unit tests
   177 ----------------------
   179 Each unit test consists of a Python script, possibly with some accompanying
   180 C++ code. Running tests works like this:
   182 - The run-tests.py script calls 'make' in 'BUILDDIR/gdb' to build
   183   'gdb-tests'.
   185 - Then, for each '.py' test script in js/src/gdb/tests, the harness starts
   186   GDB on the 'gdb-tests' executable, and then has GDB run
   187   js/src/gdb/lib-for-tests/prolog.py, passing it the test script's path as
   188   its first command-line argument.
   190 Thanks To:
   191 ----------
   193 - David Anderson
   194 - Steve Fink
   195 - Chris Leary
   196 - Josh Matthews
   197 - Jason Orendorff
   198 - Andrew Sutherland

mercurial