|
LinuxDebugging
tips for debugging on Linux
This page is for Chromium-specific debugging tips; learning how to run gdb is out of scope. GDBMultiprocess TricksGetting renderer subprocesses into gdbSince Chromium itself spawns the renderers, it can be tricky to grab a particular with gdb. This command does the trick: chrome --renderer-cmd-prefix='gdb --args' Note that if you're using Emacs and M-x gdb, you must quote it like chrome "--renderer-cmd-prefix=gdb --args" Note: using the --renderer-cmd-prefix option bypasses the zygote launcher, so the renderers won't be sandboxed. It is generally not an issue, except when you are trying to debug interactions with the sandbox. If that's what you are doing, you will need to attach your debugger to a running renderer process (see below). Choosing which renderers to debugIf you are starting multiple renderers then the above means that multiple gdb's start and fight over the console. Instead, you can set the prefix to point to this shell script: #!/bin/sh echo "**** Child $$ starting: y to debug" read input if [ "$input" == "y" ] ; then gdb --args $* else $* fi Connecting to a running rendererUsually ps aux | grep chrome will not give very helpful output. Try pstree -p | grep chrome to get something like | |-bash(21969)---chrome(672)-+-chrome(694)
| | |-chrome(695)---chrome(696)-+-{chrome}(697)
| | | \-{chrome}(709)
| | |-{chrome}(675)
| | |-{chrome}(678)
| | |-{chrome}(679)
| | |-{chrome}(680)
| | |-{chrome}(681)
| | |-{chrome}(682)
| | |-{chrome}(684)
| | |-{chrome}(685)
| | |-{chrome}(705)
| | \-{chrome}(717)Most of those are threads. In this case the browser process would be 672 and the (sole) renderer process is 696. You can use gdb -p 696 to attach. Note: by default, sandboxed processes can't be attached by a debugger. To be able to do so, you will need to pass the --allow-sandbox-debugging option. Debugging all rendererschrome --renderer-cmd-prefix='xterm -e gdb --args' Ain't it cute? To auto-start the renderers in the debugger, send the "run" command to the debugger: chrome --renderer-cmd-prefix='xterm -e gdb --eval-command=run --args' Plugin ProcessesSame strategies as renderers, but the flag is called --plugin-launcher. Single-Process modeDepending on whether it's relevant to the problem, it's often easier to just run in "single process" mode where the renderer threads are in-process. Then you can just run gdb on the main process. gdb --args chrome --single-process Printing Chromium typesHere's code for printing WebCore::String types in gdb 7: import gdb
import re
class WebCoreAtomicStringPrinter:
"Print a WebCore::AtomicString"
def __init__(self, val):
self.val = val
def display_hint(self):
return 'string'
def to_string(self):
return self.val['m_string']
class WebCoreStringPrinter:
"Print a WebCore::String"
def __init__(self, val):
self.val = val
def display_hint(self):
return 'string'
def get_length(self):
if not self.val['m_impl']['m_ptr']:
return 0
return self.val['m_impl']['m_ptr']['m_length']
def to_string(self):
if 0 == self.get_length():
return '(null)'
uchar_ptr = self.val['m_impl']['m_ptr']['m_data']
char_vals = [int((uchar_ptr + i).dereference()) for i in xrange(self.get_length())
def m(x):
if x < 128:
return chr(x)
else:
return '?'
chars = [m(x) for x in char_vals]
return ''.join(chars)
def lookup_function(val):
lookup_tag = val.type.tag
if lookup_tag == None:
return None
if lookup_tag.find("WebCore::AtomicString") != -1:
return WebCoreAtomicStringPrinter(val)
if lookup_tag.find("WebCore::String") != -1:
return WebCoreStringPrinter(val)
return None
gdb.pretty_printers.append(lookup_function)Put the above into a file somewhere called webcore.py and load it by adding the following to the end of ~/.gdbinit: python
import sys
sys.path.append("/path/to/script")
import webcorePretty printers for std types shouldn't be necessary in gdb 7, but they're provided here in case you're using an older gdb. Put the following into ~/.gdbinit: # Print a C++ string.
define ps
print $arg0.c_str()
end
# Print a C++ wstring or wchar_t*.
define pws
printf "\""
set $c = (wchar_t*)$arg0
while ( *$c )
if ( *$c > 0x7f )
printf "[%x]", *$c
else
printf "%c", *$c
end
set $c++
end
printf "\"\n"
end
# Print a FilePath.
define pfp
print $arg0.value().c_str()
endRunning TestsBrowser testsBy default the browser_tests forks itself for each test. When debugging, it's useful to pass --child flag and --gtest_filter. This is the command line for the forked child. Layout testsSee LayoutTestsLinux for some tips. In particular, it's possible to debug a layout test via sshing to a Linux box; you don't need anything on screen if you use Xvfb. UI testsLike layout tests, you're better off running running ui tests within Xvfb or Xephyr. See above. LoggingSeeing all LOG(foo) messagesDefault log level hides LOG(INFO). Run with --log-level=0 and --enable-logging=stderr flags. Seeing IPC debug messagesRun with CHROME_IPC_LOGGING=1 eg. CHROME_IPC_LOGGING=1 sconsbuild/Debug/chrome or within gdb: set environment CHROME_IPC_LOGGING 1 Using valgrindTo run valgrind on the browser and renderer processes, with our suppression file and flags: $ cd $CHROMIUM_ROOT/src $ chrome/tools/valgrind/valgrind.sh sconsbuild/Debug/chrome You can use valgrind on chrome and/or on the renderers e.g valgrind --smc-check=all ../sconsbuild/Debug/chrome or by passing valgrind as the argument to --render-cmd-prefix. Beware that there are several valgrind "false positives" e.g. pickle, sqlite and some instances in webkit that are ignorable. On systems with prelink and address space randomization (e.g. Fedora), you may also see valgrind errors in libstdc++ on startup and in gnome-breakpad. i18nWe obey your system locale. Try something like: LANG=ja_JP.UTF-8 sconsbuild/Debug/chrome If this doesn't work, make sure that the LANGUAGE environment variable isn't set -- it can override LANG. RTLNote that GTK needs translation data to properly RTL-ize in an RTL locale, so install that if you're testing an RTL language: sudo apt-get install language-pack-ar language-pack-he language-pack-gnome-ar language-pack-gnome-he Note that the --lang flag does not work properly for this; we should just remove it on Linux. On non-Debian systems, you need the gtk20.mo files. (Please update these docs with the appropriate instructions if you know what they are.) Tracking Down BugsRegression TestingOld builds are archived here: http://build.chromium.org/buildbot/snapshots/chromium-rel-linux/ Screen recording for bug reportssudo apt-get install gtk-recordmydesktop Bugs in Ubuntu packagesSince we don't build the Ubuntu packages (Ubuntu does) we can't get useful backtraces from them. Direct users to https://wiki.ubuntu.com/Chromium/Debug . Bugs in Fedora packagesLike Ubuntu, but direct users to https://fedoraproject.org/wiki/TomCallaway/Chromium_Debug . Libraries we depend onGTKSee Running GLib Applications for notes on how to make GTK warnings fatal. See also LinuxDebuggingGtk. XlibIf you're trying to track down X errors like: The program 'chrome' received an X Window System error. This probably reflects a bug in the program. The error was 'BadDrawable (invalid Pixmap or Window parameter)'. Some strategies are:
Window ManagersTo test on various window managers, you can use a nested X server like Xephyr. Instructions for how to use Xephyr are on the LayoutTestsLinux page. If you need to test something with hardware accelerated compositing (e.g., compiz), you can use Xgl (sudo apt-get install xserver-xgl). E.g.: Xgl :1 -ac -accel glx:pbuffer -accel xv:pbuffer -screen 1024x768 Mozilla Tipshttps://developer.mozilla.org/en/Debugging_Mozilla_on_Linux_FAQ |