Bug 60758 - Infinite backtrace in __cxa_end_cleanup
Summary: Infinite backtrace in __cxa_end_cleanup
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 5.0
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2014-04-04 07:51 UTC by Alexey Merzlyakov
Modified: 2015-04-22 19:53 UTC (History)
2 users (show)

See Also:
Target: arm
Known to work:
Known to fail:
Last reconfirmed:

Testcase to reproduce (9.56 KB, text/plain)
2014-04-04 07:51 UTC, Alexey Merzlyakov
Proposed patch (321 bytes, patch)
2014-04-04 07:51 UTC, Alexey Merzlyakov
Details | Diff
Fix for thumb fail (471 bytes, patch)
2014-05-19 11:26 UTC, Alexey Merzlyakov
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alexey Merzlyakov 2014-04-04 07:51:01 UTC
Created attachment 32542 [details]
Testcase to reproduce

While debugging a compiled testcase, the infinite backtrace appears:
  Breakpoint 1, __gnu_end_cleanup () at ../../../../gcc-src/libstdc++-v3/libsupc++/eh_arm.cc:134
  134	../../../../gcc-src/libstdc++-v3/libsupc++/eh_arm.cc: No such file or directory.
  (gdb) bt
  #0  __gnu_end_cleanup () at ../../../../gcc-src/libstdc++-v3/libsupc++/eh_arm.cc:134
  #1  0xb6f45b2c in __cxa_end_cleanup () from /lib/libstdc++.so.6
  #2  0xb6f45b2c in __cxa_end_cleanup () from /lib/libstdc++.so.6
  #3  0xb6f45b2c in __cxa_end_cleanup () from /lib/libstdc++.so.6
  #4  0xb6f45b2c in __cxa_end_cleanup () from /lib/libstdc++.so.6

GCC configuration:
  $ arm-linux-gnueabi-gcc -v
  Using built-in specs.
  Target: arm-linux-gnueabi
  Configured with: ../gcc-src/configure --host=i686-pc-linux-gnu --target=arm-linux-gnueabi --prefix=/home/alexey.merzlyakov/arm --with-sysroot=/home/alexey.merzlyakov/arm/arm-linux-gnueabi/sys-root --disable-libmudflap --disable-libssp --with-mode=arm --with-fpu=vfpv3 --with-cpu=cortex-a15 --with-tune=cortex-a15 --with-float=softfp --disable-libatomic --disable-libgomp --enable-languages=c,c++ --with-gmp=/home/alexey.merzlyakov/arm --with-mpfr=/home/alexey.merzlyakov/arm --with-mpc=/home/alexey.merzlyakov/arm
  Thread model: posix
  gcc version 4.9.0 20140403 (experimental) (GCC)

Compiling the testcase:
  $ arm-linux-gnueabi-g++ rethrow_if_nested.ii -std=gnu++0x -g

The __cxa_end_cleanup() does not save/restore LR in function header/footer and does not provide any unwind info:
libstdc++-v3/libsupc++/eh_arm.cc ->
  "       push\t{r1, r2, r3, r4}\n"
  "       bl\t__gnu_end_cleanup\n"
  "       pop\t{r1, r2, r3, r4}\n"
  "       bl\t_Unwind_Resume @ Never returns\n"
GDB uses LR saving/restoring information when making a backtrace (when unwind info is not available). Otherwise if there are no information, the LR on current frame will be equal to LR on previous frame. It causes GDB to generate same backtrace-items for __cxa_end_cleanup again and again.

I would expect the same problem for other tools that unwind stacks (e.g. unwind code in libgcc, libbacktrace, etc.).

So, it seems to be a libstdc++ bug. Adding the LR in the arguments of save/restore instructions in __cxa_end_cleanup() code fixes it. Another option would be to add unwind entries (.cfi_whatever).
Comment 1 Alexey Merzlyakov 2014-04-04 07:51:51 UTC
Created attachment 32543 [details]
Proposed patch

Proposed patch is attached.
Comment 2 Ramana Radhakrishnan 2014-04-04 16:03:12 UTC
Please send patches to the mailing list after testing them appropriately and not attach them to bugzilla.
Comment 3 Alexey Merzlyakov 2014-04-07 06:20:47 UTC
Thank you very much!
Reg. test - no changes.
Comment 4 merzlyakovao 2014-05-16 13:17:05 UTC
Author: merzlyakovao
Date: Fri May 16 13:16:33 2014
New Revision: 210515

URL: http://gcc.gnu.org/viewcvs?rev=210515&root=gcc&view=rev
2014-05-16  Alexey Merzlyakov  <alexey.merzlyakov@samsung.com>

	PR libstdc++/60758
	* libsupc++/eh_arm.cc (__cxa_end_cleanup): Change r4 to lr in save/restore
	and add unwind directives.

Comment 5 Sandra Loosemore 2014-05-18 03:25:43 UTC
The patch committed as r210215 is broken for -mthumb on arm-none-eabi:

libtool: compile:  /scratch/sandra/arm-fsf/obj/gcc-mainline-0-arm-none-eabi-i686-pc-linux-gnu/./gcc/xgcc -shared-libgcc -B/scratch/sandra/arm-fsf/obj/gcc-mainline-0-arm-none-eabi-i686-pc-linux-gnu/./gcc -nostdinc++ -L/scratch/sandra/arm-fsf/obj/gcc-mainline-0-arm-none-eabi-i686-pc-linux-gnu/arm-none-eabi/thumb/libstdc++-v3/src -L/scratch/sandra/arm-fsf/obj/gcc-mainline-0-arm-none-eabi-i686-pc-linux-gnu/arm-none-eabi/thumb/libstdc++-v3/src/.libs -L/scratch/sandra/arm-fsf/obj/gcc-mainline-0-arm-none-eabi-i686-pc-linux-gnu/arm-none-eabi/thumb/libstdc++-v3/libsupc++/.libs -B/scratch/sandra/arm-fsf/install/arm-none-eabi/bin/ -B/scratch/sandra/arm-fsf/install/arm-none-eabi/lib/ -isystem /scratch/sandra/arm-fsf/install/arm-none-eabi/include -isystem /scratch/sandra/arm-fsf/install/arm-none-eabi/sys-include -mthumb -I/scratch/sandra/arm-fsf/src/gcc-mainline/libstdc++-v3/../libgcc -I/scratch/sandra/arm-fsf/obj/gcc-mainline-0-arm-none-eabi-i686-pc-linux-gnu/arm-none-eabi/thumb/libstdc++-v3/include/arm-none-eabi -I/scratch/sandra/arm-fsf/obj/gcc-mainline-0-arm-none-eabi-i686-pc-linux-gnu/arm-none-eabi/thumb/libstdc++-v3/include -I/scratch/sandra/arm-fsf/src/gcc-mainline/libstdc++-v3/libsupc++ -fno-implicit-templates -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi -fdiagnostics-show-location=once -ffunction-sections -fdata-sections -frandom-seed=eh_arm.lo -g -O2 -mthumb -c /scratch/sandra/arm-fsf/src/gcc-mainline/libstdc++-v3/libsupc++/eh_arm.cc -o eh_arm.o
/tmp/cchJLQxH.s: Assembler messages:
/tmp/cchJLQxH.s:26: Error: invalid register list to push/pop instruction -- `pop {r1,r2,r3,lr}'

It looks to me like lr is valid in the reglist for PUSH but not POP on Thumb.

Since this breaks builds, please either fix ASAP or revert the broken patch.
Comment 6 Alexey Merzlyakov 2014-05-19 07:40:14 UTC
The issue was reproduced at my side.
Let me make necessary investigations to fix the problem as soon as possible.
Comment 7 Alexey Merzlyakov 2014-05-19 11:19:25 UTC
The problem does not appear for thumb2 targets.
On older architectures (armv6 and below) in thumb-mode the LR indeed can not be used as argument of POP instruction.

To support __cxa_end_cleanup backtracing on thumb1, we can make additional register operations before push/pop.
But I guess, this will have a negative effect on __cxa_end_cleanup performance.
So, I propose to preserve __cxa_end_cleanup backtracing on thumb2 architectures and revert it on thumb1.
Comment 8 Alexey Merzlyakov 2014-05-19 11:26:08 UTC
Created attachment 32820 [details]
Fix for thumb fail

Proposed bugfix (build OK, but not regtested).
Comment 9 Alexey Merzlyakov 2014-05-20 06:27:47 UTC
The following PR has been opened for Thumb1 problem:
Comment 10 Yury Gribov 2014-05-20 17:25:58 UTC
Author: ygribov
Date: Tue May 20 17:25:26 2014
New Revision: 210650

URL: http://gcc.gnu.org/viewcvs?rev=210650&root=gcc&view=rev
2014-05-20  Alexey Merzlyakov  <alexey.merzlyakov@samsung.com>

	PR libstdc++/61223
	2014-05-16  Alexey Merzlyakov  <alexey.merzlyakov@samsung.com>

	PR libstdc++/60758
	* libsupc++/eh_arm.cc (__cxa_end_cleanup): Change r4 to lr in save/restore
	and add unwind directives.

Comment 11 Ramana Radhakrishnan 2015-04-22 19:53:18 UTC
fixed on 5.0