This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default.
- From: jose dot marchesi at oracle dot com (Jose E. Marchesi)
- To: Eric Botcazou <ebotcazou at adacore dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 29 Feb 2016 07:50:18 -0800
- Subject: Re: [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default.
- Authentication-results: sourceware.org; auth=none
- References: <1456435447-23676-1-git-send-email-jose dot marchesi at oracle dot com> <10333302 dot PFiANu1Ugm at polaris>
Hi Eric.
> In sparc systems glibc uses libgcc's unwinder to implement the
> backtrace(3) function, defaulting to a simple non-dwarf unwinder if
> libgcc_s doesn't provide a working _Unwind_Backtrace.
>
> However, libgcc's unwinder uses .eh_frame instead of .frame_debug, and
> .eh_frame is fully populated only if applications are built with
> -fexceptions or -fasynchronous-unwind-tables.
>
> This patch changes GCC to assume -fasynchronous-unwind-tables by default
> in sparcv9 and sparc64, like other ports (notably x86) do.
eric@polaris:~/svn/gcc/gcc/common/config> grep -r
x_flag_asynchronous_unwind_tables .
./tilegx/tilegx-common.c: opts->x_flag_asynchronous_unwind_tables = 1;
./tilepro/tilepro-common.c: opts->x_flag_asynchronous_unwind_tables = 1;
./i386/i386-common.c: opts->x_flag_asynchronous_unwind_tables = 2;
./s390/s390-common.c: opts->x_flag_asynchronous_unwind_tables = 1;
In particular, the 2 means that it's overridden by USE_IX86_FRAME_POINTER,
i.e. the frame pointer is always enabled instead (e.g on Solaris).
Ah, so I guess the right value to set in sparc-*-* is 1.
What's the problem exactly here? Simple non-DWARF unwinders usually work fine
with the SPARC architecture thanks to the calling conventions.
Consider the attached test program. When built with -g in sparc64-*-*
the resulting binary contains:
- A .eh_frame segment containing CFA information for __libc_csu_init and
__libc_csu_fini.
- A .debug_frame segment containing CFA information for func2, func1 and
main.
The backtrace(3) implementation for sparc contains a simple unwinder
that works well in most cases, but that unwinder is not used if
libgcc_s.so can be dlopened and it provides _Unwind_Backtrace. Now,
_Unwind_Backtrace uses .eh_frame but not .debug_frame. Thus,
backtrace(3) is only useful in programs built with
-fasynchronous-unwind-tables even if -g provides CFA info in
.debug_frame.
I see three solutions to this:
- To change glibc in order to not use libgcc's DWARF unwinder.
- To expand the libgcc unwinder to use the CFA in .frame_debug.
- To change GCC in sparc-*-* to generate fully populated .eh_frame
sections by default. (The patch I attempted.)
#include <stdio.h>
#include <execinfo.h>
int func2()
{
const int MAXFRAME = 10;
void *buffer[MAXFRAME];
int nframes = backtrace(buffer, MAXFRAME);
printf("backtrace returned %d frames\n", nframes);
return nframes;
}
void func1()
{
int num = func2();
printf("func2 returned %d\n", num);
return;
}
int main()
{
func1();
return 0;
}