开发者

what could cause a segfault in pointer assignment?

开发者 https://www.devze.com 2023-04-02 06:54 出处:网络
I am trying to debug native C code for an Android application, where I am getting the following segfault:

I am trying to debug native C code for an Android application, where I am getting the following segfault:

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

The relevant code is:

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;
}

I verify that fi is not NULL, as shown, throwing开发者_如何学运维 an Exception which is caught by my Java application. I never see an Exception thrown (which I have tested). So, fi is guaranteed to be non-NULL.

If that is the case, then how can this segfault?


EDIT: FIELD_INFO_NEW() is in fact a macro. This is code that belongs to Wireshark that I am trying to debug, since it keeps crashing my application.

#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;

I don't think I should be checking if fi->hfinfo is valid, right? Because, I think from this code SLAB_ALLOC will allocate (or pull in already existing memory) the proper size for fi. Because, hfinfo is a pointer. Therefore, I'm just trying to give that pointer a value, and that assignment is causing the crash:

/** 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; 


Null pointer is only a particular case of segfault.

segfault means you are trying to access to a portion (segment) of memory that is not allocated to your process.

So what exactly FIELD_INFO_NEW(fi) is doing ? Does it allocate memory via malloc for example ?

I got the impression that fi is not correctly initialized. So basically you are trying to assign data at a random address that happens to be forbidden.

(And you are lucky it throws a segfault, because if you were by chance writing to an allowed memory area it would be harder to find out the cause of memory corruption that could trigger strange side effect much later in your code execution.)


fi points to read-only memory. Check your FIELD_INFO_NEW macro.


Just because it's not null doesn't mean that you can safely access it or write to it. It could be pointing to freed memory, read-only memory or memory that just doesn't belong to you. Either of those could cause a segmentation fault.


Just because fi is not null does not mean that fi is valid. Apparently, your fi holds an invalid pointer value to that points to some completely bogus non-writable location in memory.

The crash has nothing to do with "pointer assignment" in this case. You can put the line that assigns fi->start first and it will most likely crash at that assignment instead.

Your problem is certainly in FIELD_INFO_NEW.

0

精彩评论

暂无评论...
验证码 换一张
取 消