Skip to content

Debugging Firefox Tips

Martin Sirringhaus edited this page Feb 21, 2023 · 6 revisions

Some helpful tips when debugging Firefox

Building with mach

Build dependencies

Note: At the time of writing the patch to make ./mach bootstrap know openSUSE was not yet released but already worked on upstream. So hopefully this will be there soon.

./mach bootstrap will not only install all build-dependencies you need, but also set up some rather nice mercurial-helpers and so on.

If you are unlucky enough to not have bootstrap, just have a look at the Firefox spec-file and the BuildRequires-portions and install those.

mozconfig

The file mozconfig determines all build-settings and flags. In case you want to just try a normal build, an empty mozconfig is fine.

But usually, you want to debug some (open)SUSE specific problem and want to build it as specified in the spec-file.

For this, there is the script get_mozconfig_from_spec in https://github.com/openSUSE/firefox-scripts.

Just hand it the spec-file of the correct version, the (open)SUSE-product you want to build for and optionally the architecture with --target=$ARCH.

It will echo the mozconfig that would be used by OBS. You can simply pipe the output there:

get_mozconfig_from_spec /path/to/MozillaFirefox.spec 1500 2> /dev/null > mozconfig

To use it you have to:

  1. Delete the first line which is output from rpmbuild
  2. Comment out ac_add_options --with-l10n-base=...
  3. Comment out all options containing %{SOURCE..}
  4. Depending on your setup, you might want to change mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/../obj to something containing the version you are building, e.g. ../obj-esr68 or have the obj/-dir directly in the source code and not in the parent directory. Otherwise you might share the build-dir from different Firefox-versions, leading to all kinds of weirdness.

Local optimizations

get_mozconfig_from_spec also makes suggestions of additional compile-options that might be beneficial for local debug builds at the end of the file.

Simply uncomment them to use them.

You also might need to --enable-debug and --enable-optimize="-Og -g" for debugging.

Patching Rust crates

In case you modify vendored rust crates, cargo/mach will not let you build, due to checksummed sources.

To make this work, you have to add to the top-level Cargo.toml-file (where mach and mozconfig are) under the section [patch.crates-io]:

[patch.crates-io]
# ...
YOUR-CRATE = { path = './third_party/rust/YOUR-CRATE' }

Layout debugger

Firefox comes with a feature for debugging layer-related things. It can be started by handing in --layoutdebug, e.g. by calling

./mach run -- --layoutdebug

This has multiple advantages: It can dump all current content (or chrome) layers, and it uses a minimalistic frontend (less graphics functions called, because of the chrome), which helps debugging.

Logger-output

Firefox has lots of debugging output, but it does not show per default.

Some more output is shown, if you compile with --enable-debug, but still only very little.

Additionall loggers can be activated by starting Firefox with -MOZ_LOG <YourDebugger:LEVEL>

If you have a rough idea of where in the codebase you want more output, go looking for LOG, or MOZ_LOG, or MSE_DEBUG or similar macros in the code.

Search the macro-definition. It should be a LazyLogModule object associated with it. This one has a name associated with it (a string-value). That is the name to use for -MOZ_LOG.

Example:

static mozilla::LazyLogModule sFormatDecoderLog("MediaFormatReader");
mozilla::LazyLogModule gMediaDemuxerLog("MediaDemuxer");

#define LOG(arg, ...)                                                  \
  DDMOZ_LOG(sFormatDecoderLog, mozilla::LogLevel::Debug, "::%s: " arg, \
            __func__, ##__VA_ARGS__)
#define LOGV(arg, ...)                                                   \
  DDMOZ_LOG(sFormatDecoderLog, mozilla::LogLevel::Verbose, "::%s: " arg, \
            __func__, ##__VA_ARGS__)

So, if you want to see the output of "LOG()"-statements, you have to start firefox with ./mach run -MOZ_LOG MediaFormatReader:5, to see "LOGV()"-output, you need to run ./mach run -MOZ_LOG MediaDemuxer:3

Or both with ./mach run -MOZ_LOG MediaFormatReader:5,MediaDemuxer:3

Rust log output

Rust log output is handled by RUST_LOG. Here, one can also filter according to level and service.

RUST_LOG=debug will output debug-level output for ALL Rust services, which is usually a lot. It's better to also filter for the specific service one needs: RUST_LOG=authenticator=debug.

This can also be added to the run-command: ./mach run --set-env RUST_LOG=authenticator=debug

Graphics debug output

Throughout the code that deals with painting elements, there are defines such as MOZ_DUMP_PAINTING. These usually are enclosing if-statements that look like if (gfxEnv::DumpPaintItems()) {...}.

If you have build in debug-mode, to activate this, you merely have to export the associated environment-variable before starting Firefox.

These variables can be found here: gfx/thebes/gfxEnv.h

In the above example it would be export MOZ_DUMP_PAINT_ITEMS=1 before starting Firefox.

NOTE: This can be very verbose!