def _UnserializableObjectFallback(self, obj):
    """Handles sanitizing of unserializable objects for Json.

    For instances of heap types, we take the class dict, augment it with the
    instance's __dict__, tag it and transmit it over to the RPC client to be
    reconstructed there. (Works with both old and new style classes)
    Args:
      obj: The object to Json-serialize
    Returns:
      A Json-serializable version of the parameter
    """
    if isinstance(obj, libpython.PyInstanceObjectPtr):
      # old-style classes use 'classobj'/'instance'
      # get class attribute dictionary
      in_class = obj.pyop_field('in_class')
      result_dict = in_class.pyop_field('cl_dict').proxyval(set())

      # let libpython.py do the work of getting the instance dict
      instanceproxy = obj.proxyval(set())
      result_dict.update(instanceproxy.attrdict)
      result_dict['__pyringe_type_name__'] = instanceproxy.cl_name
      result_dict['__pyringe_address__'] = instanceproxy.address
      return result_dict

    if isinstance(obj, libpython.HeapTypeObjectPtr):
      # interestingly enough, HeapTypeObjectPtr seems to handle all pointers to
      # heap type PyObjects, not only pointers to PyHeapTypeObject. This
      # corresponds to new-style class instances. However, as all instances of
      # new-style classes are simple PyObject pointers to the interpreter,
      # libpython.py tends to give us HeapTypeObjectPtrs for things we can't
      # handle properly.

      try:
        # get class attribute dictionary
        type_ptr = obj.field('ob_type')
        tp_dict = type_ptr.cast(GdbCache.TYPE)['tp_dict'].cast(GdbCache.DICT)
        result_dict = libpython.PyDictObjectPtr(tp_dict).proxyval(set())
      except gdb.error:
        # There was probably a type mismatch triggered by wrong assumptions in
        # libpython.py
        result_dict = {}

      try:
        # get instance attributes
        result_dict.update(obj.get_attr_dict().proxyval(set()))
        result_dict['__pyringe_type_name__'] = obj.safe_tp_name()
        result_dict['__pyringe_address__'] = long(obj._gdbval)  # pylint: disable=protected-access
        return result_dict
      except TypeError:
        # This happens in the case where we're not really looking at a heap type
        # instance. There isn't really anything we can do, so we fall back to
        # the default handling.
        pass
    # Default handler -- this does not result in proxy objects or fancy dicts,
    # but most of the time, we end up emitting strings of the format
    # '<object at remote 0x345a235>'
    try:
      proxy = obj.proxyval(set())
      # json doesn't accept non-strings as keys, so we're helping along
      if isinstance(proxy, dict):
        return {str(key): val for key, val in proxy.iteritems()}
      return proxy
    except AttributeError:
      return str(obj)
Handles sanitizing of unserializable objects for Json.

    For instances of heap types, we take the class dict, augment it with the
    instance's __dict__, tag it and transmit it over to the RPC client to be
    reconstructed there. (Works with both old and new style classes)
    Args:
      obj: The object to Json-serialize
    Returns:
      A Json-serializable version of the parameter