#1872: t/pmc/fixedstringarray.t fails coretest 64 bit with g++-4.5
--------------------+-------------------------------------------------------
 Reporter:  mikehh  |       Owner:  bacek             
     Type:  bug     |      Status:  new               
 Priority:  normal  |   Milestone:  2.11              
Component:  core    |     Version:  master            
 Severity:  medium  |    Keywords:  Segmentation Fault
     Lang:          |       Patch:                    
 Platform:  linux   |  
--------------------+-------------------------------------------------------

Comment(by bacek):

 Hello.

 Fix for this bug (and #1871) is something like this:

 {{{
 diff --git a/include/parrot/pointer_array.h
 b/include/parrot/pointer_array.h
 index 7c0277f..35be87a 100644
 --- a/include/parrot/pointer_array.h
 +++ b/include/parrot/pointer_array.h
 @@ -20,7 +20,8 @@ Lower bit in cell masked to indicate pointer-to-free-
 cell.
  #define PARROT_POINTER_ARRAY_H_GUARD

  /* Calculate size of chunk data     "header"  */
 -#define CELL_PER_CHUNK ((4096 - 2 * sizeof(size_t) / sizeof (void *)))
 +#define CHUNK_SIZE 4096
 +#define CELL_PER_CHUNK ((CHUNK_SIZE - 2 * sizeof(size_t) / sizeof (void
 *)))

  typedef struct Parrot_Pointer_Array_Chunk {
      size_t   num_free;
 @@ -76,6 +77,15 @@ void * Parrot_pa_insert(PARROT_INTERP,
          __attribute__nonnull__(3);

  PARROT_EXPORT
 +int Parrot_pa_is_owned(PARROT_INTERP,
 +    ARGIN(Parrot_Pointer_Array *self),
 +    ARGIN(void *orig),
 +    ARGIN_NULLOK(void *ref))
 +        __attribute__nonnull__(1)
 +        __attribute__nonnull__(2)
 +        __attribute__nonnull__(3);
 +
 +PARROT_EXPORT
  PARROT_CANNOT_RETURN_NULL
  Parrot_Pointer_Array * Parrot_pa_new(PARROT_INTERP)
          __attribute__nonnull__(1);
 @@ -95,6 +105,10 @@ void Parrot_pa_remove(PARROT_INTERP,
         PARROT_ASSERT_ARG(interp) \
      , PARROT_ASSERT_ARG(self) \
      , PARROT_ASSERT_ARG(ptr))
 +#define ASSERT_ARGS_Parrot_pa_is_owned __attribute__unused__ int
 _ASSERT_ARGS_C
 +       PARROT_ASSERT_ARG(interp) \
 +    , PARROT_ASSERT_ARG(self) \
 +    , PARROT_ASSERT_ARG(orig))
  #define ASSERT_ARGS_Parrot_pa_new __attribute__unused__ int
 _ASSERT_ARGS_CHECK
         PARROT_ASSERT_ARG(interp))
  #define ASSERT_ARGS_Parrot_pa_remove __attribute__unused__ int
 _ASSERT_ARGS_CHE
 diff --git a/src/gc/gc_ms2.c b/src/gc/gc_ms2.c
 index 90d7952..b651ee7 100644
 --- a/src/gc/gc_ms2.c
 +++ b/src/gc/gc_ms2.c
 @@ -638,6 +638,7 @@ Parrot_gc_ms2_init(PARROT_INTERP)
          self->fixed_size_allocator =
 Parrot_gc_fixed_allocator_new(interp);

          self->gc_threshold = Parrot_sysmem_amount(interp) / 8;
 +        //self->gc_threshold = 1024 * 1024;
      }

      interp->gc_sys->gc_private = self;
 @@ -1242,7 +1243,11 @@ gc_ms2_is_ptr_owned(PARROT_INTERP,
 ARGIN_NULLOK(void *ptr
      if (PObj_is_live_or_free_TESTALL(obj))
          return 0;

 -    return 1;
 +    /* Pool.is_owned isn't precise enough (yet) */
 +    if (Parrot_pa_is_owned(interp, self->objects, item, item->ptr))
 +        return 1;
 +
 +    return 0;
  }


 diff --git a/src/pointer_array.c b/src/pointer_array.c
 index 811ec97..2f5096f 100644
 --- a/src/pointer_array.c
 +++ b/src/pointer_array.c
 @@ -147,6 +147,42 @@ Parrot_pa_remove(PARROT_INTERP,
 ARGIN(Parrot_Pointer_Array

  /*

 +=item C<int Parrot_pa_is_owned(PARROT_INTERP, Parrot_Pointer_Array *self,
 void
 +*orig, void *ref)>
 +
 +Check that C<orig> pointer is stored in C<ref> cell. Used during system
 stack t
 +
 +=cut
 +
 +*/
 +PARROT_EXPORT
 +int
 +Parrot_pa_is_owned(PARROT_INTERP, ARGIN(Parrot_Pointer_Array *self),
 +        ARGIN(void *orig), ARGIN_NULLOK(void *ref))
 +{
 +    ASSERT_ARGS(Parrot_pa_is_owned)
 +    size_t i;
 +
 diff --git a/include/parrot/pointer_array.h
 b/include/parrot/pointer_array.h
 index 7c0277f..35be87a 100644
 --- a/include/parrot/pointer_array.h
 +++ b/include/parrot/pointer_array.h
 @@ -20,7 +20,8 @@ Lower bit in cell masked to indicate pointer-to-free-
 cell.
  #define PARROT_POINTER_ARRAY_H_GUARD

  /* Calculate size of chunk data     "header"  */
 -#define CELL_PER_CHUNK ((4096 - 2 * sizeof(size_t) / sizeof (void *)))
 +#define CHUNK_SIZE 4096
 +#define CELL_PER_CHUNK ((CHUNK_SIZE - 2 * sizeof(size_t) / sizeof (void
 *)))

  typedef struct Parrot_Pointer_Array_Chunk {
      size_t   num_free;
 @@ -76,6 +77,15 @@ void * Parrot_pa_insert(PARROT_INTERP,
          __attribute__nonnull__(3);

  PARROT_EXPORT
 +int Parrot_pa_is_owned(PARROT_INTERP,
 +    ARGIN(Parrot_Pointer_Array *self),
 +    ARGIN(void *orig),
 +    ARGIN_NULLOK(void *ref))
 +        __attribute__nonnull__(1)
 ~/src/parrot (master)$ git diff > fix.patch
 ~/src/parrot (master)$ git diff
 diff --git a/include/parrot/pointer_array.h
 b/include/parrot/pointer_array.h
 index 7c0277f..35be87a 100644
 --- a/include/parrot/pointer_array.h
 +++ b/include/parrot/pointer_array.h
 @@ -20,7 +20,8 @@ Lower bit in cell masked to indicate pointer-to-free-
 cell.
  #define PARROT_POINTER_ARRAY_H_GUARD

  /* Calculate size of chunk data     "header"  */
 -#define CELL_PER_CHUNK ((4096 - 2 * sizeof(size_t) / sizeof (void *)))
 +#define CHUNK_SIZE 4096
 +#define CELL_PER_CHUNK ((CHUNK_SIZE - 2 * sizeof(size_t) / sizeof (void
 *)))

  typedef struct Parrot_Pointer_Array_Chunk {
      size_t   num_free;
 @@ -76,6 +77,15 @@ void * Parrot_pa_insert(PARROT_INTERP,
          __attribute__nonnull__(3);

  PARROT_EXPORT
 +int Parrot_pa_is_owned(PARROT_INTERP,
 +    ARGIN(Parrot_Pointer_Array *self),
 +    ARGIN(void *orig),
 +    ARGIN_NULLOK(void *ref))
 +        __attribute__nonnull__(1)
 +        __attribute__nonnull__(2)
 +        __attribute__nonnull__(3);
 +
 +PARROT_EXPORT
  PARROT_CANNOT_RETURN_NULL
  Parrot_Pointer_Array * Parrot_pa_new(PARROT_INTERP)
          __attribute__nonnull__(1);
 @@ -95,6 +105,10 @@ void Parrot_pa_remove(PARROT_INTERP,
         PARROT_ASSERT_ARG(interp) \
      , PARROT_ASSERT_ARG(self) \
      , PARROT_ASSERT_ARG(ptr))
 +#define ASSERT_ARGS_Parrot_pa_is_owned __attribute__unused__ int
 _ASSERT_ARGS_C
 +       PARROT_ASSERT_ARG(interp) \
 +    , PARROT_ASSERT_ARG(self) \
 +    , PARROT_ASSERT_ARG(orig))
  #define ASSERT_ARGS_Parrot_pa_new __attribute__unused__ int
 _ASSERT_ARGS_CHECK
         PARROT_ASSERT_ARG(interp))
  #define ASSERT_ARGS_Parrot_pa_remove __attribute__unused__ int
 _ASSERT_ARGS_CHE
 diff --git a/src/gc/gc_ms2.c b/src/gc/gc_ms2.c
 index 90d7952..b651ee7 100644
 --- a/src/gc/gc_ms2.c
 +++ b/src/gc/gc_ms2.c
 @@ -638,6 +638,7 @@ Parrot_gc_ms2_init(PARROT_INTERP)
          self->fixed_size_allocator =
 Parrot_gc_fixed_allocator_new(interp);

          self->gc_threshold = Parrot_sysmem_amount(interp) / 8;
 +        //self->gc_threshold = 1024 * 1024;
      }

      interp->gc_sys->gc_private = self;
 @@ -1242,7 +1243,11 @@ gc_ms2_is_ptr_owned(PARROT_INTERP,
 ARGIN_NULLOK(void *ptr
      if (PObj_is_live_or_free_TESTALL(obj))
          return 0;

 -    return 1;
 +    /* Pool.is_owned isn't precise enough (yet) */
 +    if (Parrot_pa_is_owned(interp, self->objects, item, item->ptr))
 +        return 1;
 +
 +    return 0;
  }


 diff --git a/src/pointer_array.c b/src/pointer_array.c
 index 811ec97..2f5096f 100644
 --- a/src/pointer_array.c
 +++ b/src/pointer_array.c
 @@ -147,6 +147,42 @@ Parrot_pa_remove(PARROT_INTERP,
 ARGIN(Parrot_Pointer_Array

  /*

 +=item C<int Parrot_pa_is_owned(PARROT_INTERP, Parrot_Pointer_Array *self,
 void
 +*orig, void *ref)>
 +
 +Check that C<orig> pointer is stored in C<ref> cell. Used during system
 stack t
 +
 +=cut
 +
 +*/
 +PARROT_EXPORT
 +int
 +Parrot_pa_is_owned(PARROT_INTERP, ARGIN(Parrot_Pointer_Array *self),
 +        ARGIN(void *orig), ARGIN_NULLOK(void *ref))
 +{
 +    ASSERT_ARGS(Parrot_pa_is_owned)
 +    size_t i;
 +
 +    /* Return early if ref is null */
 +    if (!ref)
 +        return 0;
 +
 +    /* We can't just deref pointer. It can be garbage */
 +    /* So, ensure that C<ref> is looks like real pointer */
 +    for (i = 0; i < self->total_chunks; i++) {
 +        Parrot_Pointer_Array_Chunk *chunk = self->chunks[i];
 +        if (PTR2UINTVAL(ref) < PTR2UINTVAL(chunk->data))
 +            continue;
 +        if (PTR2UINTVAL(ref) > PTR2UINTVAL(chunk) + CHUNK_SIZE)
 +            continue;
 +        return (*(void **)ref == orig);
 +    }
 +
 +    return 0;
 +}
 +
 +/*
 +
  =item C<static void allocate_more_chunks(PARROT_INTERP,
 Parrot_Pointer_Array
  *self)>


 }}}

 Unfortunatelly I will not have time to test and finish it till next week.
 If someone can finish patch it will be very helpful.

 --
 Bacek

-- 
Ticket URL: <https://trac.parrot.org/parrot/ticket/1872#comment:8>
Parrot <https://trac.parrot.org/parrot/>
Parrot Development
_______________________________________________
parrot-tickets mailing list
[email protected]
http://lists.parrot.org/mailman/listinfo/parrot-tickets

Reply via email to