我正在尝试调试 Android 应用程序的 native 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->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;
最佳答案
空指针只是段错误的一个特例。
segfault
表示您正在尝试访问未分配给您的进程的内存部分(段)。
那么 FIELD_INFO_NEW(fi) 到底在做什么?例如,它是否通过 malloc 分配内存?
我的印象是 fi 没有正确初始化。所以基本上你是在尝试在一个恰好被禁止的随机地址分配数据。
(幸运的是它会引发段错误,因为如果您偶然写入允许的内存区域,则很难找出内存损坏的原因,而内存损坏可能会在代码执行的后期引发奇怪的副作用。 )
关于c - 什么会导致指针分配出现段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7288262/