Я не очень хорошо знаком с Python, и я просто открываю возможности сценариев для python для GDB; мотивировка моего вопроса заключается в усилении печати значений GDB внутри монитора MELT, который позже будет подключен к GCC MELT. Но вот более простой вариант.
Моя система - Linux/Debian/Sid/x86-64. компилятор GCC - 4.8.2; отладчик GDB - 7.6.2; его питон составляет 3,3
Я хочу отлаживать программу C с типом "дискриминационный союз":
// file tiny.c in the public domain by Basile Starynkevitch
// compile with gcc -g3 -Wall -std=c99 tiny.c -o tiny
// debug with gdb tiny
// under gdb: python tiny-gdb.py
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef union my_un myval_t;
enum tag_en {
tag_none,
tag_int,
tag_string,
tag_sequence
};
struct boxint_st;
struct boxstring_st;
struct boxsequence_st;
union my_un {
void* ptr;
enum tag_en *ptag;
struct boxint_st *pint;
struct boxstring_st *pstr;
struct boxsequence_st *pseq;
};
struct boxint_st {
enum tag_en tag; // for tag_int
int ival;
};
struct boxstring_st {
enum tag_en tag; // for tag_string
char strval[]; // a zero-terminated C string
};
struct boxsequence_st {
enum tag_en tag; // for tag_sequence
unsigned slen;
myval_t valtab[]; // of length slen
};
int main (int argc, char **argv) {
printf ("start %s, argc=%d", argv[0], argc);
struct boxint_st *iv42 = malloc (sizeof (struct boxint_st));
iv42->tag = tag_int;
iv42->ival = 42;
struct boxstring_st *istrhello =
malloc (sizeof (struct boxstring_st) + sizeof ("hello") + 1);
istrhello->tag = tag_string;
strcpy (istrhello->strval, "hello");
struct boxsequence_st *iseq3 =
malloc (sizeof (struct boxsequence_st) + 3 * sizeof (myval_t));
iseq3->tag = tag_sequence;
iseq3->slen = 3;
iseq3->valtab[0] = (myval_t)iv42;
iseq3->valtab[1] = (myval_t)istrhello;
iseq3->valtab[2] = (myval_t)NULL;
printf ("before %s:%d gdb print iseq3\n", __FILE__, __LINE__);
}
Вот мой файл Python для чтения под gdb
# file tiny-gdb.py in the public domain by Basile Starynkevitch
## see also tiny.c file
class my_val_Printer:
"""pretty prints a my_val"""
def __init__ (self, val):
self.val = val
def to_string (self):
outs = "[email protected]" + self.val['ptr']
mytag = self.val['ptag'].dereference();
if (mytag):
outs = outs + mytag.to_string()
def display_hint (self):
return 'my_val'
def my_val_lookup(val):
lookup = val.type.tag
if (lookup == None):
return None
if lookup == "my_val":
return my_val_Printer(val)
return None
Я придерживаюсь следующих основных вопросов.
- Как установить мой красивый принтер в python под GDB? (В документации я вижу несколько способов, и я не могу выбрать подходящую).
- Как обеспечить, чтобы GDB печатал как
union my_un
, так и синоним typedef-edmyval_t
таким же образом. - Как должен красивый принтер обнаруживать NULL-указатели?
- Как мой симпатичный принтер рекурсирует для
struct boxsequence_st
? Это означает, что указатель не равен нулю, а затем разыменовывает егоptag
, сравнивая этот тег сtag_sequence
, довольно печатая член гибкого массиваvaltab
. - Как избежать слишком глубокого перебора печатной печати?