Changeset 249030 in webkit


Ignore:
Timestamp:
Aug 22, 2019 3:06:54 PM (5 years ago)
Author:
dbates@webkit.org
Message:

[lldb-webkit] OptionSet summary shows size 0 sometimes for non-empty set
https://bugs.webkit.org/show_bug.cgi?id=200742

Reviewed by Simon Fraser.

The OptionSet synthetic provider must respond to requests for the value of m_storage
(i.e. GetChildMemberWithName('m_storage')) to avoid interfering with the computation
of the type summary.

Synthetic providers substitute alternative debug information (children) for the default
information for a variable. The OptionSet type summary is implemented in terms of the
OptionSet synthetic provider to maximize code reuse. If LLDB instantiates the provider
before invoking the type summary handler then evaluating GetChildMemberWithName() on
the SBValue passed to the type summary handler will access the substitute information
instead of the original debug information. As a result OptionSet's synthetic provider's
get_child_index('m_storage') returns None hence SBValue.GetChildMemberWithName('m_storage')
returned an invalid value; => WTFOptionSetProvider._bitmask() returns 0; => the size
reported in the type summary for the OptionSet is 0. Instead get_child_index('m_storage')
should return a valid value.

  • lldb/lldb_webkit.py:

(FlagEnumerationProvider.init):
(FlagEnumerationProvider):
(FlagEnumerationProvider._get_child_index): Added. WTFOptionSetProvider will override.
(FlagEnumerationProvider._get_child_at_index): Added. WTFOptionSetProvider will override.
(FlagEnumerationProvider.size): Added.
(FlagEnumerationProvider.get_child_index): Modified to call _get_child_index().
(FlagEnumerationProvider.get_child_at_index): Modified to call _get_child_at_index().
(FlagEnumerationProvider.update): Moved initialization of self._elements to the constructor
and removed self.size. For the latter we can just expose a getter that returns the size of
the list self._elements.
(WTFOptionSetProvider._get_child_index): Added. Return the index for LLDB to query for the
value of m_storage.
(WTFOptionSetProvider):
(WTFOptionSetProvider._get_child_at_index): Added. Return the value for m_storage if it
matches the specified index.

  • lldb/lldb_webkit_unittest.py:

(TestSummaryProviders.serial_test_WTFOptionSetProvider_empty): Update expected result now
that we return the value of m_storage as the last synthetic child.

Location:
trunk/Tools
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r249024 r249030  
     12019-08-22  Daniel Bates  <dabates@apple.com>
     2
     3        [lldb-webkit] OptionSet summary shows size 0 sometimes for non-empty set
     4        https://bugs.webkit.org/show_bug.cgi?id=200742
     5
     6        Reviewed by Simon Fraser.
     7
     8        The OptionSet synthetic provider must respond to requests for the value of m_storage
     9        (i.e. GetChildMemberWithName('m_storage')) to avoid interfering with the computation
     10        of the type summary.
     11
     12        Synthetic providers substitute alternative debug information (children) for the default
     13        information for a variable. The OptionSet type summary is implemented in terms of the
     14        OptionSet synthetic provider to maximize code reuse. If LLDB instantiates the provider
     15        before invoking the type summary handler then evaluating GetChildMemberWithName() on
     16        the SBValue passed to the type summary handler will access the substitute information
     17        instead of the original debug information. As a result OptionSet's synthetic provider's
     18        get_child_index('m_storage') returns None hence SBValue.GetChildMemberWithName('m_storage')
     19        returned an invalid value; => WTFOptionSetProvider._bitmask() returns 0; => the size
     20        reported in the type summary for the OptionSet is 0. Instead get_child_index('m_storage')
     21        should return a valid value.
     22
     23        * lldb/lldb_webkit.py:
     24        (FlagEnumerationProvider.__init__):
     25        (FlagEnumerationProvider):
     26        (FlagEnumerationProvider._get_child_index): Added. WTFOptionSetProvider will override.
     27        (FlagEnumerationProvider._get_child_at_index): Added. WTFOptionSetProvider will override.
     28        (FlagEnumerationProvider.size): Added.
     29        (FlagEnumerationProvider.get_child_index): Modified to call _get_child_index().
     30        (FlagEnumerationProvider.get_child_at_index): Modified to call _get_child_at_index().
     31        (FlagEnumerationProvider.update): Moved initialization of self._elements to the constructor
     32        and removed self.size. For the latter we can just expose a getter that returns the size of
     33        the list self._elements.
     34        (WTFOptionSetProvider._get_child_index): Added. Return the index for LLDB to query for the
     35        value of m_storage.
     36        (WTFOptionSetProvider):
     37        (WTFOptionSetProvider._get_child_at_index): Added. Return the value for m_storage if it
     38        matches the specified index.
     39        * lldb/lldb_webkit_unittest.py:
     40        (TestSummaryProviders.serial_test_WTFOptionSetProvider_empty): Update expected result now
     41        that we return the value of m_storage as the last synthetic child.
     42
    1432019-08-22  Jonathan Bedard  <jbedard@apple.com>
    244
  • trunk/Tools/lldb/lldb_webkit.py

    r248980 r249030  
    736736    def __init__(self, valobj, internal_dict):
    737737        self.valobj = valobj
     738        self._elements = []
    738739        self.update()
    739740
     
    751752        pass
    752753
     754    # Subclasses can override this to provide the index that corresponds to the specified name.
     755    # If this method is overridden then it is also expected that _get_child_at_index() will be
     756    # overridden to provide the value for the index returned by this method. Note that the
     757    # returned index must be greater than or equal to self.size in order to avoid breaking
     758    # printing of synthetic children.
     759    def _get_child_index(self, name):
     760        return None
     761
     762    # Subclasses can override this to provide the SBValue for the specified index. It is only
     763    # meaningful to override this method if _get_child_index() is also overridden.
     764    def _get_child_at_index(self, index):
     765        return None
     766
     767    @property
     768    def size(self):
     769        return len(self._elements)
     770
     771    # LLDB overrides
    753772    def has_children(self):
    754773        return bool(self._elements)
     
    758777
    759778    def get_child_index(self, name):
    760         try:
    761             return int(name.lstrip('[').rstrip(']'))
    762         except:
    763             return None
     779        return self._get_child_index(name)
    764780
    765781    def get_child_at_index(self, index):
     
    769785            (name, value) = self._elements[index]
    770786            return self.valobj.CreateValueFromExpression(name, str(value))
    771         return None
     787        return self._get_child_at_index(index)
    772788
    773789    def update(self):
    774790        self._update()
    775 
    776         self._elements = []
    777         self.size = 0
    778791
    779792        enumerator_value_to_name_map = self._enumerator_value_to_name_map()
     
    794807            bitmask = bitmask & (bitmask - 1)  # Turn off the rightmost set bit.
    795808        self._elements = elements
    796         self.size = len(elements)
    797 
    798809
    799810class WTFOptionSetProvider(FlagEnumerationProvider):
     
    812823    def _update(self):
    813824        self.storage = self.valobj.GetChildMemberWithName('m_storage')  # May be an invalid value.
     825
     826    def _get_child_index(self, name):
     827        if name == 'm_storage':
     828            return self.size
     829        return None
     830
     831    def _get_child_at_index(self, index):
     832        if index == self.size:
     833            return self.storage
     834        return None
    814835
    815836
  • trunk/Tools/lldb/lldb_webkit_unittest.py

    r237564 r249030  
    186186        variable = self._sbFrame.FindVariable('exampleFlagsEmpty')
    187187        provider = lldb_webkit.WTFOptionSetProvider(variable, {})
    188         self.assertEqual(provider.get_child_at_index(0), None)
     188        self.assertEqual(provider.get_child_at_index(0).GetName(), 'm_storage')
    189189
    190190    def serial_test_WTFOptionSetProvider_simple(self):
Note: See TracChangeset for help on using the changeset viewer.