public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default.
@ 2016-02-25 21:16 Jose E. Marchesi
  2016-02-28 18:35 ` Eric Botcazou
  0 siblings, 1 reply; 7+ messages in thread
From: Jose E. Marchesi @ 2016-02-25 21:16 UTC (permalink / raw)
  To: gcc-patches

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.

Tested in both sparcv9-*-* and sparc64-*-* targets.

       * common/config/sparc/sparc-common.c (sparc_option_init_struct):
         New function.
         (TARGET_OPTION_INIT_STRUCT): Defined.
---
 gcc/ChangeLog                          |  6 ++++++
 gcc/common/config/sparc/sparc-common.c | 10 ++++++++++
 2 files changed, 16 insertions(+)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3a13f5f..ba7befe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-02-25  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* common/config/sparc/sparc-common.c (sparc_option_init_struct):
+	New function.
+	(TARGET_OPTION_INIT_STRUCT): Defined.
+
 2016-02-25  Richard Biener  <rguenther@suse.de>
 
 	PR tree-optimization/48795
diff --git a/gcc/common/config/sparc/sparc-common.c b/gcc/common/config/sparc/sparc-common.c
index 3958b7e..1c5bc06 100644
--- a/gcc/common/config/sparc/sparc-common.c
+++ b/gcc/common/config/sparc/sparc-common.c
@@ -24,6 +24,14 @@ along with GCC; see the file COPYING3.  If not see
 #include "common/common-target.h"
 #include "common/common-target-def.h"
 
+/* Implement TARGET_OPTION_INIT_STRUCT.  */
+
+static void
+sparc_option_init_struct (struct gcc_options *opts)
+{
+  opts->x_flag_asynchronous_unwind_tables = 2;
+}
+
 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
 static const struct default_options sparc_option_optimization_table[] =
   {
@@ -31,6 +39,8 @@ static const struct default_options sparc_option_optimization_table[] =
     { OPT_LEVELS_NONE, 0, NULL, 0 }
   };
 
+#undef TARGET_OPTION_INIT_STRUCT
+#define TARGET_OPTION_INIT_STRUCT sparc_option_init_struct
 #undef TARGET_DEFAULT_TARGET_FLAGS
 #define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
 #undef TARGET_OPTION_OPTIMIZATION_TABLE
-- 
2.3.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default.
  2016-02-25 21:16 [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default Jose E. Marchesi
@ 2016-02-28 18:35 ` Eric Botcazou
  2016-02-29 15:42   ` Jose E. Marchesi
  0 siblings, 1 reply; 7+ messages in thread
From: Eric Botcazou @ 2016-02-28 18:35 UTC (permalink / raw)
  To: Jose E. Marchesi; +Cc: gcc-patches

> 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).

What's the problem exactly here?  Simple non-DWARF unwinders usually work fine 
with the SPARC architecture thanks to the calling conventions.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default.
  2016-02-28 18:35 ` Eric Botcazou
@ 2016-02-29 15:42   ` Jose E. Marchesi
  2016-03-09 10:03     ` Eric Botcazou
  2016-03-17 21:17     ` Richard Henderson
  0 siblings, 2 replies; 7+ messages in thread
From: Jose E. Marchesi @ 2016-02-29 15:42 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2284 bytes --]


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.)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: bug-backtrace.c --]
[-- Type: text/x-csrc, Size: 353 bytes --]

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default.
  2016-02-29 15:42   ` Jose E. Marchesi
@ 2016-03-09 10:03     ` Eric Botcazou
  2016-03-15 16:38       ` Jose E. Marchesi
  2016-03-17 21:17     ` Richard Henderson
  1 sibling, 1 reply; 7+ messages in thread
From: Eric Botcazou @ 2016-03-09 10:03 UTC (permalink / raw)
  To: Jose E. Marchesi; +Cc: gcc-patches

> 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.

How does that work for e.g. PowerPC or MIPS?  Why not do the same for SPARC?

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default.
  2016-03-09 10:03     ` Eric Botcazou
@ 2016-03-15 16:38       ` Jose E. Marchesi
  0 siblings, 0 replies; 7+ messages in thread
From: Jose E. Marchesi @ 2016-03-15 16:38 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches


    > 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.
    
    How does that work for e.g. PowerPC or MIPS?  Why not do the same for SPARC?

The glibc PowerPC port doesn't use the libgcc_s unwinder to implement
backtrace().  It has a little ad-hoc unwinder.

MIPS is like x86_64: it exclusively relies on libgcc_s _Unwind_Backtrace
to unwind the stack.

As far as I can tell, -fasynchronous-unwind-tables is disabled in MIPS
by default.  Therefore unless -fasynchronous-unwind-tables is used at
build time backtrace() probably has the same problem than sparc (can't
tell for sure, as I don't have access to any mips host where to test).

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default.
  2016-02-29 15:42   ` Jose E. Marchesi
  2016-03-09 10:03     ` Eric Botcazou
@ 2016-03-17 21:17     ` Richard Henderson
  2016-03-18  1:07       ` Jose E. Marchesi
  1 sibling, 1 reply; 7+ messages in thread
From: Richard Henderson @ 2016-03-17 21:17 UTC (permalink / raw)
  To: Jose E. Marchesi, Eric Botcazou; +Cc: gcc-patches

On 02/29/2016 07:50 AM, Jose E. Marchesi wrote:
> 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.

There's no reason that simple unwinder can't be put into
MD_FALLBACK_FRAME_STATE_FOR.

Currently we only use that for unwinding through signal stacks, but it could be
used for anything that the dwarf2 unwinder doesn't have data for.  Given sparc
register windows, this seems particularly reliable.


r~

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default.
  2016-03-17 21:17     ` Richard Henderson
@ 2016-03-18  1:07       ` Jose E. Marchesi
  0 siblings, 0 replies; 7+ messages in thread
From: Jose E. Marchesi @ 2016-03-18  1:07 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Eric Botcazou, gcc-patches


    > 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.
    
    There's no reason that simple unwinder can't be put into
    MD_FALLBACK_FRAME_STATE_FOR.
    
    Currently we only use that for unwinding through signal stacks, but it could be
    used for anything that the dwarf2 unwinder doesn't have data for.  Given sparc
    register windows, this seems particularly reliable.
    
Sounds like a good idea.  Let me prepare a patch for that...

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-03-18  0:33 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-25 21:16 [PATCH][SPARC] sparc: switch -fasynchronous-unwind-tables on by default Jose E. Marchesi
2016-02-28 18:35 ` Eric Botcazou
2016-02-29 15:42   ` Jose E. Marchesi
2016-03-09 10:03     ` Eric Botcazou
2016-03-15 16:38       ` Jose E. Marchesi
2016-03-17 21:17     ` Richard Henderson
2016-03-18  1:07       ` Jose E. Marchesi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).