c - 什么会导致指针分配出现段错误?

标签 c debugging segmentation-fault

我正在尝试调试 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/

相关文章:

c - 将数据存储到多维数组中

debugging - 为什么 64 位 gdb 在 ARM 32 代码中永远不会到达断点?

javascript - NetBeans 调试突然停止工作

c - 从文件创建 1 和 0 的矩阵 NxN 的 C 程序中的段错误

segmentation-fault - Gfortran : Segmentation fault with long character

c - 计算三叉树中具有给定键的所有节点的时间复杂度?

c - 尝试通过 apache 模块强制保持事件状态

c - 将C二进制搜索树保存到txt文件

java - 如何处理java中的bug "dead store to local variable"?

c - 使用类函数宏检查变量是否已定义