Bug 433543 - simple program compiled with gcc -O2 -pthread segfaults on exit
Summary: simple program compiled with gcc -O2 -pthread segfaults on exit
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: gcc
Version: 5.1
Hardware: x86_64
OS: Linux
low
medium
Target Milestone: rc
: ---
Assignee: Jakub Jelinek
QA Contact: BaseOS QE
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2008-02-19 22:04 UTC by Joe Korty
Modified: 2013-11-26 18:31 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2013-11-26 18:31:34 UTC
Target Upstream Version:
Embargoed:


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

Description Joe Korty 2008-02-19 22:04:50 UTC
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)
glibc-2.5-18

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:
Exiting...
Segmentation fault


Expected results:
Exiting...


Additional info:

Comment 1 Joe Korty 2008-02-19 22:04:50 UTC
Created attachment 295347 [details]
short multithreaded C program

Comment 2 Jeff Law 2013-11-26 18:31:34 UTC
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.