2013-03-01 9 views
12

kiedy piszę kod w Javie, używam debuggera osadzonego w Eclipse. Podczas wizualizacji obiektu w tym kontekście debugger automatycznie wywołuje funkcję toString(), która jest bardzo wygodna dla szybkiej wizualizacji podczas eksplorowania stanu programu.Definiowanie funkcji drukowania gdb dla struktur C

Teraz, gdy pracuję w C, używam emacs + gdb do debugowania, ale nie udało mi się znaleźć/odtworzyć równoważnej funkcji do wizualizacji skomplikowanych struktur C (np. Wywołanie konkretnej funkcji drukowania). Oczywiście nie ma ogólnej metody toString(), ale w każdym razie bardzo często zaimplementowałem funkcję drukowania dla moich struktur.

Ale kiedy chcę wizualizować coś w gdb, muszę wywołać te funkcje drukowania ręcznie z gdb robi p my_print_function(my_struct_pointer), co jest dość nieskuteczne (trzeba zapamiętać jego nazwę, wpisać poprawnie, ponadto standardowe wyjście może być w innym okna ...).

Rzecz Chciałbym to skonfigurować gdb do powiedzenia „podczas wywoływania funkcji drukowania gdb od rodzaju wskaźnika struct T, zadzwoń automatycznie, że funkcja drukowania zdefiniowane przez użytkownika f ...”. Czy jest jakiś sposób na zrobienie tego? Z góry dziękuję.

Odpowiedz

5

Dobre pytanie.

Tak, tak sądzę. Wygląda na to, że GDB 7 ma wsparcie dla "pretty-printers" written in Python. Nie tak wygodne (moim zdaniem), jak używanie już napisanego kodu w rzeczywistym języku docelowym, ale być może wystarczająco dobre.

These are the commands do pracy z ładnymi drukarkami.

+0

Niezbyt wygodnie ... ale prawdopodobnie najlepsze istniejące rozwiązanie. Dzięki. – Hobbes

7

użycie print struct_var wydrukować członków danej struktury

użytku print *struct_ptr wydrukować członków danego wskaźnika struct

użytku set print pretty on jeśli chcesz gdb wydrukować struktur w formacie wcięte z jednego członka jednej linii, tak:

$1 = { 
     next = 0x0, 
     flags = { 
      sweet = 1, 
      sour = 1 
     }, 
     meat = 0x54 "Pork" 
     } 

a także można użyć ptype struct_var wydrukować definicję danej struktury

więcej informacji here

1

Chociaż nie miałem czasu, aby nauczyć się wszystkich teorii całkiem-druk gdb/python, znalazłem prosty sposób na ponowne wykorzystanie moich drukarek C w gdb.

przykład połączyć konstrukcjom "struct_name_1" i "struct_name_2" do funkcji "struct_printer_1_c_func C" i "struct_printer_2_c_func":

1) Tworzenie pliku struct_printers.py

class Pstruct (gdb.Function): 
    """Returns a string describing a struct... 
    """ 

    def __init__ (self): 
    super (Pstruct, self).__init__ ("pstruct") 

    def invoke (self, name): 
     expr_type = name.dereference().type.tag 
     expr_string = name.__str__()    
     expr_address = expr_string.split(" ")[0]  
     if (cmp(expr_type, "struct_name_1") == 0): 
     return gdb.parse_and_eval("struct_printer_1_c_func("+ expr_address +")") 
     elif (cmp(expr_type, "struct_name_2") == 0): 
     return gdb.parse_and_eval("struct_printer_2_c_func("+ expr_address +")") 
     else: 
     print "[No struct printer for this type]" 
     return gdb.parse_and_eval(expr_address) 

Pstruct() 

2) Dodać to do .gdbinit:

source struct_printers.py 

define pstruct 
p $pstruct($arg0) 
end 

Potem, gdy uruchamiany jest gdb przed wskaźnik do struct chcesz zbadać, zadzwoń pstruct zamiast druku.

Prawdopodobnie brzydki i słabo rozszerzalny, ale działa wystarczająco dobrze na to, czego potrzebowałem (jednak byłbym zadowolony, że ktoś zna właściwą metodę zrobienia tego z pythonowymi materiałami drukowanymi).