• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

lib-for-tests/H01-Sep-2019-12775

mozilla/H01-Sep-2019-2,0361,268

tests/H01-Sep-2019-924624

READMEH A D01-Sep-20197.1 KiB199156

TODOH A D01-Sep-2019770 2320

gdb-tests-gdb.py.inH A D01-Sep-2019277 128

gdb-tests.cppH A D01-Sep-20193.3 KiB10772

gdb-tests.hH A D01-Sep-20193.5 KiB9742

moz.buildH A D01-Sep-20191.6 KiB5947

progressbar.pyH A D01-Sep-20191.6 KiB4935

run-tests.pyH A D01-Sep-201912.9 KiB350262

taskpool.pyH A D01-Sep-20198.6 KiB220138

README

1This directory holds Python code to support debugging SpiderMonkey with
2GDB. It includes pretty-printers for common SpiderMonkey types like jsval,
3jsid, and JSObject, and makes GDB "see through" the SpiderMonkey rooting
4types like js::Rooted and JS::Handle. For example:
5
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	    MOZ_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_UNQUALIFIED)) == 0);
13    (gdb)
14
15Things to note here:
16
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.
21
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.
25
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.
30
31You can still see the raw form of a value with 'print/r':
32
33    (gdb) p/r obj
34    $1 = {<js::HandleBase<JSObject*>> = {<No data fields>}, ptr = 0x7fffffffca60}
35    (gdb)
36
37You can also use GDB's 'disable pretty-printer' command to turn off
38individual pretty-printers; try 'info pretty-printer' first.
39
40GDB should pick these extensions up automatically when you debug the shell, by
41auto-loading the 'js-gdb.py' file that js/src/shell/Makefile.in places in the
42same directory as the 'js' executable. You may need to add a command like the
43following to your '$HOME/.gdbinit' file:
44
45    # Tell GDB to trust auto-load files found under ~/moz.
46    add-auto-load-safe-path ~/moz
47
48If you do need this, GDB will tell you.
49
50In general, pretty-printers for pointer types include a summary of the
51pointer's referent:
52
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)
67
68We used to also have pretty-printers for the actual contents of a JSString
69struct, that knew which union branches were live and which were dead. These were
70more fragile than the summary pretty-printers, and harder to test, so I've
71removed them until we can see how to do better.
72
73There are unit tests; see 'Running the unit tests', below.
74
75I'd love for others to pitch in. GDB's Python API is documented in the GDB
76manual.
77
78I've recently rewritten the printers. The new code is simpler, and more
79robust; unit tests are easier to write; and the new test harness can run
80the tests in parallel. If a printer you'd contributed to in the past was
81dropped in the process, I apologize; I felt we should have good test
82coverage for any printer landed in-tree. You may also be interested in
83'Personal pretty-printers', below.
84
85Directory layout
86----------------
87
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.
94
95In js/src/gdb:
96
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.
102
103Personal pretty-printers
104------------------------
105
106If you'd like to write your own pretty-printers, you can put them in a
107module named 'my_mozilla_printers' in a directory somewhere on your Python
108module search path. Our autoload code tries to import 'my_mozilla_printers'
109after importing our other SpiderMonkey support modules. For example:
110
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
116
117    # Simple char16_t * printer. Doesn't show address; chases null pointers.
118    @ptr_pretty_printer('char16_t')
119    class char16Ptr(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 = char16_t [4]
132    (gdb) print &sample[0]
133    $1 = "Hi!"
134
135Running the unit tests
136----------------------
137
138These extensions have unit tests, invoked as follows:
139
140$ python run-tests.py [OPTIONS] OBJDIR [TESTS...]
141
142where OBJDIR is a directory containing a standalone SpiderMonkey build; TESTS
143are names of selected tests to run (if omitted, we run them all); and OPTIONS
144are drawn from the list below.
145
146--gdb=EXECUTABLE
147  Instead of running whatever 'gdb' we find in our search path, use
148  EXECUTABLE to run the tests.
149
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.)
156
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'.
161
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.
165
166(It is safe to use relative paths for LIBDIR, SRCDIR, and so on. They are
167always interpreted relative to the directory that was current when
168run-tests.py was started.)
169
170For example, since I build in a subdirectory 'obj~' of the 'js/src'
171directory, I use this command from 'js/src' to run the pretty-printer unit
172tests:
173
174  $ python gdb/run-tests.py obj~
175
176Writing new unit tests
177----------------------
178
179Each unit test consists of a Python script, possibly with some accompanying
180C++ code. Running tests works like this:
181
182- The run-tests.py script calls 'make' in 'BUILDDIR/gdb' to build
183  'gdb-tests'.
184
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/prologue.py, passing it the test script's path as
188  its first command-line argument.
189
190Thanks To:
191----------
192
193- David Anderson
194- Steve Fink
195- Chris Leary
196- Josh Matthews
197- Jason Orendorff
198- Andrew Sutherland
199