Bug 65209 - [5 Regression] Broken code with global static variables, invalid pointer when freeing global variables
Summary: [5 Regression] Broken code with global static variables, invalid pointer when...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.0
: P1 normal
Target Milestone: 5.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-02-25 15:03 UTC by Sandro Mani
Modified: 2015-03-04 18:14 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.9.2
Known to fail:
Last reconfirmed: 2015-02-25 00:00:00


Attachments
testcase (845 bytes, application/gzipped-tar)
2015-02-25 15:03 UTC, Sandro Mani
Details
Slightly reduced test case (744 bytes, application/gzipped-tar)
2015-02-25 16:09 UTC, Sandro Mani
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Sandro Mani 2015-02-25 15:03:02 UTC
Created attachment 34870 [details]
testcase

Using gcc-5.0.0-0.15.fc23.x86_64

Test case attached. Build with

$ g++ -g -Wall -o main foo.cpp main.cpp

The test case crashes when freeing global variables:

./main
*** Error in `/home/sandro/Desktop/a/main': free(): invalid pointer: 0x0000000000610001 ***


#0  0x00007ffff71a6ae8 in raise () from /lib64/libc.so.6
#1  0x00007ffff71a877a in abort () from /lib64/libc.so.6
#2  0x00007ffff71eb092 in __libc_message () from /lib64/libc.so.6
#3  0x00007ffff71f2994 in _int_free () from /lib64/libc.so.6
#4  0x00007ffff71f748c in free () from /lib64/libc.so.6
#5  0x000000000040099b in FooData::~FooData (this=0x602118 <_ZGVZN12_GLOBAL__N_112Q_QGS_s_self13innerFunctionEvE6holder>, __in_chrg=<optimized out>)
    at foo.cpp:5
#6  0x00000000004009da in Foo::~Foo (this=0x602100 <_ZZN12_GLOBAL__N_112Q_QGS_s_self13innerFunctionEvE6holder>, __in_chrg=<optimized out>) at foo.cpp:8
#7  0x0000000000400a12 in FooSingleton::~FooSingleton (this=0x602100 <_ZZN12_GLOBAL__N_112Q_QGS_s_self13innerFunctionEvE6holder>, 
    __in_chrg=<optimized out>) at foo.cpp:15
#8  0x0000000000400a69 in (anonymous namespace)::Q_QGS_s_self::innerFunction()::Holder::~Holder() (
    this=0x602100 <_ZZN12_GLOBAL__N_112Q_QGS_s_self13innerFunctionEvE6holder>, __in_chrg=<optimized out>) at foo.cpp:33
#9  0x00007ffff71ab628 in __run_exit_handlers () from /lib64/libc.so.6
#10 0x00007ffff71ab675 in exit () from /lib64/libc.so.6
#11 0x00007ffff7191847 in __libc_start_main () from /lib64/libc.so.6
#12 0x00000000004007e9 in _start ()


Observations:
- Depends on the Q_QGS_s_self namespace being called such (more precisely, exactly such, not even any other name with equal length)
- Depends on the innerFunction method being called such
- Depends on innerFunction being inline
- Depends on the size of the global variables
Comment 1 Richard Biener 2015-02-25 15:08:55 UTC
Confirmed.  Valgrind says

==23580== Invalid free() / delete / delete[] / realloc()
==23580==    at 0x4C28FAC: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23580==    by 0x4009D4: FooData::~FooData() (foo.cpp:5)
==23580==    by 0x400A13: Foo::~Foo() (foo.cpp:8)
==23580==    by 0x400A4B: FooSingleton::~FooSingleton() (foo.cpp:15)
==23580==    by 0x400AA2: (anonymous namespace)::Q_QGS_s_self::innerFunction()::Holder::~Holder() (foo.cpp:33)
==23580==    by 0x5704058: __run_exit_handlers (exit.c:82)
==23580==    by 0x57040A4: exit (exit.c:104)
==23580==    by 0x56EDBEB: (below main) (libc-start.c:303)
==23580==  Address 0x5a80001 is 24,513 bytes inside a block of size 72,704 alloc'd
==23580==    at 0x4C277AB: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23580==    by 0x4EC31AF: ??? (in /usr/lib64/libstdc++.so.6.0.21)
==23580==    by 0x400E859: call_init.part.0 (dl-init.c:84)
==23580==    by 0x400E942: _dl_init (dl-init.c:36)
==23580==    by 0x40011C9: ??? (in /lib64/ld-2.18.so)
Comment 2 Sandro Mani 2015-02-25 16:09:25 UTC
Created attachment 34874 [details]
Slightly reduced test case

==30483== Invalid free() / delete / delete[] / realloc()
==30483==    at 0x4C2D143: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==30483==    by 0x400983: Foo::~Foo() (foo.cpp:4)
==30483==    by 0x40099F: (anonymous namespace)::Q_QGS_s_self::innerFunction()::Holder::~Holder() (foo.cpp:21)
==30483==    by 0x570F627: __run_exit_handlers (in /usr/lib64/libc-2.21.90.so)
==30483==    by 0x570F674: exit (in /usr/lib64/libc-2.21.90.so)
==30483==    by 0x56F5846: (below main) (in /usr/lib64/libc-2.21.90.so)
==30483==  Address 0x1 is not stack'd, malloc'd or (recently) free'd
Comment 3 Jakub Jelinek 2015-02-25 17:08:01 UTC
Started with r213307
Comment 4 Jakub Jelinek 2015-02-25 17:13:48 UTC
Exported symbols like
_ZZN12_GLOBAL__N_112Q_QGS_s_self13innerFunctionEvEN6HolderC1Ev
look very much wrong to me, anonymous namespace shouldn't be visible to other TUs.  Similarly, sections containing such symbols shouldn't be linkonce.
Comment 5 Jason Merrill 2015-02-25 21:47:00 UTC
Author: jason
Date: Wed Feb 25 21:46:29 2015
New Revision: 220991

URL: https://gcc.gnu.org/viewcvs?rev=220991&root=gcc&view=rev
Log:
	PR c++/65209
	* decl2.c (constrain_visibility) [VISIBILITY_ANON]: Clear
	DECL_COMDAT.
	(constrain_visibility_for_template): Handle reference arguments.

Added:
    trunk/gcc/testsuite/g++.dg/abi/anon4.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl2.c
Comment 6 Jakub Jelinek 2015-02-25 23:05:15 UTC
Fixed.
Comment 7 Jason Merrill 2015-03-04 18:14:16 UTC
Author: jason
Date: Wed Mar  4 18:13:44 2015
New Revision: 221192

URL: https://gcc.gnu.org/viewcvs?rev=221192&root=gcc&view=rev
Log:
	PR c++/65209
	PR c++/65309
	* decl2.c (constrain_visibility_for_template): Handle reference
	arguments.

Added:
    branches/gcc-4_9-branch/gcc/testsuite/g++.dg/abi/anon4.C
Modified:
    branches/gcc-4_9-branch/gcc/cp/ChangeLog
    branches/gcc-4_9-branch/gcc/cp/decl2.c