This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Possible Bug


On 03/27/2011 06:27 AM, Ian Lance Taylor wrote:
Nathan Boley<npboley@gmail.com> writes:

In a much larger application, I was getting a weird segfault that an
assignment to a temporary variable fixed. I distilled the example into
the attached "test_case.c". When I run test_case.c under valgrind I
get a memory read error, and it segfaults with electric fence, but I'm
not actually able to get a true segfault. However, I am pretty sure
that the same issue was causing the segfault in my application.

There is nothing wrong if gcc is reading an 8-byte value at an 8-byte aligned address.

Note the struct is packed, so alignof = 1.


That said, I could not recreate the problem with your test case.  I only
see 4-byte loads.

I see it with this modified testcase:


#include <stdio.h>
#include <stdlib.h>

/* GCC uses 4-byte + 2-byte loads and stack passing */
typedef struct __attribute__((__packed__))
{
   unsigned short chr;
   unsigned int loc;
} GENOME_LOC_TYPE_1;

/* GCC uses 8-byte loads and register passing even though sizeof = 6 */
typedef struct __attribute__((__packed__))
{
   unsigned chr            :16;
   unsigned loc            :32;
} GENOME_LOC_TYPE_2;

//#define GENOME_LOC_TYPE GENOME_LOC_TYPE_1
#define GENOME_LOC_TYPE GENOME_LOC_TYPE_2

static __attribute__((__noclone__,__noinline__))
int f(GENOME_LOC_TYPE x)
{
  return x.loc;
}

GENOME_LOC_TYPE h;
GENOME_LOC_TYPE *g = &h;

int
main()
{
  printf ("%d %d\n", sizeof (GENOME_LOC_TYPE),
                     __alignof__(GENOME_LOC_TYPE));
  return f(*g);
}


Both definitions have a (sizeof = 6, alignof = 1) but GCC loads the second with an 8-byte load. It's really an ugly bug if I understood it correctly, because I would have expected the second struct to have sizeof = 8. The two final bytes are not padding, they are what's left of the unsigned int from which the bitfields are carved. If that were the correct fix for the bug, it would be a change to the ABI.


Paolo


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]