Подтвердить что ты не робот

Определение функции печати gdb для структур C

когда я пишу код в Java, я использую отладчик, встроенный в Eclipse. При визуализации объекта в этом контексте отладчик автоматически вызывает функцию toString(), которая мне очень удобна для быстрой визуализации при изучении состояния программы.

Теперь, когда я работаю на C, я использую emacs + gdb для отладки, но мне не удалось найти/воссоздать эквивалентную функцию для визуализации сложных структур C (т.е. вызвать определенную функцию печати). Конечно, нет общего метода toString(), но в любом случае я очень часто реализовал где-то функцию печати для своих структур.

Но когда я хочу визуализировать что-то в gdb, я должен вызвать эти функции печати вручную из gdb, выполняющего p my_print_function(my_struct_pointer), что довольно неэффективно (нужно помнить его имя, набирать его правильно, причем стандартный вывод может быть в другие окна...).

Мне хотелось бы настроить gdb, чтобы сказать "при вызове функции печати gdb на тип указателя типа T, автоматически вызывать эту пользовательскую функцию печати f...". Есть ли способ сделать это? Спасибо заранее.

4b9b3361

Ответ 1

Хороший вопрос.

Да, я думаю. Кажется, GDB 7 поддерживает "довольно-принтеры" , написанные на Python. Не так удобно (на мой взгляд) использовать уже написанный код на реальном целевом языке, но, возможно, достаточно хорошо.

Это команды для работы с симпатичными принтерами.

Ответ 2

используйте print struct_var для печати элементов данной структуры

использовать print *struct_ptr для печати элементов заданного указателя структуры

используйте set print pretty on, если вы хотите, чтобы gdb печатал структуры в формате с отступом с одним членом на строку, например:

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

а также вы можете использовать ptype struct_var для печати определения данной структуры

подробнее здесь

Ответ 3

Хотя у меня не было времени узнать всю теорию довольно печатной теории gdb/python, я нашел простой способ повторно использовать свои C-принтеры в gdb.

Пример связывания структур "struct_name_1" и "struct_name_2" с функцией C "struct_printer_1_c_func" и "struct_printer_2_c_func":

1) Создайте файл 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) Добавьте это в свой .gdbinit:

source struct_printers.py

define pstruct  
p $pstruct($arg0) 
end

Затем, когда вы находитесь в gdb перед указателем на структуру, которую хотите исследовать, вызовите pstruct вместо печати. ​​

Вероятно, уродливый и плохо расширяемый, но работает достаточно хорошо для того, что мне нужно (однако я был бы рад, что кто-то знает правильный способ сделать это с питонским довольно-печатным материалом).