Bug 840689: JS GDB support: Don't confuse typedefs with concrete types. r=sfink

This commit is contained in:
Jim Blandy 2013-02-15 21:27:44 -08:00
parent 55d7aa2c7f
commit 1fe8515306
9 changed files with 32 additions and 10 deletions

View File

@ -39,10 +39,11 @@ class JSObjectPtrOrRef(prettyprinters.Pointer):
is_delegate = bool(flags & self.otc.flag_DELEGATE) is_delegate = bool(flags & self.otc.flag_DELEGATE)
name = None name = None
if class_name == 'Function': if class_name == 'Function':
if self.value.type.code == gdb.TYPE_CODE_PTR: function = self.value
function = self.value.cast(self.otc.func_ptr_type) concrete_type = function.type.strip_typedefs()
elif self.value.type.code == gdb.TYPE_CODE_REF: if concrete_type.code == gdb.TYPE_CODE_REF:
function = self.value.address.cast(self.otc.func_ptr_type) function = function.address
function = function.cast(self.otc.func_ptr_type)
atom = deref(function['atom_']) atom = deref(function['atom_'])
name = str(atom) if atom else '<unnamed>' name = str(atom) if atom else '<unnamed>'
return '[object %s%s]%s' % (class_name, return '[object %s%s]%s' % (class_name,

View File

@ -23,14 +23,15 @@ class jsid(object):
def __init__(self, value, cache): def __init__(self, value, cache):
self.value = value self.value = value
self.cache = cache self.cache = cache
self.concrete_type = self.value.type.strip_typedefs()
# SpiderMonkey has two alternative definitions of jsid: a typedef for # SpiderMonkey has two alternative definitions of jsid: a typedef for
# ptrdiff_t, and a struct with == and != operators defined on it. # ptrdiff_t, and a struct with == and != operators defined on it.
# Extract the bits from either one. # Extract the bits from either one.
def as_bits(self): 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'] 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 return self.value
else: else:
raise RuntimeError, ("definition of SpiderMonkey 'jsid' type" raise RuntimeError, ("definition of SpiderMonkey 'jsid' type"

View File

@ -312,7 +312,7 @@ def lookup_for_objfile(objfile):
class Pointer(object): class Pointer(object):
def __new__(cls, value, cache): def __new__(cls, value, cache):
# Don't try to provide pretty-printers for NULL pointers. # 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 None
return super(Pointer, cls).__new__(cls) return super(Pointer, cls).__new__(cls)
@ -323,10 +323,13 @@ class Pointer(object):
def to_string(self): def to_string(self):
# See comment above. # See comment above.
assert not hasattr(self, 'display_hint') or self.display_hint() != 'string' 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) 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)) address = '@' + str(self.value.address.cast(self.cache.void_ptr_t))
else:
assert not "mozilla.prettyprinters.Pointer applied to bad value type"
try: try:
summary = self.summary() summary = self.summary()
except gdb.MemoryError as r: except gdb.MemoryError as r:

View File

@ -3,4 +3,4 @@ gdb.execute('set print address on')
run_fragment('JSObject.null') run_fragment('JSObject.null')
assert_pretty('null', '0x0') assert_pretty('null', '0x0')
assert_pretty('nullRaw', '0x0')

View File

@ -12,6 +12,8 @@ FRAGMENT(JSObject, simple) {
JSObject &plainRef = *plain; JSObject &plainRef = *plain;
JSFunction &funcRef = *funcPtr; JSFunction &funcRef = *funcPtr;
js::RawObject plainRaw = plain;
js::RawObject funcRaw = func;
breakpoint(); breakpoint();
@ -22,12 +24,16 @@ FRAGMENT(JSObject, simple) {
(void) funcPtr; (void) funcPtr;
(void) &plainRef; (void) &plainRef;
(void) &funcRef; (void) &funcRef;
(void) plainRaw;
(void) funcRaw;
} }
FRAGMENT(JSObject, null) { FRAGMENT(JSObject, null) {
js::Rooted<JSObject *> null(cx, NULL); js::Rooted<JSObject *> null(cx, NULL);
js::RawObject nullRaw = null;
breakpoint(); breakpoint();
(void) null; (void) null;
(void) nullRaw;
} }

View File

@ -18,3 +18,5 @@ assert_pretty('funcPtr', '(JSFunction *) [object Function "formFollows"]')
assert_pretty('plainRef', '(JSObject &) @ [object Object]') assert_pretty('plainRef', '(JSObject &) @ [object Object]')
assert_pretty('funcRef', '(JSFunction &) @ [object Function "formFollows"]') assert_pretty('funcRef', '(JSFunction &) @ [object Function "formFollows"]')
assert_pretty('plainRaw', '(js::RawObject) [object Object]')
assert_pretty('funcRaw', '(js::RawObject) [object Function "dys"]')

View File

@ -3,3 +3,4 @@ gdb.execute('set print address on')
run_fragment('JSString.null') run_fragment('JSString.null')
assert_pretty('null', '0x0') assert_pretty('null', '0x0')
assert_pretty('nullRaw', '0x0')

View File

@ -23,6 +23,9 @@ FRAGMENT(JSString, simple) {
// This will probably be a rope. // This will probably be a rope.
js::Rooted<JSString *> doubleStars(cx, JS_ConcatStrings(cx, stars, stars)); js::Rooted<JSString *> doubleStars(cx, JS_ConcatStrings(cx, stars, stars));
// Ensure we're not confused by typedefs for pointer types.
js::RawString xRaw = x;
breakpoint(); breakpoint();
(void) empty; (void) empty;
@ -31,14 +34,17 @@ FRAGMENT(JSString, simple) {
(void) stars; (void) stars;
(void) xz; (void) xz;
(void) doubleStars; (void) doubleStars;
(void) xRaw;
} }
FRAGMENT(JSString, null) { FRAGMENT(JSString, null) {
js::Rooted<JSString *> null(cx, NULL); js::Rooted<JSString *> null(cx, NULL);
js::RawString nullRaw = null;
breakpoint(); breakpoint();
(void) null; (void) null;
(void) nullRaw;
} }
FRAGMENT(JSString, subclasses) { FRAGMENT(JSString, subclasses) {

View File

@ -14,6 +14,8 @@ assert_eq(str(stars), "'*' <repeats 100 times>")
doubleStars = gdb.parse_and_eval('doubleStars') doubleStars = gdb.parse_and_eval('doubleStars')
assert_eq(str(doubleStars), "'*' <repeats 200 times>") assert_eq(str(doubleStars), "'*' <repeats 200 times>")
assert_pretty('xRaw', '"x"')
# JSAtom * # JSAtom *
run_fragment('JSString.atom') run_fragment('JSString.atom')