Bug 433543 - simple program compiled with gcc -O2 -pthread segfaults on exit
simple program compiled with gcc -O2 -pthread segfaults on exit
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: gcc (Show other bugs)
x86_64 Linux
low Severity medium
: rc
: ---
Assigned To: Jakub Jelinek
Depends On:
  Show dependency treegraph
Reported: 2008-02-19 17:04 EST by Joe Korty
Modified: 2013-11-26 13:31 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2013-11-26 13:31:34 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
short multithreaded C program (656 bytes, text/x-csrc)
2008-02-19 17:04 EST, Joe Korty
no flags Details

  None (edit)
Description Joe Korty 2008-02-19 17:04:50 EST
Description of problem:
The attached 32-line C program segfaults on exit when it is compiled
with -O2 -pthread.  It works fine if 1) -O1 is used, or 2) the return
is replaced with an exit(0), or 3) it is compiled on a RHEL 4 system with
-O2 -pthread, the binary moved over to a RHEL 5 system and executed there.

Version-Release number of selected component (if applicable):
gcc version 4.1.2 20070626 (Red Hat 4.1.2-14)

How reproducible:
Every time.

Steps to Reproduce:
1. Get an x86_64 smp box
2. Install 64 bit RHEL 5.1
3. yum update
4. compile with -O2 -pthread the given test program
5. run program.  It will segfault on return from main().
Actual results:
Segmentation fault

Expected results:

Additional info:
Comment 1 Joe Korty 2008-02-19 17:04:50 EST
Created attachment 295347 [details]
short multithreaded C program
Comment 2 Jeff Law 2013-11-26 13:31:34 EST
Your program is buggy.

The fundamental problem is th_ret is defined as an integer, which is 4 bytes. You take the address of th_ret, cast it to a void * and pass that to pthread_join.  pthread_join.  pthread_join expects a void** and will write a pointer sized value.

The size a pointer is larger than an integer, this results in pthread_join writing out of the memory space occupied by th_ret and stomps on the stack resulting in a segfault when the optimizer is enabled.  WIthout the optimizer, your code still stomps on the stack, but it does not clobber a critical memory location.

Pass a pointer to a correctly sized object to pthread_join and this will (of course) work fine.

Note You need to log in before you can comment on or make changes to this bug.