コード例 #1
0
 def get_table(self):
     if not gdb_stopped() or not inferior_alive():
         raise RuntimeError
     rows_regs = []
     for regname in self.regnames:
         regvalue = valcache(regname)
         self.regvals[regname] = str(regvalue)
         chunks = self.get_register_chunks(regname=regname,
                                           regvalue=regvalue)
         col = {'chunks': chunks}
         row = {'columns': [col]}
         rows_regs.append(row)
     return {'rows': rows_regs}
コード例 #2
0
 def value(self):
     ''' Вернуть gdb.Value, которое соответствует path'''
     path = self.path_from_root()
     value = gdb.parse_and_eval(path[0])
     for name in path[1:]:
         if type(name) is gdb.Type:
             value = value.cast(name)
         else:
             assert type(name) in (int, str, unicode,
                                   gdb.Field), 'path={path}'.format(
                                       path=path)
             try:
                 value = value[name]
             except gdb.error:
                 return None
                 #gdb_print('cant access path=%s id=%s\n' % (str(self),self.id))
     return valcache(value)
コード例 #3
0
 def is_array_fetchable(self, arr, n1, n2):
     '''Данная функция возвращает True, если элементы массива с номерами [n1,n2] включая концы
     доступны для чтения. False в противном случае.
     Прочитанные (fetch_lazy) значения массива будут сохранены в кэш.
 '''
     try:
         valcache(arr[n1]).fetch_lazy()
         if n2 == None:
             return True
         valcache(arr[n2]).fetch_lazy()
         for i in range(n1 + 1, n2):
             valcache(arr[i]).fetch_lazy()
     except gdb.MemoryError:
         return False
     return True
コード例 #4
0
def get_local_variables(frame):
    if not frame:
        return {}
    try:
        block = frame.block()
    except RuntimeError:
        return {}
    variables = {}
    while block:
        for symbol in block:
            if (symbol.is_argument or symbol.is_variable):
                name = symbol.name
                if name not in variables:
                    variables[name] = valcache(symbol.value(frame))
        if block.function:
            break
        block = block.superblock
    ordered_vars = OrderedDict()
    for key in sorted(variables):
        ordered_vars[key] = variables[key]
    return ordered_vars
コード例 #5
0
def get_frame_func_args(frame):
    ''' Возвращает список пар: (имя аргумента, строковое представление аргумента) '''
    args = []
    try:
        block = frame.block()
    except RuntimeError:
        return []
    while block:
        for sym in block:
            if sym.is_argument:
                value = valcache(sym.value(frame))
                try:
                    strvalue = stringify_value(value)
                except ValueUnavailable:
                    strvalue = ValueUnavailable.default_stub
                args.append((sym.name, strvalue))
        if block.function:
            break
        block = block.superblock
        if (not block):
            break
    return args
コード例 #6
0
 def get_local_vars_1(self):
     try:
         frame = gdb.selected_frame()
     except gdb.error:
         return []
     if not frame:
         return []
     try:
         block = frame.block()
     except RuntimeError:
         return []
     variables = {}
     while block:
         for symbol in block:
             if (symbol.is_argument or symbol.is_variable):
                 name = symbol.name
                 if name not in variables:
                     variables[name] = valcache(symbol.value(frame))
         if block.function:
             break
         block = block.superblock
     return variables
コード例 #7
0
    def struct_to_chunks(self,
                         value,
                         name,
                         path,
                         fields=None,
                         expand_depth=0,
                         **kwargs):
        '''
        :param fields: list of gdb.Field If this argument specified then only this fields will be print
    '''
        type_code = value.type.strip_typedefs().code  #may be union or struct
        chunks = []
        chunks += self.chunks_type_name(value, name, **kwargs)
        value_addr = value.address
        #first check whether we can read memory occupied by struct (value)
        collapsed = self.expand_variable.get(path.id)
        expand_single = self.expand_single_array_elem(
            path
        )  #True, Если данная структура получается в результате разыменования уазателя,
        #причем в slice у указателя стоит только один элемент, а не диапазон.
        ok_expand_depth = expand_depth > 0
        if (collapsed == False) or (collapsed == None and not expand_single
                                    and not ok_expand_depth):
            chunks += self.collapsed_struct_to_chunks(path, **kwargs)
            return chunks

        chunks1 = []
        data_chunks = []
        base_classes = []

        target_fields = fields if fields else value.type.strip_typedefs(
        ).fields()
        try:
            for idx, field in enumerate(target_fields):
                field_value, field_name, value_path = None, None, None
                if field.is_base_class:
                    base_type = gdb.lookup_type(field.name)
                    field_value = value.cast(base_type)
                    tochunks = lambda value, name, path, **kwargs: self.value_to_chunks_1(
                        value=value, name='<INHERITANCE>', path=path, **kwargs)
                    value_path = path.cast(base_type, tochunks=tochunks)
                else:
                    field_name = field.name
                    if field_name == None:
                        #this is anonymous field. For example:
                        # class A {
                        #    union {
                        #      int x;
                        #      double y;
                        #    };
                        # };
                        # class A have fielns x,y and UNION is anonimous field
                        value_name = self.type_code_to_string[field.type.code]
                        tochunks = (
                            lambda value_name: lambda value, name, path, **
                            kwargs: self.value_to_chunks_1(
                                value=value,
                                name=value_name,
                                path=path,
                                **self.update_kwargs(
                                    expand_depth=max(1, expand_depth - 1),
                                    print_typename=False,
                                    kwargs=kwargs)))(value_name)
                        field_value = value[field]
                        value_path = path.append(name=(idx, None),
                                                 tochunks=tochunks,
                                                 field=field)
                    else:
                        field_value = valcache(value[field_name])
                        value_path = path.append(name=field_name)
                        tochunks = lambda value, name, path, **kwargs: self.value_to_chunks_1(
                            value, name, path, **kwargs)
                data_chunks += tochunks(field_value,
                                        field_name,
                                        value_path,
                                        expand_depth=expand_depth - 1,
                                        **kwargs)
                data_chunks.append({'str': '\n'})
            if type_code == gdb.TYPE_CODE_STRUCT:
                chunks1.append({
                    'chunks': data_chunks,
                    'type_code': 'TYPE_CODE_STRUCT'
                })
            elif type_code == gdb.TYPE_CODE_UNION:
                chunks1.append({
                    'chunks': data_chunks,
                    'type_code': 'TYPE_CODE_UNION'
                })
            chunks.append({
                'str':
                '{\n',
                'onclick_data':
                self.base_onclick_data('collapse_variable', path_id=path.id),
            })
            chunks.append({
                'chunks': chunks1,
            })
            chunks.append({
                'str':
                '\n}\n',
                'onclick_data':
                self.base_onclick_data('collapse_variable', path_id=path.id),
            })
        except:
            chunks = [UNAVAILABLE_CHUNK]
        return chunks
コード例 #8
0
    def array_to_chunks(self,
                        value,
                        name,
                        n1,
                        n2,
                        path,
                        slice_clickable=True,
                        **kwargs):
        ''' Конвертация массива или указателя, который указывает на массив в json-дерево.

        Args:
          n1 (int): Начиная с этого номера элементы массива будут напечатаны.
          n2 (int): включительно по этот номер будут напечатаны элементы массива.

        Если элементы массива не указатели, то печатается нечто вроде
        arr = [p1,p2,..,pn]
        Если элементы массива есть указатели, тип которых не "char *"
        и не "void *", то печатается конструкция вида
        arr = [
           *(p1) = [...]
           *(p2) = [...]
        ]
        Где p1,p2 есть адреса, а конструкция между  [...] есть содержимое указателя

    '''
        chunks = []

        type_code = value.type.strip_typedefs().code
        if name != None:
            if kwargs.get('print_typename', True):
                chunks += self.value_type_to_chunks(value, **kwargs)
                chunks.append({'str': ' '})

            if type(name) is str:
                slice_chunk = self.make_slice_chunk(
                    n1, n2, path, slice_clickable=slice_clickable)
                varname = [
                    {
                        'str': name,
                        'name': 'varname'
                    },
                    slice_chunk,
                ]
                chunks += varname
            else:
                chunks += name
            chunks += [{'str': ' = '}]
        #if read address of value is impossible then impossible evaluate value[idx].
        if not self.address_available(value):
            chunks.append(UNAVAILABLE_CHUNK)
            return chunks

        if not self.expand_variable.get(path.id):
            chunks += self.collapsed_array_to_chunks(path, **kwargs)
            return chunks

        chunks1 = []
        array_data_chunks = []
        n22 = n2 + 1 if n2 != None else n1 + 1
        deref_value = value[n1]
        deref_type_code = deref_value.type.strip_typedefs().code
        deref_type_str = str(deref_value.type.strip_typedefs())
        if deref_type_code == (
                gdb.TYPE_CODE_PTR
                and not re.match('.*((char \*)|(void \*))$', deref_type_str)
                and not is_incomplete_type_ptr(deref_value)):
            elem_as_array = True
        else:
            elem_as_array = False

        arr_elem_size = deref_value.type.strip_typedefs().sizeof
        arr_size = n2 - n1 + 1 if n2 != None else 1
        if 'delimiter' in kwargs:
            delimiter = kwargs['delimiter']
        else:
            if deref_type_code in (gdb.TYPE_CODE_INT, gdb.TYPE_CODE_FLT):
                delimiter = {'str': ', '}
            else:
                delimiter = {'str': ',\n'}
        for i in range(n1, n22):
            value_idx = valcache(value[i])
            if value_idx.is_optimized_out:
                elem_chunk = OPTIMIZED_OUT_CHUNK
            else:
                if elem_as_array:  #pointer, not really array
                    tochunks = lambda value, name, path, **kwargs: self.subarray_pointer_data_chunks(
                        value, path, **kwargs)
                else:
                    if deref_type_code == gdb.TYPE_CODE_ARRAY:
                        tochunks = lambda value, name, path, **kwargs: self.value_to_chunks_1(
                            value=value,
                            name='',
                            path=path,
                            suppress_array_addr=True,
                            **kwargs)
                    else:
                        tochunks = lambda value, name, path, **kwargs: self.value_to_chunks_1(
                            value=value, name=None, path=path, **kwargs)
                #we can try read memory that occupies element of array, but it is bad approach.
                #Because in this check we read memory and if OK then when we will convert value to tree
                #we secondary will be read memory. In embedding systems reading of memory can take a lot of time.
                #
                # According to this, we convert value to and if in some place we get error, exception
                # ValueUnavailable will be raised.
                tochunks = self.catch_unavailable(tochunks)
                path_idx = path.append(
                    name=i,
                    tochunks=tochunks,
                )
                chs = tochunks(
                    value_idx, None,
                    path_idx)  #inside this function id must be appended
                assert len(chs) == 1
                elem_chunk = chs[0]
                assert 'id' in elem_chunk
            array_data_chunks.append(elem_chunk)
            if delimiter and i != n22 - 1:
                array_data_chunks.append(delimiter)
        array_data_chunks.append({'str': '\n'})
        chunks1.append({
            'chunks': array_data_chunks,
            'type_code': 'TYPE_CODE_ARRAY'
        })
        chunks.append({
            'str':
            '[\n',
            'onclick_data':
            self.base_onclick_data('collapse_variable', path_id=path.id)
        })
        chunks.append({
            'chunks': chunks1,
            'name': 'parenthesis',
        })
        chunks.append({
            'str':
            '\n]\n',
            'onclick_data':
            self.base_onclick_data('collapse_variable', path_id=path.id)
        })
        return chunks