我正在尝试为Android应用程序调试本机C代码,我得到以下段错误:
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的。
如果是这种情况,那么这个段错误怎么办?
编辑: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-&gt; 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;
答案 0 :(得分:2)
空指针只是segfault的一个特例。
segfault
表示您正在尝试访问未分配给您的流程的部分(段)内存。
那究竟FIELD_INFO_NEW(fi)到底在做什么?它是否通过malloc分配内存,例如?
我的印象是fi未正确初始化。所以基本上你试图在一个恰好被禁止的随机地址上分配数据。
(你很幸运它抛出一个段错误,因为如果你偶然写入允许的内存区域,那么很难找到内存损坏的原因,这可能会在代码执行后期引发奇怪的副作用。 )
答案 1 :(得分:0)
fi
指向只读内存。检查您的FIELD_INFO_NEW宏。
答案 2 :(得分:0)
仅仅因为它不是null并不意味着您可以安全地访问它或写入它。它可能指向释放的内存,只读内存或不属于您的内存。这些都可能导致分段错误。
答案 3 :(得分:0)
仅仅因为fi
不为空并不意味着fi
有效。显然,你的fi
持有一个无效的指针值,指向内存中一些完全虚假的不可写位置。
在这种情况下,崩溃与“指针分配”无关。您可以将首先分配fi->start
的行放在那里,而很可能会在该分配时崩溃。
您的问题肯定在FIELD_INFO_NEW
。