This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default.


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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]