https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103537
Bug ID: 103537
Summary: Using -fstack-protector-strong "without" optimization
cause segmentation fault
Product: gcc
Version: 11.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: hedayat.fwd at gmail dot com
Target Milestone: ---
When compiling https://github.com/hedayat/powerfake with GCC 11.2.1 with
default settings, which uses -fstack-protector-strong flag but no optimization
flags, if you run the sample executable it crashes with segmentation fault when
accessing a privation member function using its pointer (running with -g only
reveals that it is accessing another member function instead!).
However, running without -fstack-protector-strong, or running with
-fstack-protector-strong AND some optimizations flags (tested with -Og and -O3
flags), make the program to run without any problems. Even using
-fstack-protector works fine.
This is a sample GDB session (compiled with -g but without any optimization
flags):
Program received signal SIGSEGV, Segmentation fault.
0x000000000040a5b3 in
PowerFake::internal::TagBase<SamplePrivate>::Call<FakeTest::SampleClass2>
(obj=...) at /home/hedayat/Projects/powerfake/powerfake.h:257
257 return (obj.*GetAddress(Tag()))(args...);
Missing separate debuginfos, use: dnf debuginfo-install
glibc-2.34-8.fc35.x86_64 libgcc-11.2.1-1.fc35.x86_64
libstdc++-11.2.1-1.fc35.x86_64
(gdb) bt
#0 0x000000000040a5b3 in
PowerFake::internal::TagBase<SamplePrivate>::Call<FakeTest::SampleClass2>
(obj=...) at /home/hedayat/Projects/powerfake/powerfake.h:257
#1 0x00000000004030fa in FakeOverloaded () at
/home/hedayat/Projects/powerfake/sample/faked.cpp:196
#2 0x00000000004024df in main () at
/home/hedayat/Projects/powerfake/sample/faked.cpp:53
(gdb) print GetAddress(Tag())
$1 = {void
(FakeTest::SampleClass::*(OverloadedPrivateFloat))(FakeTest::SampleClass *
const, float)} 0x40a67e
<PowerFake::internal::GetAddress(OverloadedPrivateFloat)>
If the output is to be trusted, the GetAddress(Tag()) function is returning
wrong address. It is actually calling
PowerFake::internal::GetAddress(OverloadedPrivateFloat) while it should call
PowerFake::internal::GetAddress(SamplePrivate)
I'm not sure if the code is having any UB in it, and as it works fine except
with this specific combination of compiler options, I guessed it might be a
compiler bug.
Note that you can remove all other code in FakeOverloaded() function, and still
see the crash. So, surrounding code doesn't affect the problem.