From 1fe85153067468ba6205fe2d5214467e1dd01296 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Fri, 15 Feb 2013 21:27:44 -0800 Subject: [PATCH] Bug 840689: JS GDB support: Don't confuse typedefs with concrete types. r=sfink --- js/src/gdb/mozilla/JSObject.py | 9 +++++---- js/src/gdb/mozilla/jsid.py | 5 +++-- js/src/gdb/mozilla/prettyprinters.py | 9 ++++++--- js/src/gdb/tests/test-JSObject-null.py | 2 +- js/src/gdb/tests/test-JSObject.cpp | 6 ++++++ js/src/gdb/tests/test-JSObject.py | 2 ++ js/src/gdb/tests/test-JSString-null.py | 1 + js/src/gdb/tests/test-JSString.cpp | 6 ++++++ js/src/gdb/tests/test-JSString.py | 2 ++ 9 files changed, 32 insertions(+), 10 deletions(-) diff --git a/js/src/gdb/mozilla/JSObject.py b/js/src/gdb/mozilla/JSObject.py index 5a019ac953f..26886f81a0d 100644 --- a/js/src/gdb/mozilla/JSObject.py +++ b/js/src/gdb/mozilla/JSObject.py @@ -39,10 +39,11 @@ class JSObjectPtrOrRef(prettyprinters.Pointer): is_delegate = bool(flags & self.otc.flag_DELEGATE) name = None if class_name == 'Function': - if self.value.type.code == gdb.TYPE_CODE_PTR: - function = self.value.cast(self.otc.func_ptr_type) - elif self.value.type.code == gdb.TYPE_CODE_REF: - function = self.value.address.cast(self.otc.func_ptr_type) + function = self.value + concrete_type = function.type.strip_typedefs() + if concrete_type.code == gdb.TYPE_CODE_REF: + function = function.address + function = function.cast(self.otc.func_ptr_type) atom = deref(function['atom_']) name = str(atom) if atom else '' return '[object %s%s]%s' % (class_name, diff --git a/js/src/gdb/mozilla/jsid.py b/js/src/gdb/mozilla/jsid.py index 903fcc82cb8..fda0716d196 100644 --- a/js/src/gdb/mozilla/jsid.py +++ b/js/src/gdb/mozilla/jsid.py @@ -23,14 +23,15 @@ class jsid(object): def __init__(self, value, cache): self.value = value self.cache = cache + self.concrete_type = self.value.type.strip_typedefs() # SpiderMonkey has two alternative definitions of jsid: a typedef for # ptrdiff_t, and a struct with == and != operators defined on it. # Extract the bits from either one. def as_bits(self): - if self.value.type.code == gdb.TYPE_CODE_STRUCT: + if self.concrete_type.code == gdb.TYPE_CODE_STRUCT: return self.value['asBits'] - elif self.value.type.code == gdb.TYPE_CODE_INT: + elif self.concrete_type.code == gdb.TYPE_CODE_INT: return self.value else: raise RuntimeError, ("definition of SpiderMonkey 'jsid' type" diff --git a/js/src/gdb/mozilla/prettyprinters.py b/js/src/gdb/mozilla/prettyprinters.py index 79631832620..b09c5e29a74 100644 --- a/js/src/gdb/mozilla/prettyprinters.py +++ b/js/src/gdb/mozilla/prettyprinters.py @@ -312,7 +312,7 @@ def lookup_for_objfile(objfile): class Pointer(object): def __new__(cls, value, cache): # Don't try to provide pretty-printers for NULL pointers. - if value.type.code == gdb.TYPE_CODE_PTR and value == 0: + if value.type.strip_typedefs().code == gdb.TYPE_CODE_PTR and value == 0: return None return super(Pointer, cls).__new__(cls) @@ -323,10 +323,13 @@ class Pointer(object): def to_string(self): # See comment above. assert not hasattr(self, 'display_hint') or self.display_hint() != 'string' - if self.value.type.code == gdb.TYPE_CODE_PTR: + concrete_type = self.value.type.strip_typedefs() + if concrete_type.code == gdb.TYPE_CODE_PTR: address = self.value.cast(self.cache.void_ptr_t) - elif self.value.type.code == gdb.TYPE_CODE_REF: + elif concrete_type.code == gdb.TYPE_CODE_REF: address = '@' + str(self.value.address.cast(self.cache.void_ptr_t)) + else: + assert not "mozilla.prettyprinters.Pointer applied to bad value type" try: summary = self.summary() except gdb.MemoryError as r: diff --git a/js/src/gdb/tests/test-JSObject-null.py b/js/src/gdb/tests/test-JSObject-null.py index 7bf5f05175a..40721b2e227 100644 --- a/js/src/gdb/tests/test-JSObject-null.py +++ b/js/src/gdb/tests/test-JSObject-null.py @@ -3,4 +3,4 @@ gdb.execute('set print address on') run_fragment('JSObject.null') assert_pretty('null', '0x0') - +assert_pretty('nullRaw', '0x0') diff --git a/js/src/gdb/tests/test-JSObject.cpp b/js/src/gdb/tests/test-JSObject.cpp index ae944b046c4..ba17ceb7f29 100644 --- a/js/src/gdb/tests/test-JSObject.cpp +++ b/js/src/gdb/tests/test-JSObject.cpp @@ -12,6 +12,8 @@ FRAGMENT(JSObject, simple) { JSObject &plainRef = *plain; JSFunction &funcRef = *funcPtr; + js::RawObject plainRaw = plain; + js::RawObject funcRaw = func; breakpoint(); @@ -22,12 +24,16 @@ FRAGMENT(JSObject, simple) { (void) funcPtr; (void) &plainRef; (void) &funcRef; + (void) plainRaw; + (void) funcRaw; } FRAGMENT(JSObject, null) { js::Rooted null(cx, NULL); + js::RawObject nullRaw = null; breakpoint(); (void) null; + (void) nullRaw; } diff --git a/js/src/gdb/tests/test-JSObject.py b/js/src/gdb/tests/test-JSObject.py index 35122e14a5d..74e02e75e9d 100644 --- a/js/src/gdb/tests/test-JSObject.py +++ b/js/src/gdb/tests/test-JSObject.py @@ -18,3 +18,5 @@ assert_pretty('funcPtr', '(JSFunction *) [object Function "formFollows"]') assert_pretty('plainRef', '(JSObject &) @ [object Object]') assert_pretty('funcRef', '(JSFunction &) @ [object Function "formFollows"]') +assert_pretty('plainRaw', '(js::RawObject) [object Object]') +assert_pretty('funcRaw', '(js::RawObject) [object Function "dys"]') diff --git a/js/src/gdb/tests/test-JSString-null.py b/js/src/gdb/tests/test-JSString-null.py index bb24e19a743..eec3e03bac1 100644 --- a/js/src/gdb/tests/test-JSString-null.py +++ b/js/src/gdb/tests/test-JSString-null.py @@ -3,3 +3,4 @@ gdb.execute('set print address on') run_fragment('JSString.null') assert_pretty('null', '0x0') +assert_pretty('nullRaw', '0x0') diff --git a/js/src/gdb/tests/test-JSString.cpp b/js/src/gdb/tests/test-JSString.cpp index 21760ddaa50..5a1e35a96be 100644 --- a/js/src/gdb/tests/test-JSString.cpp +++ b/js/src/gdb/tests/test-JSString.cpp @@ -23,6 +23,9 @@ FRAGMENT(JSString, simple) { // This will probably be a rope. js::Rooted doubleStars(cx, JS_ConcatStrings(cx, stars, stars)); + // Ensure we're not confused by typedefs for pointer types. + js::RawString xRaw = x; + breakpoint(); (void) empty; @@ -31,14 +34,17 @@ FRAGMENT(JSString, simple) { (void) stars; (void) xz; (void) doubleStars; + (void) xRaw; } FRAGMENT(JSString, null) { js::Rooted null(cx, NULL); + js::RawString nullRaw = null; breakpoint(); (void) null; + (void) nullRaw; } FRAGMENT(JSString, subclasses) { diff --git a/js/src/gdb/tests/test-JSString.py b/js/src/gdb/tests/test-JSString.py index efe33629200..3189f34a480 100644 --- a/js/src/gdb/tests/test-JSString.py +++ b/js/src/gdb/tests/test-JSString.py @@ -14,6 +14,8 @@ assert_eq(str(stars), "'*' ") doubleStars = gdb.parse_and_eval('doubleStars') assert_eq(str(doubleStars), "'*' ") +assert_pretty('xRaw', '"x"') + # JSAtom * run_fragment('JSString.atom')