Я пытаюсь отладить собственный код C для приложения Android, где я получаю следующее сообщение об ошибке:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1640]
0x8463022c in new_field_info (tree=0x7c1a98, hfinfo=0x865b6344, tvb=0xa65100, start=8, item_length=2) at proto.c:3491
3491 proto.c: No such file or directory.
in proto.c
(gdb) bt
#0 0x8463022c in new_field_info (tree=0x7c1a98, hfinfo=0x865b6344, tvb=0xa65100, start=8, item_length=2) at proto.c:3491
#1 0x846303dc in alloc_field_info (tree=0x7c1a98, hfindex=30607, tvb=0xa65100, start=8, length=0xbeb703b0) at proto.c:3519
#2 0x8462fcdc in proto_tree_add_pi (tree=0x7c1a98, hfindex=30607, tvb=0xa65100, start=8, length=0xbeb703b0, pfi=0xbeb70398) at proto.c:3328
Соответствующий код:
static field_info *
new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
const gint start, const gint item_length)
{
field_info *fi;
FIELD_INFO_NEW(fi);
if(fi == NULL)
throwDissectorException("proto.c", 3483, "fi==NULL");
fi->hfinfo = hfinfo; // THIS IS LINE 3491 <----- SEGFAULT
fi->start = start;
fi->start+=(tvb)?TVB_RAW_OFFSET(tvb):0;
fi->length = item_length;
fi->tree_type = -1;
fi->flags = 0;
...
return fi;
}
Я проверяю, что fi не равно NULL, как показано, и выдает исключение, которое перехватывается моим Java-приложением. Я никогда не вижу исключения (которое я проверял). Таким образом, fi гарантированно не равно NULL.
Если это так, то как может этот segfault?
РЕДАКТИРОВАТЬ: FIELD_INFO_NEW () на самом деле является макросом. Это код, принадлежащий Wireshark, который я пытаюсь отладить, поскольку он продолжает сбой моего приложения.
#define FIELD_INFO_NEW(fi) \
SLAB_ALLOC(fi, field_info)
/* we never free any memory we have allocated, when it is returned to us
we just store it in the free list until (hopefully) it gets used again
*/
#define SLAB_ALLOC(item, type) \
if(!type ## _free_list){ \
int i; \
union type ## slab_item *tmp; \
tmp=g_malloc(NITEMS_PER_SLAB*sizeof(*tmp)); \
for(i=0;i<NITEMS_PER_SLAB;i++){ \
tmp[i].next_free = type ## _free_list; \
type ## _free_list = &tmp[i]; \
} \
} \
item = &(type ## _free_list->slab_item); \
type ## _free_list = type ## _free_list->next_free;
Не думаю, что мне следует проверять, действительно ли fi-> hfinfo, верно? Потому что, я думаю, из этого кода SLAB_ALLOC выделит (или вытянет уже существующую память) правильный размер для fi. Потому что hfinfo - это указатель. Поэтому я просто пытаюсь дать этому указателю значение, и это назначение вызывает сбой:
/** Contains the field information for the proto_item. */
typedef struct field_info {
header_field_info *hfinfo; /**< pointer to registered field information */
gint start; /**< current start of data in field_info.ds_tvb */
gint length; /**< current data length of item in field_info.ds_tvb */
gint appendix_start; /**< start of appendix data */
gint appendix_length; /**< length of appendix data */
gint tree_type; /**< one of ETT_ or -1 */
item_label_t *rep; /**< string for GUI tree */
guint32 flags; /**< bitfield like FI_GENERATED, ... */
tvbuff_t *ds_tvb; /**< data source tvbuff */
fvalue_t value;
} field_info;