Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Unified Diff: tools/gdb/gdb_chrome.py

Issue 1841863002: Update monet. (Closed) Base URL: https://github.com/domokit/monet.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/download_from_google_storage.py ('k') | tools/git/README » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gdb/gdb_chrome.py
diff --git a/tools/gdb/gdb_chrome.py b/tools/gdb/gdb_chrome.py
new file mode 100644
index 0000000000000000000000000000000000000000..2ba7ce8b1daff0ee6496f24c7abb9bcdb2270915
--- /dev/null
+++ b/tools/gdb/gdb_chrome.py
@@ -0,0 +1,331 @@
+# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""GDB support for Chrome types.
+
+Add this to your gdb by amending your ~/.gdbinit as follows:
+ python
+ import sys
+ sys.path.insert(0, "/path/to/tools/gdb/")
+ import gdb_chrome
+ end
+
+Use
+ (gdb) p /r any_variable
+to print |any_variable| without using any printers.
+"""
+
+import datetime
+import gdb
+import gdb.printing
+import os
+import sys
+
+sys.path.insert(0, os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ '..', '..', 'third_party', 'WebKit', 'Tools', 'gdb'))
+try:
+ import webkit
+finally:
+ sys.path.pop(0)
+
+# When debugging this module, set the below variable to True, and then use
+# (gdb) python del sys.modules['gdb_chrome']
+# (gdb) python import gdb_chrome
+# to reload.
+_DEBUGGING = False
+
+
+pp_set = gdb.printing.RegexpCollectionPrettyPrinter("chromium")
+
+
+def typed_ptr(ptr):
+ """Prints a pointer along with its exact type.
+
+ By default, gdb would print just the address, which takes more
+ steps to interpret.
+ """
+ # Returning this as a cast expression surrounded by parentheses
+ # makes it easier to cut+paste inside of gdb.
+ return '((%s)%s)' % (ptr.dynamic_type, ptr)
+
+
+def yield_fields(val):
+ """Use this in a printer's children() method to print an object's fields.
+
+ e.g.
+ def children():
+ for result in yield_fields(self.val):
+ yield result
+ """
+ try:
+ fields = val.type.target().fields()
+ except:
+ fields = val.type.fields()
+ for field in fields:
+ if field.is_base_class:
+ yield (field.name, val.cast(gdb.lookup_type(field.name)))
+ else:
+ yield (field.name, val[field.name])
+
+
+class Printer(object):
+ def __init__(self, val):
+ self.val = val
+
+
+class StringPrinter(Printer):
+ def display_hint(self):
+ return 'string'
+
+
+class String16Printer(StringPrinter):
+ def to_string(self):
+ return webkit.ustring_to_string(self.val['_M_dataplus']['_M_p'])
+pp_set.add_printer(
+ 'string16',
+ '^string16|std::basic_string<(unsigned short|base::char16).*>$',
+ String16Printer);
+
+
+class GURLPrinter(StringPrinter):
+ def to_string(self):
+ return self.val['spec_']
+pp_set.add_printer('GURL', '^GURL$', GURLPrinter)
+
+
+class FilePathPrinter(StringPrinter):
+ def to_string(self):
+ return self.val['path_']['_M_dataplus']['_M_p']
+pp_set.add_printer('FilePath', '^FilePath$', FilePathPrinter)
+
+
+class SizePrinter(Printer):
+ def to_string(self):
+ return '%sx%s' % (self.val['width_'], self.val['height_'])
+pp_set.add_printer('gfx::Size', '^gfx::(Size|SizeF|SizeBase<.*>)$', SizePrinter)
+
+
+class PointPrinter(Printer):
+ def to_string(self):
+ return '%s,%s' % (self.val['x_'], self.val['y_'])
+pp_set.add_printer('gfx::Point', '^gfx::(Point|PointF|PointBase<.*>)$',
+ PointPrinter)
+
+
+class RectPrinter(Printer):
+ def to_string(self):
+ return '%s %s' % (self.val['origin_'], self.val['size_'])
+pp_set.add_printer('gfx::Rect', '^gfx::(Rect|RectF|RectBase<.*>)$',
+ RectPrinter)
+
+
+class SmartPtrPrinter(Printer):
+ def to_string(self):
+ return '%s%s' % (self.typename, typed_ptr(self.ptr()))
+
+
+class ScopedRefPtrPrinter(SmartPtrPrinter):
+ typename = 'scoped_refptr'
+ def ptr(self):
+ return self.val['ptr_']
+pp_set.add_printer('scoped_refptr', '^scoped_refptr<.*>$', ScopedRefPtrPrinter)
+
+
+class LinkedPtrPrinter(SmartPtrPrinter):
+ typename = 'linked_ptr'
+ def ptr(self):
+ return self.val['value_']
+pp_set.add_printer('linked_ptr', '^linked_ptr<.*>$', LinkedPtrPrinter)
+
+
+class WeakPtrPrinter(SmartPtrPrinter):
+ typename = 'base::WeakPtr'
+ def ptr(self):
+ flag = ScopedRefPtrPrinter(self.val['ref_']['flag_']).ptr()
+ if flag and flag['is_valid_']:
+ return self.val['ptr_']
+ return gdb.Value(0).cast(self.val['ptr_'].type)
+pp_set.add_printer('base::WeakPtr', '^base::WeakPtr<.*>$', WeakPtrPrinter)
+
+
+class CallbackPrinter(Printer):
+ """Callbacks provide no usable information so reduce the space they take."""
+ def to_string(self):
+ return '...'
+pp_set.add_printer('base::Callback', '^base::Callback<.*>$', CallbackPrinter)
+
+
+class LocationPrinter(Printer):
+ def to_string(self):
+ return '%s()@%s:%s' % (self.val['function_name_'].string(),
+ self.val['file_name_'].string(),
+ self.val['line_number_'])
+pp_set.add_printer('tracked_objects::Location', '^tracked_objects::Location$',
+ LocationPrinter)
+
+
+class PendingTaskPrinter(Printer):
+ def to_string(self):
+ return 'From %s' % (self.val['posted_from'],)
+
+ def children(self):
+ for result in yield_fields(self.val):
+ if result[0] not in ('task', 'posted_from'):
+ yield result
+pp_set.add_printer('base::PendingTask', '^base::PendingTask$',
+ PendingTaskPrinter)
+
+
+class LockPrinter(Printer):
+ def to_string(self):
+ try:
+ if self.val['owned_by_thread_']:
+ return 'Locked by thread %s' % self.val['owning_thread_id_']
+ else:
+ return 'Unlocked'
+ except gdb.error:
+ return 'Unknown state'
+pp_set.add_printer('base::Lock', '^base::Lock$', LockPrinter)
+
+
+class TimeDeltaPrinter(object):
+ def __init__(self, val):
+ self._timedelta = datetime.timedelta(microseconds=int(val['delta_']))
+
+ def timedelta(self):
+ return self._timedelta
+
+ def to_string(self):
+ return str(self._timedelta)
+pp_set.add_printer('base::TimeDelta', '^base::TimeDelta$', TimeDeltaPrinter)
+
+
+class TimeTicksPrinter(TimeDeltaPrinter):
+ def __init__(self, val):
+ self._timedelta = datetime.timedelta(microseconds=int(val['ticks_']))
+pp_set.add_printer('base::TimeTicks', '^base::TimeTicks$', TimeTicksPrinter)
+
+
+class TimePrinter(object):
+ def __init__(self, val):
+ timet_offset = gdb.parse_and_eval(
+ 'base::Time::kTimeTToMicrosecondsOffset')
+ self._datetime = (datetime.datetime.fromtimestamp(0) +
+ datetime.timedelta(microseconds=
+ int(val['us_'] - timet_offset)))
+
+ def datetime(self):
+ return self._datetime
+
+ def to_string(self):
+ return str(self._datetime)
+pp_set.add_printer('base::Time', '^base::Time$', TimePrinter)
+
+
+class IpcMessagePrinter(Printer):
+ def header(self):
+ return self.val['header_'].cast(
+ gdb.lookup_type('IPC::Message::Header').pointer())
+
+ def to_string(self):
+ message_type = self.header()['type']
+ return '%s of kind %s line %s' % (
+ self.val.dynamic_type,
+ (message_type >> 16).cast(gdb.lookup_type('IPCMessageStart')),
+ message_type & 0xffff)
+
+ def children(self):
+ yield ('header_', self.header().dereference())
+ yield ('capacity_after_header_', self.val['capacity_after_header_'])
+ for field in self.val.type.fields():
+ if field.is_base_class:
+ continue
+ yield (field.name, self.val[field.name])
+pp_set.add_printer('IPC::Message', '^IPC::Message$', IpcMessagePrinter)
+
+
+class NotificationRegistrarPrinter(Printer):
+ def to_string(self):
+ try:
+ registrations = self.val['registered_']
+ vector_finish = registrations['_M_impl']['_M_finish']
+ vector_start = registrations['_M_impl']['_M_start']
+ if vector_start == vector_finish:
+ return 'Not watching notifications'
+ if vector_start.dereference().type.sizeof == 0:
+ # Incomplete type: b/8242773
+ return 'Watching some notifications'
+ return ('Watching %s notifications; '
+ 'print %s->registered_ for details') % (
+ int(vector_finish - vector_start),
+ typed_ptr(self.val.address))
+ except gdb.error:
+ return 'NotificationRegistrar'
+pp_set.add_printer('content::NotificationRegistrar',
+ '^content::NotificationRegistrar$',
+ NotificationRegistrarPrinter)
+
+
+class SiteInstanceImplPrinter(object):
+ def __init__(self, val):
+ self.val = val.cast(val.dynamic_type)
+
+ def to_string(self):
+ return 'SiteInstanceImpl@%s for %s' % (
+ self.val.address, self.val['site_'])
+
+ def children(self):
+ yield ('id_', self.val['id_'])
+ yield ('has_site_', self.val['has_site_'])
+ if self.val['browsing_instance_']['ptr_']:
+ yield ('browsing_instance_', self.val['browsing_instance_']['ptr_'])
+ if self.val['process_']:
+ yield ('process_', typed_ptr(self.val['process_']))
+pp_set.add_printer('content::SiteInstanceImpl', '^content::SiteInstanceImpl$',
+ SiteInstanceImplPrinter)
+
+
+class RenderProcessHostImplPrinter(object):
+ def __init__(self, val):
+ self.val = val.cast(val.dynamic_type)
+
+ def to_string(self):
+ pid = ''
+ try:
+ child_process_launcher_ptr = (
+ self.val['child_process_launcher_']['impl_']['data_']['ptr'])
+ if child_process_launcher_ptr:
+ context = (child_process_launcher_ptr['context_']['ptr_'])
+ if context:
+ pid = ' PID %s' % str(context['process_']['process_'])
+ except gdb.error:
+ # The definition of the Context type may not be available.
+ # b/8242773
+ pass
+ return 'RenderProcessHostImpl@%s%s' % (self.val.address, pid)
+
+ def children(self):
+ yield ('id_', self.val['id_'])
+ yield ('listeners_',
+ self.val['listeners_']['data_'])
+ yield ('worker_ref_count_', self.val['worker_ref_count_'])
+ yield ('fast_shutdown_started_', self.val['fast_shutdown_started_'])
+ yield ('deleting_soon_', self.val['deleting_soon_'])
+ yield ('pending_views_', self.val['pending_views_'])
+ yield ('visible_widgets_', self.val['visible_widgets_'])
+ yield ('backgrounded_', self.val['backgrounded_'])
+ yield ('widget_helper_', self.val['widget_helper_'])
+ yield ('is_initialized_', self.val['is_initialized_'])
+ yield ('browser_context_', typed_ptr(self.val['browser_context_']))
+ yield ('sudden_termination_allowed_',
+ self.val['sudden_termination_allowed_'])
+ yield ('ignore_input_events_', self.val['ignore_input_events_'])
+ yield ('is_guest_', self.val['is_guest_'])
+pp_set.add_printer('content::RenderProcessHostImpl',
+ '^content::RenderProcessHostImpl$',
+ RenderProcessHostImplPrinter)
+
+
+gdb.printing.register_pretty_printer(gdb, pp_set, replace=_DEBUGGING)
« no previous file with comments | « tools/download_from_google_storage.py ('k') | tools/git/README » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698