Depuración de Extensiones Python con GDB: Comando Personalizado para Inspección de Variables

Esta funcionalidad permite imprimir el valor de varialbes, incluyendo la estructura, contenido y dirección de estructuras de datos enlazadas.

Registro de comandos personalizados en GDB

import gdb
import gdb.types

# Obtener información de tipo &xxxxxx

ARCHIVO_LOG = 'analisis_tipo.log'

def registrar_log(mensaje):
    archivo = open(ARCHIVO_LOG, "a")
    archivo.write(mensaje + '\n')
    archivo.close()


class AnalizarTipo(gdb.Command):
    def __init__(self):
        super(AnalizarTipo, self).__init__("analizartipo", gdb.COMMAND_USER)  # Registro del comando analizartipo
        self.lista_direcciones = []

    def invocar(self, argumentos, desde_tty):  # Método obligatorio para comandos Python en GDB
        '''
        El primer argumento debe ser un puntero
        '''
        args = gdb.string_to_argv(argumentos)  # Conversión de argumentos a lista
        variable_raiz = gdb.parse_and_eval(args[0]).dereference() # Convertir a objeto gdb.Value
        self._procesar_variable(0, args[0], variable_raiz)   # Llamada al método de procesamiento

    def _procesar_variable(self, profundidad, nombre_var, valor_var):
        # Para el registro de logs
        espaciado1 = " " * 2 * profundidad
        profundidad += 1
        espaciado2 = " " * 2 * profundidad + '-'
        
        # Procesamiento de variable
        tipo_var = valor_var.type      
        tipo_basico = gdb.types.get_basic_type(tipo_var)   
        direccion_var = valor_var.address
        
        # Escribir en el archivo de log
        registrar_log("%s%s:" % (espaciado1, nombre_var))
        registrar_log("%stipo=%s" % (espaciado2, tipo_var))
        registrar_log("%stipo_basico=%s" % (espaciado2, tipo_basico))
        registrar_log("%sdireccion=%s" % (espaciado2, direccion_var))
        registrar_log("%svalor=%s" % (espaciado2, valor_var))

        if '*' in str(tipo_basico):
            # El valor de un puntero es una dirección
            if valor_var in self.lista_direcciones or valor_var is None:   
                return None
            self.lista_direcciones.append(valor_var)   # Evitar bucles en listas enlazadas

            nombre_var = '*' + nombre_var
            valor_referenciado = valor_var.dereference()  # Obtener valor al que apunta el puntero
            self._procesar_variable(profundidad, nombre_var, valor_referenciado)  
        elif 'struct' in str(tipo_basico):
            campos = valor_var.type.fields()   # Para estructuras, iterar sobre sus campos
            for i, campo in enumerate(campos):
                nombre_campo = campo.name
                valor_campo = valor_var[nombre_campo]     # Acceso a elementos de estructura como diccionario
                self._procesar_variable(profundidad, nombre_campo, valor_campo)


AnalizarTipo()

(gdb) source analizartipo.py

(gdb) analizartipo &variable # El comando se ejecuta con una dirección de variable, los resultados se guardarán en analisis_tipo.log

tipo_basico

Etiquetas: GDB depuración Python extensiones comandos personalizados

Publicado el 7-20 05:43