Skip to content
mskrzypkows edited this page Jun 16, 2015 · 21 revisions

Debugging with gdb

Just run servo with 'debug' option:

./mach run --dev --debug

Now you can set breakpoints etc. To run browser specify URL, e.g.:

r http://en.wikipedia.org

Debugging with rr

There are also mach commands for running Servo under rr:

./mach rr-record
./mach rr-replay

Debugging task failure

Task failure (e.g. fail!) results in a call to the C function rust_fail. I wrote a small script to automate the process of putting a breakpoint on this function to get a backtrace. Use it like

rust-backtrace ./servo foo.html

Debugging X Windows errors

You can break on _XDefaultError.

To make X requests synchronous, set _Xdebug = 1. In GDB:

(gdb) print _Xdebug = 1

The program needs to be running for the symbol to be loaded, so break on main or something and do it there.

Source information

If you build Servo with ../configure --enable-debug then the binaries will include source line information. So for example you can do

objdump -Srd build/*/src/components/script/libscript-*.so

and see the assembly interleaved with Rust source from the script crate.

To see the rustc command lines during build, use make VERBOSE=1.

Finding memory errors with Valgrind

You can run Valgrind like so:

valgrind --soname-synonyms=somalloc=NONE --smc-check=all-non-file --num-callers=50 --log-file=valgrind.out --suppressions=../../notes/valgrind.suppression ./servo ../src/test/html/about-mozilla.html

The --soname-synonyms flag fixes an incompatibility with jemalloc and requires a fairly recent version of Valgrind. See this article.

The --smc-check flag is necessary to instrument the code dynamically produced by SpiderMonkey. Otherwise SpiderMonkey can crash or hit assertion failures. See #980.

The suppressions file is here; it just excludes things from i965_dri.so, and not very well.

Even with the suppressions file I get some irrelevant errors from graphics drivers etc, so I also postprocess the output of Valgrind with this script:

#!/usr/bin/env python
import sys
import re

blocks = [[]]

for ln in sys.stdin:
    ln = ln.rstrip()
    m = re.match(r'^==\d+==', ln)
    assert m
    ln = ln[m.end():]
    if not ln:
        blocks.append([])
    blocks[-1].append(ln)

exclude = ['libdrm.so.2.4.0', 'i965_dri.so', '_dl_start']

for b in blocks:
    if not any(any(e in ln for e in exclude) for ln in b):
        for ln in b:
            print ln
Clone this wiki locally