Skip to content

Instantly share code, notes, and snippets.

@parsa
Forked from ytomino/drake-gdb.py
Created March 4, 2018 21:26
Show Gist options
  • Save parsa/48cfd7352b01a6da99f15db78d81cef2 to your computer and use it in GitHub Desktop.
Save parsa/48cfd7352b01a6da99f15db78d81cef2 to your computer and use it in GitHub Desktop.

Revisions

  1. @ytomino ytomino revised this gist Sep 27, 2016. 1 changed file with 71 additions and 41 deletions.
    112 changes: 71 additions & 41 deletions drake-gdb.py
    Original file line number Diff line number Diff line change
    @@ -22,72 +22,102 @@ def gnat_substitute(c, char_t):
    else:
    return "[\"%.8x\"]" % c

    def read_string(p, length, char_t):
    if char_t.sizeof == 1:
    bin = bytearray(length)
    for i in range(length):
    code = int(p.dereference())
    if code < 0: code += 256 # signed?
    bin[i] = code
    p += 1
    try:
    contents = bin.decode("utf-8")
    except:
    contents = bin
    else:
    contents = []
    for i in range(length):
    code = int(p.dereference())
    contents.append(code)
    p += 1
    return contents

    def wrapped_string_image(contents, length_is_limited):
    double_quote = ord("\"")
    s = "+\""
    for c in contents:
    code = ord(c) if type(contents) == unicode else c
    if type(contents) == bytearray:
    valid = code < 0x80 # decoding is failed
    else:
    valid = code <= 0xFFFF
    if valid and code != double_quote and is_graphic(code):
    s += unichr(code)
    else:
    s += gnat_substitute(code, char_t)
    s += "\""
    if length_is_limited: s += " & ..."
    return s

    length_limit = 1024

    class BoundedStringPrinter:
    "Print a Bounded_String"

    def __init__(self, val):
    global length_limit
    self.val = val
    # components
    length = int(self.val["length"])
    element = self.val["element___XVL"]
    # Character_Type
    char_t = element.type.target()
    # contents
    char_t_ptr = char_t.pointer()
    p = element.address.reinterpret_cast(char_t_ptr)
    read_length = length if length <= length_limit else length_limit
    contents = read_string(p, read_length, char_t)
    self.image = wrapped_string_image(contents, read_length < length)

    def to_string(self):
    return self.image

    class UnboundedStringPrinter:
    "Print a Unbounded_String"

    def __init__(self, val):
    global length_limit
    self.val = val
    # components
    length = int(self.val["length"])
    items = self.val["data"].dereference()["items"]
    # Character_Type
    typename = get_typename(self.val)
    char_typename = typename[0 : len(typename) - 16] + "character_type"
    char_t = gdb.lookup_type(char_typename)
    # make (byte)array or unicode
    length = int(self.val["length"])
    items = self.val["data"].dereference()["items"] # fat pointer
    # contents
    char_t_ptr_ptr = char_t.pointer().pointer()
    p = items.address.reinterpret_cast(char_t_ptr_ptr).dereference()
    read_length = length if length <= length_limit else length_limit
    if char_t.sizeof == 1:
    bin = bytearray(read_length)
    for i in range(read_length):
    code = int(p.dereference())
    if code < 0: code += 256 # signed?
    bin[i] = code
    p += 1
    try:
    contents = bin.decode("utf-8")
    except:
    contents = bin
    else:
    in_python_string = True
    contents = []
    for i in range(read_length):
    code = int(p.dereference())
    contents.append(code)
    p += 1
    # image
    double_quote = ord("\"")
    s = "+\""
    for c in contents:
    if type(contents) == bytearray:
    code = c
    valid = code < 0x80
    else:
    code = ord(c) if type(contents) == unicode else c
    valid = code <= 0xFFFF
    if valid and is_graphic(code) and code != double_quote:
    s += unichr(code)
    else:
    s += gnat_substitute(code, char_t)
    s += "\""
    if read_length < length: s += " & ..."
    self.image = s
    contents = read_string(p, read_length, char_t)
    self.image = wrapped_string_image(contents, read_length < length)

    def to_string(self):
    return self.image

    class Printer(gdb.printing.RegexpCollectionPrettyPrinter):
    def __call__(self, val):
    t = get_typename(val)
    # if t: print "{{" + t + "}}"
    if t and t.endswith("__unbounded_string"):
    return UnboundedStringPrinter(val)
    if t:
    # print "{{" + t + "}}"
    if t.find("__Tbounded_stringB__") >= 0:
    return BoundedStringPrinter(val)
    elif t.endswith("__unbounded_string"):
    return UnboundedStringPrinter(val)
    super(Printer, self).__call__(val)

    pp = Printer("drake")
    pp.add_printer("Bounded_String", '__Tbounded_stringB__', BoundedStringPrinter)
    pp.add_printer("Unbounded_String", '__unbounded_string$',
    UnboundedStringPrinter)
    gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
  2. @ytomino ytomino revised this gist Sep 27, 2016. 1 changed file with 50 additions and 41 deletions.
    91 changes: 50 additions & 41 deletions drake-gdb.py
    Original file line number Diff line number Diff line change
    @@ -1,74 +1,83 @@
    # from pprint import pprint
    import codecs
    import unicodedata

    def get_typename(val):
    t = gdb.types.get_basic_type(val.type).tag
    if not t: t = val.type.name
    return t

    def is_graphic(c):
    category = unicodedata.category(unichr(c))
    # print "{{%s}}" % category
    # excluding Cc, Cf, Co, Zl, Zp, not Cs(Surrogate)
    return (category != "Cc" and category != "Cf" and category != "Co" and
    category != "Zl" and category != "Zp")

    def gnat_substitute(c, char_t):
    if char_t.sizeof == 1:
    return "[\"%.2x\"]" % c
    elif char_t.sizeof == 2:
    return "[\"%.4x\"]" % c
    else:
    return "[\"%.8x\"]" % c

    length_limit = 1024

    class UnboundedStringPrinter:
    "Print a Unbounded_String"

    def __init__(self, val):
    global length_limit
    self.val = val
    # Character_Type
    typename = get_typename(self.val)
    char_typename = typename[0 : len(typename) - 16] + "character_type"
    self.char_t = gdb.lookup_type(char_typename)
    # make bytearray
    char_t = gdb.lookup_type(char_typename)
    # make (byte)array or unicode
    length = int(self.val["length"])
    items = self.val["data"].dereference()["items"] # fat pointer
    char_t_ptr_ptr = self.char_t.pointer().pointer()
    char_t_ptr_ptr = char_t.pointer().pointer()
    p = items.address.reinterpret_cast(char_t_ptr_ptr).dereference()
    if self.char_t.sizeof == 1:
    bin = bytearray(length)
    for i in range(length):
    read_length = length if length <= length_limit else length_limit
    if char_t.sizeof == 1:
    bin = bytearray(read_length)
    for i in range(read_length):
    code = int(p.dereference())
    if code < 0: code += 256 # signed?
    bin[i] = code
    p += 1
    try:
    self.data = bin.decode("utf-8")
    self.in_python_string = True
    contents = bin.decode("utf-8")
    except:
    self.data = bin
    self.in_python_string = False
    contents = bin
    else:
    self.in_python_string = True
    s = u""
    a = []
    for i in range(length):
    in_python_string = True
    contents = []
    for i in range(read_length):
    code = int(p.dereference())
    self.in_python_string &= code < 80
    if self.in_python_string: s += unichr(code)
    a.append(code)
    contents.append(code)
    p += 1
    if self.in_python_string:
    self.data = s
    # image
    double_quote = ord("\"")
    s = "+\""
    for c in contents:
    if type(contents) == bytearray:
    code = c
    valid = code < 0x80
    else:
    code = ord(c) if type(contents) == unicode else c
    valid = code <= 0xFFFF
    if valid and is_graphic(code) and code != double_quote:
    s += unichr(code)
    else:
    self.data = a
    s += gnat_substitute(code, char_t)
    s += "\""
    if read_length < length: s += " & ..."
    self.image = s

    def to_string(self):
    if self.in_python_string:
    return self.data
    else:
    s = "+\""
    for c in self.data:
    if c < 0x80:
    s += chr(c)
    elif self.char_t.sizeof == 1:
    s += "[\"%.2x\"]" % c
    elif self.char_t.sizeof == 2:
    s += "[\"%.4x\"]" % c
    else:
    s += "[\"%.8x\"]" % c
    s += "\""
    return s

    def display_hint (self):
    if self.in_python_string:
    return "string"
    else:
    return "string(binary)"
    return self.image

    class Printer(gdb.printing.RegexpCollectionPrettyPrinter):
    def __call__(self, val):
  3. @ytomino ytomino revised this gist Sep 26, 2016. 1 changed file with 54 additions and 22 deletions.
    76 changes: 54 additions & 22 deletions drake-gdb.py
    Original file line number Diff line number Diff line change
    @@ -5,38 +5,70 @@ def get_typename(val):
    if not t: t = val.type.name
    return t

    class UnboundedStringPrinter(object):
    class UnboundedStringPrinter:
    "Print a Unbounded_String"

    def __init__(self, val):
    self.val = val

    def to_string(self):
    length = int(self.val["length"])
    data = self.val["data"].dereference()
    items = data["items"]
    # Character_Type
    typename = get_typename(self.val)
    char_typename = typename[0 : len(typename) - 16] + "character_type"
    char_t = gdb.lookup_type(char_typename)
    char_t_ptr_ptr = char_t.pointer().pointer()
    self.char_t = gdb.lookup_type(char_typename)
    # make bytearray
    length = int(self.val["length"])
    items = self.val["data"].dereference()["items"] # fat pointer
    char_t_ptr_ptr = self.char_t.pointer().pointer()
    p = items.address.reinterpret_cast(char_t_ptr_ptr).dereference()
    s = "+\""
    for i in range(length):
    c = int(p.dereference())
    if c < 0x80:
    s += chr(c)
    elif char_t.sizeof == 1:
    s += "[\"%.2x\"]" % c
    elif char_t.sizeof == 2:
    s += "[\"%.4x\"]" % c
    if self.char_t.sizeof == 1:
    bin = bytearray(length)
    for i in range(length):
    code = int(p.dereference())
    if code < 0: code += 256 # signed?
    bin[i] = code
    p += 1
    try:
    self.data = bin.decode("utf-8")
    self.in_python_string = True
    except:
    self.data = bin
    self.in_python_string = False
    else:
    self.in_python_string = True
    s = u""
    a = []
    for i in range(length):
    code = int(p.dereference())
    self.in_python_string &= code < 80
    if self.in_python_string: s += unichr(code)
    a.append(code)
    p += 1
    if self.in_python_string:
    self.data = s
    else:
    s += "[\"%.8x\"]" % c
    p += 1
    s += "\""
    return s
    self.data = a

    def to_string(self):
    if self.in_python_string:
    return self.data
    else:
    s = "+\""
    for c in self.data:
    if c < 0x80:
    s += chr(c)
    elif self.char_t.sizeof == 1:
    s += "[\"%.2x\"]" % c
    elif self.char_t.sizeof == 2:
    s += "[\"%.4x\"]" % c
    else:
    s += "[\"%.8x\"]" % c
    s += "\""
    return s

    def display_hint (self):
    return "Unbounded_String"
    if self.in_python_string:
    return "string"
    else:
    return "string(binary)"

    class Printer(gdb.printing.RegexpCollectionPrettyPrinter):
    def __call__(self, val):
  4. @ytomino ytomino created this gist Sep 26, 2016.
    52 changes: 52 additions & 0 deletions drake-gdb.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    # from pprint import pprint

    def get_typename(val):
    t = gdb.types.get_basic_type(val.type).tag
    if not t: t = val.type.name
    return t

    class UnboundedStringPrinter(object):
    "Print a Unbounded_String"

    def __init__(self, val):
    self.val = val

    def to_string(self):
    length = int(self.val["length"])
    data = self.val["data"].dereference()
    items = data["items"]
    typename = get_typename(self.val)
    char_typename = typename[0 : len(typename) - 16] + "character_type"
    char_t = gdb.lookup_type(char_typename)
    char_t_ptr_ptr = char_t.pointer().pointer()
    p = items.address.reinterpret_cast(char_t_ptr_ptr).dereference()
    s = "+\""
    for i in range(length):
    c = int(p.dereference())
    if c < 0x80:
    s += chr(c)
    elif char_t.sizeof == 1:
    s += "[\"%.2x\"]" % c
    elif char_t.sizeof == 2:
    s += "[\"%.4x\"]" % c
    else:
    s += "[\"%.8x\"]" % c
    p += 1
    s += "\""
    return s

    def display_hint (self):
    return "Unbounded_String"

    class Printer(gdb.printing.RegexpCollectionPrettyPrinter):
    def __call__(self, val):
    t = get_typename(val)
    # if t: print "{{" + t + "}}"
    if t and t.endswith("__unbounded_string"):
    return UnboundedStringPrinter(val)
    super(Printer, self).__call__(val)

    pp = Printer("drake")
    pp.add_printer("Unbounded_String", '__unbounded_string$',
    UnboundedStringPrinter)
    gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)