-
Notifications
You must be signed in to change notification settings - Fork 0
Debugging
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
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
.
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
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.