Debugging B2G using gdb and related tools

  • Revision slug: Mozilla/Boot_to_Gecko/Debugging_on_Boot_to_Gecko/Debugging_B2G_using_gdb
  • Revision title: Debugging B2G using gdb
  • Revision id: 327321
  • Created:
  • Creator: bjacob
  • Is current revision? No
  • Comment

Revision Content

{{draft()}}

Debugging Firefox OS using gdb is easy. This article will help make it even more so.

Starting the debugger in single-process mode

Note: Before running the debugger, you may want to set up a .userconfig file to customize things. See Customization with the .userconfig file for details.

To restart Firefox OS and run it under gdb control, simply use the run-gdb.sh script:

./run-gdb.sh

Note: If you want to debug on the emulator, be sure there are no phones attached; this may conflict with gdb's ability to connect to the emulator.

If Firefox OS is already running and you want to attach to it without restarting it, you can do so like this:

./run-gdb.sh attach

Debugging out-of-process tasks

Because of the threaded nature of Firefox OS, you often need to be able to debug tasks other than the main B2G task. To do this, the simplest way is to use the b2g-ps command to find out the PID of the process that you need to debug:

$ adb shell b2g-ps
b2g              root      106   1     189828 56956 ffffffff 40101330 S /system/b2g/b2g
Browser          app_0     4308  106   52688  16188 ffffffff 400db330 S /system/b2g/plugin-container

Here, Browser is the child process used as the "content process" for the browser application. So if you want to debug the content process, in this example, do:

$ ./run-gdb attach 4308

Sometimes, it is useful to be notified immediately of any child process creation. This can be achieved by starting run-gdb.sh with the MOZ_DEBUG_CHILD_PROCESS environment variable:

MOZ_DEBUG_CHILD_PROCESS=1 ./run-gdb.sh

Having done this, launching an OOP application on Firefox OS will cause gdb to output the PID of the plugin-container for the new task. You can then do

$ ./run-gdb attach <pid>

as above.

If you are trying to debug something that occurs during boot, you have to launch the debugger instance for the new application fairly quickly. Once the new debugger is launched, you should immediately press "c" to continue running the new task.

Support

What level of functionality to expect

The following debugging features at least should definitely work. If they don't, it's likely that a simple tweak to your setup will make them work:

  • Symbols for all libraries (except perhaps certain drivers on certain Android phones)
  • Backtraces with full debug info (except for optimized-away argument values)
  • Breakpoints: you should be able to break on a symbol, or on a file:line, or on an address. All should work.
  • Single-stepping ('s' and 'n' should both work)

The following debugging features are not supported. Don't try to use them.

  • Watchpoints.

Troubleshooting

Here are a few things to try first whenever GDB is not working as described above.

Ensure that your B2G clone is up-to-date

Always keep in mind to that to update your B2G clone you must run these two commands:

git pull
./repo sync

Forgetting the git pull there is a typical reason why you'd end up with an old run-gdb.sh and not benefit from recent improvements.

Ensure that you are attaching to the right process

Attaching to the wrong process (e.g. main B2G process versus Browser process) would explain why your breakpoints don't get hit.

Ensure that symbols are correctly read

In gdb, use info shared to check that symbols are correctly read:

(gdb) info shared
From        To          Syms Read   Shared Object Library
0xb0001000  0xb0006928  Yes         out/target/product/otoro/symbols/system/bin/linker
0x40051100  0x4007ed74  Yes         /hack/b2g/B2G/out/target/product/otoro/symbols/system/lib/libc.so
0x401ab934  0x401aba2c  Yes         /hack/b2g/B2G/out/target/product/otoro/symbols/system/lib/libstdc++.so
...

The Syms Read column should say Yes everywhere. Maybe on some android phone you would see Yes (*) for some system libraries or drivers; that would be OK. You should not see any No.

If you do see a No, that is your first problem and you must solve it before looking at anything else.

Look for any error messages in the terminal output just after you typed your run-gdb.sh command.

Also check in that terminal output that the GDB command is sane. In particular, its last command line argument should be the path to your b2g executable. Here is a sane example:

prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin/arm-linux-androideabi-gdb -x /tmp/b2g.gdbinit.bjacob /hack/b2g/B2G/objdir-gecko/dist/bin/b2g

Check the value of these GDB variables: solib-search-path and solib-absolute-prefix:

(gdb) show solib-search-path
The search path for loading non-absolute shared library symbol files is /hack/b2g/B2G/objdir-gecko/dist/bin:out/target/product/otoro/symbols/system/lib:out/target/product/otoro/symbols/system/lib/hw:out/target/product/otoro/symbols/system/lib/egl:out/target/product/otoro/symbols/system/bin:out/target/product/otoro/system/lib:out/target/product/otoro/system/lib/egl:out/target/product/otoro/system/lib/hw:out/target/product/otoro/system/vendor/lib:out/target/product/otoro/system/vendor/lib/hw:out/target/product/otoro/system/vendor/lib/egl.
(gdb) show solib-absolute-prefix
The current system root is "out/target/product/otoro/symbols".

If you need help, try the #b2g IRC channel. If you think you found a bug, report it on the B2G issue tracker.

Revision Source

<p>{{draft()}}</p>
<p>Debugging Firefox OS using gdb is easy. This article will help make it even more so.</p>
<h2 id="Starting_the_debugger_in_single-process_mode">Starting the debugger in single-process mode</h2>
<div class="note">
  <p><strong>Note:</strong> Before running the debugger, you may want to set up a <code>.userconfig</code> file to customize things. See <a href="/en-US/docs/Mozilla/Boot_to_Gecko/Customization_with_the_.userconfig_file" title="/en-US/docs/Mozilla/Boot_to_Gecko/Customization_with_the_.userconfig_file">Customization with the .userconfig file</a> for details.</p>
</div>
<p>To restart Firefox OS and run it under gdb control, simply use the <code>run-gdb.sh</code> script:</p>
<pre>
./run-gdb.sh
</pre>
<div class="note">
  <p><strong>Note:</strong> If you want to debug on the emulator, be sure there are no phones attached; this may conflict with gdb's ability to connect to the emulator.</p>
</div>
<p>If Firefox OS is already running and you want to attach to it without restarting it, you can do so like this:</p>
<pre>
./run-gdb.sh attach
</pre>
<h2 id="Debugging_out-of-process_tasks">Debugging out-of-process tasks</h2>
<p>Because of the threaded nature of Firefox OS, you often need to be able to debug tasks other than the main B2G task. To do this, the simplest way is to use the b2g-ps command to find out the PID of the process that you need to debug:</p>
<pre>
$ adb shell b2g-ps
b2g              root      106   1     189828 56956 ffffffff 40101330 S /system/b2g/b2g
Browser          app_0     4308  106   52688  16188 ffffffff 400db330 S /system/b2g/plugin-container
</pre>
<p>Here, Browser is the child process used as the "content process" for the browser application. So if you want to debug the content process, in this example, do:</p>
<pre>
$ ./run-gdb attach 4308</pre>
<p>Sometimes, it is useful to be notified immediately of any child process creation. This can be achieved by starting run-gdb.sh with the MOZ_DEBUG_CHILD_PROCESS environment variable:</p>
<pre>
MOZ_DEBUG_CHILD_PROCESS=1 ./run-gdb.sh</pre>
<p>Having done this, launching an OOP application on Firefox OS will cause gdb to output the PID of the plugin-container for the new task. You can then do</p>
<pre>
$ ./run-gdb attach &lt;pid&gt;</pre>
<p>as above.</p>
<p>If you are trying to debug something that occurs during boot, you have to launch the debugger instance for the new application fairly quickly. Once the new debugger is launched, you should immediately press "c" to continue running the new task.</p>
<h2>Support</h2>
<h3>What level of functionality to expect</h3>
<p>The following debugging features at least should definitely work. If they don't, it's likely that a simple tweak to your setup will make them work:</p>
<ul>
  <li>Symbols for all libraries (except perhaps certain drivers on certain Android phones)</li>
  <li>Backtraces with full debug info (except for optimized-away argument values)</li>
  <li>Breakpoints: you should be able to break on a symbol, or on a file:line, or on an address. All should work.</li>
  <li>Single-stepping ('s' and 'n' should both work)</li>
</ul>
<p>The following debugging features are <strong>not</strong> supported. Don't try to use them.</p>
<ul>
  <li>Watchpoints.</li>
</ul>
<h3>Troubleshooting</h3>
<p>Here are a few things to try first whenever GDB is not working as described above.</p>
<h4>Ensure that your B2G clone is up-to-date</h4>
<p>Always keep in mind to that to update your B2G clone you must run these <strong>two</strong> commands:</p>
<pre>
git pull
./repo sync</pre>
<p>Forgetting the <code>git pull</code> there is a typical reason why you'd end up with an old <code>run-gdb.sh</code> and not benefit from recent improvements.</p>
<h4>Ensure that you are attaching to the right process</h4>
<p>Attaching to the wrong process (e.g. main B2G process versus Browser process) would explain why your breakpoints don't get hit.</p>
<h4>Ensure that symbols are correctly read</h4>
<p>In gdb, use <code>info shared</code> to check that symbols are correctly read:</p>
<pre>
(gdb) info shared
From&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Syms Read&nbsp;&nbsp; Shared Object Library
0xb0001000&nbsp; 0xb0006928&nbsp; Yes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out/target/product/otoro/symbols/system/bin/linker
0x40051100&nbsp; 0x4007ed74&nbsp; Yes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /hack/b2g/B2G/out/target/product/otoro/symbols/system/lib/libc.so
0x401ab934&nbsp; 0x401aba2c&nbsp; Yes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /hack/b2g/B2G/out/target/product/otoro/symbols/system/lib/libstdc++.so
...</pre>
<p>The <code>Syms Read</code> column should say <code>Yes</code> everywhere. Maybe on some android phone you would see <code>Yes (*)</code> for some system libraries or drivers; that would be OK. You should not see any <code>No.</code></p>
<p>If you do see a <code>No</code>, that is your first problem and you must solve it before looking at anything else.</p>
<p>Look for any error messages in the terminal output just after you typed your <code>run-gdb.sh</code> command.</p>
<p>Also check in that terminal output that the GDB command is sane. In particular, its last command line argument should be the path to your b2g executable. Here is a sane example:</p>
<pre>
prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin/arm-linux-androideabi-gdb -x /tmp/b2g.gdbinit.bjacob /hack/b2g/B2G/objdir-gecko/dist/bin/b2g</pre>
<p>Check the value of these GDB variables: <code>solib-search-path</code> and <code>solib-absolute-prefix:</code></p>
<pre>
(gdb) show solib-search-path
The search path for loading non-absolute shared library symbol files is /hack/b2g/B2G/objdir-gecko/dist/bin:out/target/product/otoro/symbols/system/lib:out/target/product/otoro/symbols/system/lib/hw:out/target/product/otoro/symbols/system/lib/egl:out/target/product/otoro/symbols/system/bin:out/target/product/otoro/system/lib:out/target/product/otoro/system/lib/egl:out/target/product/otoro/system/lib/hw:out/target/product/otoro/system/vendor/lib:out/target/product/otoro/system/vendor/lib/hw:out/target/product/otoro/system/vendor/lib/egl.
(gdb) show solib-absolute-prefix
The current system root is "out/target/product/otoro/symbols".</pre>
<p>If you need help, try the #b2g IRC channel. If you think you found a bug, report it on the <a href="https://github.com/mozilla-b2g/B2G/issues" title="https://github.com/mozilla-b2g/B2G/issues">B2G issue tracker</a>.</p>
Revert to this revision