Skip to content
Keegan McAllister edited this page Oct 18, 2013 · 10 revisions

Debugging task failure

Task failure (e.g. fail!) results in a call to the C function rust_begin_unwind. 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

Source information

If you build Servo with make RUSTFLAGS="-Z debug-info" 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.

EDIT: I think this happens by default now.

To see the rustc command lines, 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

Other memory debugging

Also you can edit src/compiler/rust/src/rt/memory_region.h and set RUSTRT_TRACK_ALLOCATIONS to 3 and then run with DETAILED_LEAKS=1, and also probably apply this commit and the previous one. Then when free goes wrong, it will print a backtrace of where that object was allocated, assuming you're talking about things allocated by the Rust RT.

Alas I didn't find that information to be very useful; it's easy enough to guess where something was allocated, anyway, but hard to figure out where we failed to increment a refcount or something.

Clone this wiki locally