简体   繁体   中英

How to make Firefox startup faster in GDB

I have a large number of HTML files to debug. I wrote a python GDB script and call gdb ./path/to/firefox and open each of the HTML files within Firefox, then run the script to do what I want. The problem is this process is super slow. I am wondering is there a faster way to do this.

I noticed that everything else is fairly fast except the point after gdb outputs the following:

$ gdb ../firefox-63.0.3/objdir-ff-dbg/dist/bin/firefox
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ../firefox-63.0.3/objdir-ff-dbg/dist/bin/firefox...done.
(gdb) set args file:///home/ug16zy2/test.html 
(gdb) r
Starting program: /home/ug16zy2/firefox-63.0.3/objdir-ff-dbg/dist/bin/firefox file:///home/ug16zy2/test.html 
warning: Error disabling address space randomization: Operation not permitted
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Then I need to wait for a long time (around 20 seconds) until it outputs the next line:

Loading JavaScript value pretty-printers; see js/src/gdb/README.
If they cause trouble, type: disable pretty-printer .* SpiderMonkey
SpiderMonkey unwinder is disabled by default, to enable it type:
    enable unwinder .* SpiderMonkey

What is GDB doing and how can I avoid whichever is taking such a long time?

PS: I need to use GDB because I want to stop the process when a specific line in JS code is executed. Unfortunately the line is inside a callback registered with an event listener. The problem boils down to stopping Firefox when an event listener is triggered AND its callback function finishes execution. (If there is any other alternative that can achieve the same thing, pls let me know :) Many thanks!)

As the other answer states, the problem is that gdb is naive about debuginfo caching. And, because libxul is so large, it takes a noticeable amount of time.

If you have gdb 8.3 or later, you can fix this somewhat by using the new index-cache feature. To use it just type:

(gdb) set index-cache on

... or put it in your ~/.gdbinit for best effect.

The index cache will write an index for the debuginfo to a file in a cache directory (type show index-cache directory to see where). This should speed up re-reading.

Note that nothing prunes the index cache right now -- this is the major drawback. So, you will want to occasionally delete old files here. This lack of pruning is one reason that the cache isn't enabled by default.

What is GDB doing and how can I avoid whichever is taking such a long time?

There are a few things that are happening here:

  1. GDB reads debug info for firefox binary itself, then runs it.
  2. When firefox loads shared libraries, the dynamic loader notifies GDB about them, and GDB reads debug info for them.
  3. When libpthread is loaded, GDB loads libthread_db and sets it up to notify GDB about thread creation and destruction events (this is when Using host libthread_db message is printed).
  4. firefox initializes itself.
  5. firefox starts actually running (doing useful work).

You can see more of GDB's actions with set verbose on .

I am guessing that firefox binary is directly linked with only a few shared libraries, and dlopen s the majority of required libraries after it starts running (ie during step 4 above).

I am further guessing that some of the libraries are large, and it takes a while to load debug info for them.

If, after set verbose on , you see that above guesses are correct, you can disable auto-loading of symbols for shared libraries with set auto-solib-add off . You can then add just the libraries that you need symbols for (if any) with sharedlibrary libfoo command.

Update:

It is actually taking a majority of the time loading symbol from libxul.so. However I guess I need it in order to debug Firefox. Is there a way of preloading those symbols or avoiding loading this library every time?

I thought it would help to turn your script "inside out" -- to start a single GDB session, and execute repeated run commands with different arguments from inside that session.

But I am not sure that would actually help: last time I worked on GDB, it discarded and re-read all the DSOs on inferior (being debugged) program restart.

If GDB still does that, the only solutions I can think of are:

  1. Try using LLDB instead. It may be faster, or it may work with "inside out" script.
  2. Build libxul.so with less debug info (ie add -g only for the files that you need for your debugging, and build the rest of the files with -g0 ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM