public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Questions before submitting a bug report
@ 2012-01-03 15:02 Markus Henschel
  2012-01-03 15:06 ` Andrew Haley
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Markus Henschel @ 2012-01-03 15:02 UTC (permalink / raw)
  To: gcc-help

Hello,

I think I found a bug in gcc but before I submit it I'd like to have someone look at least briefly on the code to make sure I did not make some silly mistake.

*********************************************schnipp***************
struct Foo
{
	long long _foobar;
};

struct Foo * foo_instance()
{
	static struct Foo foo;
	return &foo;
}

void bar(struct Foo * foo)
{
	__sync_add_and_fetch(&foo->_foobar, 1LL);
}


int main(int argc, char * argv[])
{
	struct Foo * foo=foo_instance();
	foo->_foobar=argc;
	bar(foo);
	return (int)foo->_foobar;
}
*********************************************schnapp***************

Is there some obvious flaw in my code? 

My second question is if it makes any sense to submit this bug if it's against gcc version 4.2.4. I still have to use this compiler version but the bug seems to have vanished in version 4.3.3. Is 4.2.4 still maintained?

Thanks for your time.

Markus

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Questions before submitting a bug report
  2012-01-03 15:02 Questions before submitting a bug report Markus Henschel
@ 2012-01-03 15:06 ` Andrew Haley
  2012-01-03 15:23   ` Markus Henschel
  2012-01-03 15:26 ` Andrew Haley
  2012-01-03 16:55 ` Jonathan Wakely
  2 siblings, 1 reply; 10+ messages in thread
From: Andrew Haley @ 2012-01-03 15:06 UTC (permalink / raw)
  To: gcc-help

On 01/03/2012 03:02 PM, Markus Henschel wrote:
> struct Foo * foo_instance()
> {
> 	static struct Foo foo;
> 	return &foo;
> }

Uh, no.  You can't return a reference to a local
variable.

Andrew.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: Questions before submitting a bug report
  2012-01-03 15:06 ` Andrew Haley
@ 2012-01-03 15:23   ` Markus Henschel
  2012-01-03 15:25     ` Andrew Haley
  0 siblings, 1 reply; 10+ messages in thread
From: Markus Henschel @ 2012-01-03 15:23 UTC (permalink / raw)
  To: Andrew Haley, gcc-help



> -----Original Message-----
> From: gcc-help-owner@gcc.gnu.org [mailto:gcc-help-owner@gcc.gnu.org] On
> Behalf Of Andrew Haley
> Sent: Dienstag, 3. Januar 2012 16:06
> To: gcc-help@gcc.gnu.org
> Subject: Re: Questions before submitting a bug report
> 
> On 01/03/2012 03:02 PM, Markus Henschel wrote:
> > struct Foo * foo_instance()
> > {
> > 	static struct Foo foo;
> > 	return &foo;
> > }
> 
> Uh, no.  You can't return a reference to a local variable.
> 
> Andrew.

But it's a static variable. Its lifetime extends across the runtime of the whole program. I'm not 100% sure for C but at least in C++ this is a well known pattern for singletons.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Questions before submitting a bug report
  2012-01-03 15:23   ` Markus Henschel
@ 2012-01-03 15:25     ` Andrew Haley
  0 siblings, 0 replies; 10+ messages in thread
From: Andrew Haley @ 2012-01-03 15:25 UTC (permalink / raw)
  To: gcc-help

On 01/03/2012 03:23 PM, Markus Henschel wrote:
> 
> 
>> -----Original Message-----
>> From: gcc-help-owner@gcc.gnu.org [mailto:gcc-help-owner@gcc.gnu.org] On
>> Behalf Of Andrew Haley
>> Sent: Dienstag, 3. Januar 2012 16:06
>> To: gcc-help@gcc.gnu.org
>> Subject: Re: Questions before submitting a bug report
>>
>> On 01/03/2012 03:02 PM, Markus Henschel wrote:
>>> struct Foo * foo_instance()
>>> {
>>> 	static struct Foo foo;
>>> 	return &foo;
>>> }
>>
>> Uh, no.  You can't return a reference to a local variable.
> 
> But it's a static variable.

My apologies.  I posted too soon.

Andrew.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Questions before submitting a bug report
  2012-01-03 15:02 Questions before submitting a bug report Markus Henschel
  2012-01-03 15:06 ` Andrew Haley
@ 2012-01-03 15:26 ` Andrew Haley
  2012-01-03 15:39   ` Markus Henschel
  2012-01-03 16:55 ` Jonathan Wakely
  2 siblings, 1 reply; 10+ messages in thread
From: Andrew Haley @ 2012-01-03 15:26 UTC (permalink / raw)
  To: gcc-help

On 01/03/2012 03:02 PM, Markus Henschel wrote:
> Is there some obvious flaw in my code? 

What error did you get?  Not all CPUs can do
__sync_add_and_fetch on a long long.

Andrew.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: Questions before submitting a bug report
  2012-01-03 15:26 ` Andrew Haley
@ 2012-01-03 15:39   ` Markus Henschel
  2012-01-03 15:52     ` Andrew Haley
  0 siblings, 1 reply; 10+ messages in thread
From: Markus Henschel @ 2012-01-03 15:39 UTC (permalink / raw)
  To: gcc-help

> -----Original Message-----
> From: gcc-help-owner@gcc.gnu.org [mailto:gcc-help-owner@gcc.gnu.org] On
> Behalf Of Andrew Haley
> Sent: Dienstag, 3. Januar 2012 16:26
> To: gcc-help@gcc.gnu.org
> Subject: Re: Questions before submitting a bug report
> 
> On 01/03/2012 03:02 PM, Markus Henschel wrote:
> > Is there some obvious flaw in my code?
> 
> What error did you get?  Not all CPUs can do __sync_add_and_fetch on a
> long long.

The resulting program crashes with a segmentation fault on the line with __sync_add_and_fetch. This is the complete command line I used for compiling:

"gcc -fPIC -march=i586 -fvisibility=hidden -O3 mytest.c -o mytest"

The error goes away if I remove "-fPIC", "-fvisibility=hidden" or if I use some less aggressive optimization. It also disappears if I use a long instead of a long long. 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Questions before submitting a bug report
  2012-01-03 15:39   ` Markus Henschel
@ 2012-01-03 15:52     ` Andrew Haley
  2012-01-04 10:08       ` Markus Henschel
  0 siblings, 1 reply; 10+ messages in thread
From: Andrew Haley @ 2012-01-03 15:52 UTC (permalink / raw)
  To: gcc-help

On 01/03/2012 03:39 PM, Markus Henschel wrote:
>> -----Original Message-----
>> From: gcc-help-owner@gcc.gnu.org [mailto:gcc-help-owner@gcc.gnu.org] On
>> Behalf Of Andrew Haley
>> Sent: Dienstag, 3. Januar 2012 16:26
>> To: gcc-help@gcc.gnu.org
>> Subject: Re: Questions before submitting a bug report
>>
>> On 01/03/2012 03:02 PM, Markus Henschel wrote:
>>> Is there some obvious flaw in my code?
>>
>> What error did you get?  Not all CPUs can do __sync_add_and_fetch on a
>> long long.
> 
> The resulting program crashes with a segmentation fault on the line with __sync_add_and_fetch. This is the complete command line I used for compiling:
> 
> "gcc -fPIC -march=i586 -fvisibility=hidden -O3 mytest.c -o mytest"
> 
> The error goes away if I remove "-fPIC", "-fvisibility=hidden" or if I use some less aggressive optimization. It also disappears if I use a long instead of a long long. 

I think you've found yourself a bug.  I can't reproduce it, nor can
I see anything wrong with your code.  It's be interesting to see what
instruction makes it crash.

Andrew.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Questions before submitting a bug report
  2012-01-03 15:02 Questions before submitting a bug report Markus Henschel
  2012-01-03 15:06 ` Andrew Haley
  2012-01-03 15:26 ` Andrew Haley
@ 2012-01-03 16:55 ` Jonathan Wakely
  2 siblings, 0 replies; 10+ messages in thread
From: Jonathan Wakely @ 2012-01-03 16:55 UTC (permalink / raw)
  To: Markus Henschel; +Cc: gcc-help

On 3 January 2012 15:02, Markus Henschel wrote:
> My second question is if it makes any sense to submit this bug if it's against gcc version 4.2.4. I still have to use this compiler version but the bug seems to have vanished in version 4.3.3. Is 4.2.4 still maintained?

No, as shown on the gcc.gnu.org home page, the oldest maintained
release series is GCC 4.4

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: Questions before submitting a bug report
  2012-01-03 15:52     ` Andrew Haley
@ 2012-01-04 10:08       ` Markus Henschel
  2012-01-05 23:00         ` Kalle Olavi Niemitalo
  0 siblings, 1 reply; 10+ messages in thread
From: Markus Henschel @ 2012-01-04 10:08 UTC (permalink / raw)
  To: Andrew Haley, gcc-help

> -----Original Message-----
> From: gcc-help-owner@gcc.gnu.org [mailto:gcc-help-owner@gcc.gnu.org] On
> Behalf Of Andrew Haley
> Sent: Dienstag, 3. Januar 2012 16:52
> To: gcc-help@gcc.gnu.org
> Subject: Re: Questions before submitting a bug report
> 
> On 01/03/2012 03:39 PM, Markus Henschel wrote:
> >> -----Original Message-----
> >> From: gcc-help-owner@gcc.gnu.org [mailto:gcc-help-owner@gcc.gnu.org]
> >> On Behalf Of Andrew Haley
> >> Sent: Dienstag, 3. Januar 2012 16:26
> >> To: gcc-help@gcc.gnu.org
> >> Subject: Re: Questions before submitting a bug report
> >>
> >> On 01/03/2012 03:02 PM, Markus Henschel wrote:
> >>> Is there some obvious flaw in my code?
> >>
> >> What error did you get?  Not all CPUs can do __sync_add_and_fetch on
> >> a long long.
> >
> > The resulting program crashes with a segmentation fault on the line
> with __sync_add_and_fetch. This is the complete command line I used for
> compiling:
> >
> > "gcc -fPIC -march=i586 -fvisibility=hidden -O3 mytest.c -o mytest"
> >
> > The error goes away if I remove "-fPIC", "-fvisibility=hidden" or if
> I use some less aggressive optimization. It also disappears if I use a
> long instead of a long long.
> 
> I think you've found yourself a bug.  I can't reproduce it, nor can I
> see anything wrong with your code.  It's be interesting to see what
> instruction makes it crash.
> 
> Andrew.

Thanks for having a look at this. To satisfy your curiosity here is the asm output of gdb for an even simpler test case:
int main(int argc, char * argv[])
{
	static long long foo;
	return __sync_add_and_fetch(&foo, foo);
}

I don't know if this is meaningful because I don't know much about assembler.

   ┌───────────────────────────────────────────────────────────────────────────┐
   │0x8048350 <main>        lea    0x4(%esp),%ecx                              │
   │0x8048354 <main+4>      and    $0xfffffff0,%esp                            │
   │0x8048357 <main+7>      pushl  -0x4(%ecx)                                  │
   │0x804835a <main+10>     push   %ebp                                        │
   │0x804835b <main+11>     mov    %esp,%ebp                                   │
   │0x804835d <main+13>     push   %edi                                        │
   │0x804835e <main+14>     push   %esi                                        │
   │0x804835f <main+15>     push   %ebx                                        │
   │0x8048360 <main+16>     push   %ecx                                        │
   │0x8048361 <main+17>     call   0x8048366 <main+22>                         │
   │0x8048366 <main+22>     pop    %ebx                                        │
   │0x8048367 <main+23>     add    $0x1206,%ebx                                │
   │0x804836d <main+29>     sub    $0x8,%esp                                   │
   │0x8048370 <main+32>     mov    0x2c(%ebx),%eax                             │
   │0x8048376 <main+38>     mov    0x30(%ebx),%edx                             │
   │0x804837c <main+44>     mov    %eax,%esi                                   │
   │0x804837e <main+46>     mov    %edx,%edi                                   │
   │0x8048380 <main+48>     add    0x2c(%ebx),%esi                             │
   │0x8048386 <main+54>     adc    0x30(%ebx),%edi                             │
   │0x804838c <main+60>     mov    %esi,-0x18(%ebp)                            │
   │0x804838f <main+63>     mov    %edi,-0x14(%ebp)                            │
   │0x8048392 <main+66>     mov    %esi,%edi                                   │
   │0x8048394 <main+68>     mov    -0x14(%ebp),%ecx                            │
   │0x8048397 <main+71>     xchg   %ebx,%edi                                   │
  >│0x8048399 <main+73>     lock cmpxchg8b 0x2c(%ebx)                          │
   │0x80483a1 <main+81>     xchg   %ebx,%edi                                   │
   │0x80483a3 <main+83>     jne    0x804837c <main+44>                         │
   │0x80483a5 <main+85>     mov    -0x18(%ebp),%eax                            │
   │0x80483a8 <main+88>     pop    %edx                                        │
   └───────────────────────────────────────────────────────────────────────────┘
child process 15488 In: main                           Line: ??   PC: 0x8048399 
(gdb) run
Starting program: /home/ubuntu/mytest 

Program received signal SIGSEGV, Segmentation fault.
0x08048399 in main ()

If gcc 4.2 isn't maintained anymore I'll use a workaround and see that we can switch to a newer gcc release in the future. 

Thank you for your time.

Markus




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Questions before submitting a bug report
  2012-01-04 10:08       ` Markus Henschel
@ 2012-01-05 23:00         ` Kalle Olavi Niemitalo
  0 siblings, 0 replies; 10+ messages in thread
From: Kalle Olavi Niemitalo @ 2012-01-05 23:00 UTC (permalink / raw)
  To: Markus Henschel; +Cc: gcc-help

Markus Henschel <markus.henschel@yager.de> writes:

>    │0x8048397 <main+71>     xchg   %ebx,%edi                                   │
>   >│0x8048399 <main+73>     lock cmpxchg8b 0x2c(%ebx)                          │
>    │0x80483a1 <main+81>     xchg   %ebx,%edi                                   │

It looks like GCC 4.2.4 has used the wrong register in the
cmpxchg8b instruction.  The earlier part of this function uses
EBX to point to the Global Offset Table.  Because the cmpxchg8b
instruction requires that the ECX:EBX register pair contains the
64-bit value to be stored in memory, GCC has temporarily moved
the address of the GOT from EBX to EDI; so it should have used
0x2c(%edi) in the cmpxchg8b instruction.  The generated code
crashes because it tries to use the low 32 bits of the data value
as the address of the GOT.

A similar bug has already been reported:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37651
"__sync_bool_compare_and_swap creates wrong code with -fPIC"
It too is about using %ebx as a pointer in cmpxchg8b.
I can reproduce that bug with 4.2.4 but not with 4.4.6 or 4.6.2;
so I guess the report could be closed now.

Omitting -fPIC avoids the bug because accessing the foo variable
then does not need the GOT and the cmpxchg8b instruction uses a
literal address that does not involve any register.

With your original source, omitting -fvisibility=hidden avoids
the bug because it prevents foo_instance and bar from being
inlined and the out-of-line code generated for bar accesses
foo->_foobar via the pointer parameter, rather than via the GOT.
With the simplified source, -fvisibility=hidden does not matter
for the bug.

For a workaround, I suggest

int main(int argc, char * argv[])
{
	static long long foo;
	long long *volatile fooptr = &foo;
	return __sync_add_and_fetch(fooptr, foo);
}

as this seems to force GCC 4.2.4 to compute the address first,
rather than try to access the variable via the GOT as part of the
cmpxchg8b instruction.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-01-05 23:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-03 15:02 Questions before submitting a bug report Markus Henschel
2012-01-03 15:06 ` Andrew Haley
2012-01-03 15:23   ` Markus Henschel
2012-01-03 15:25     ` Andrew Haley
2012-01-03 15:26 ` Andrew Haley
2012-01-03 15:39   ` Markus Henschel
2012-01-03 15:52     ` Andrew Haley
2012-01-04 10:08       ` Markus Henschel
2012-01-05 23:00         ` Kalle Olavi Niemitalo
2012-01-03 16:55 ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).