Bug 40521 - [4.4/4.5 Regression] -g causes GCC to generate .eh_frame
Summary: [4.4/4.5 Regression] -g causes GCC to generate .eh_frame
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.4.0
: P2 critical
Target Milestone: 4.4.3
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-06-22 15:16 UTC by Daniel Jacobowitz
Modified: 2014-02-16 13:14 UTC (History)
10 users (show)

See Also:
Host:
Target: i686-pc-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Jacobowitz 2009-06-22 15:16:59 UTC
Put this in main.c and build it with a 4.4-branch compiler using recent binutils:

int main ()
{
  return 0;
}

Versions:

GNU assembler (GNU Binutils) 2.19.51.20090611
i686-pc-linux-gnu-gcc (GCC) 4.4.1 20090611 (prerelease)

% i686-pc-linux-gnu-gcc -c main.c; objdump --wide -h main.o | grep ALLOC
  0 .text         0000000a  00000000  00000000  00000034  2**2  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000040  2**2  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000040  2**2  ALLOC

% i686-pc-linux-gnu-gcc -c -g main.c; objdump --wide -h main.o | grep ALLOC
  0 .text         0000000a  00000000  00000000  00000034  2**2  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000040  2**2  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000040  2**2  ALLOC
 12 .eh_frame     00000034  00000000  00000000  000001c0  2**2  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

We're using GAS's .cfi_startproc et cetera directives to generate debug information.  But they only generate .eh_frame, not .debug_frame.

I also noticed this problem on an ARM EABI target.  ARM EABI does not use .eh_frame, only .debug_frame and .ARM.exidx.

The easiest fix is to disable use of the CFI directives when we are trying to generate .debug_frame.  I believe GCC used to generate both .debug_frame and .eh_frame for the same function.  If we want both to gain the advantages of using CFI directives (e.g. potentially accurate across inline asm), then we need to teach gas to emit .debug_frame/.eh_frame/both as requested.
Comment 1 Daniel Jacobowitz 2009-06-22 15:20:22 UTC
CC'ing some people who know about CFI for opinions on the best resolution.  Do we need a new gas option and/or CFI directive for this?
Comment 2 Daniel Jacobowitz 2009-06-22 15:22:49 UTC
I've confirmed that older GCC emits both .debug_frame and .eh_frame.
Comment 3 Jakub Jelinek 2009-06-23 11:09:46 UTC
I think if we don't want to emit .eh_frame, we should just default to -fno-dwarf2-cfi-asm.  But if we do want to generate it, I fail to see what do we gain by also generating .debug_frame.  Duplicating the same info, in one case in a more compat form, doesn't look like a good idea.

If we decide to teach gas to emit both .eh_frame and .debug_frame, or just
.eh_frame, or just .debug_frame from CFI directives (controlled using some directive or option?), then one thing that needs solving is that gas will have to hardcode a register mapping table for ppc*, because on ppc .eh_frame uses
a different register numbering from .debug_frame.
Comment 4 Daniel Jacobowitz 2009-06-23 12:24:14 UTC
Subject: Re:  [4.4/4.5 Regression] -g causes GCC to
	generate .eh_frame

On Tue, Jun 23, 2009 at 11:09:48AM -0000, jakub at gcc dot gnu dot org wrote:
> I think if we don't want to emit .eh_frame, we should just default to
> -fno-dwarf2-cfi-asm.  But if we do want to generate it, I fail to see what do
> we gain by also generating .debug_frame.  Duplicating the same info, in one
> case in a more compat form, doesn't look like a good idea.

That sounds reasonable.  At one point there was a proposal to emit
completely accurate unwind information for .debug_frame, and skip some
prologue/epilogue information in .eh_frame; if we do that, obviously
we need both sets of output, but otherwise we don't.

We should make this be consistent though, not depend on
-fno-dwarf2-cfi-asm.

Comment 6 Jakub Jelinek 2009-10-02 18:52:30 UTC
Subject: Bug 40521

Author: jakub
Date: Fri Oct  2 18:52:15 2009
New Revision: 152414

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=152414
Log:
	PR debug/40521
	* configure.ac (HAVE_GAS_CFI_SECTIONS_DIRECTIVE): New test.
	* configure: Regenerated.
	* config.in: Regenerated.
	* dwarf2out.c (dwarf2out_do_cfi_asm): Return false if
	!HAVE_GAS_CFI_SECTIONS_DIRECTIVE and not emitting .eh_frame.
	(dwarf2out_init): If HAVE_GAS_CFI_SECTIONS_DIRECTIVE and
	not emitting .eh_frame, emit .cfi_sections .debug_frame
	directive.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config.in
    trunk/gcc/configure
    trunk/gcc/configure.ac
    trunk/gcc/dwarf2out.c

Comment 7 Matthias Klose 2009-10-08 15:17:57 UTC
With binutils from the 2.20 branch, and gcc from the 4.4 branch, including Jakub's patch, and excluding the current workaround from Ramana, I get:

$ gcc -c main.c 
$ objdump --wide -h main.o | grep ALLOC
  0 .text         0000001c  00000000  00000000  00000034  2**2  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000050  2**0  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000050  2**0  ALLOC
$ gcc -c -g main.c 
$ objdump --wide -h main.o | grep ALLOC
  0 .text         0000001c  00000000  00000000  00000034  2**2  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000050  2**0  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000050  2**0  ALLOC

OpenOffice rebuilt with these tools doesn't crash anymore. See PR ld/10695 and
http://qa.openoffice.org/issues/show_bug.cgi?id=105359
Comment 8 Ramana Radhakrishnan 2009-10-08 15:36:57 UTC
(In reply to comment #7)
> With binutils from the 2.20 branch, and gcc from the 4.4 branch, including
> Jakub's patch, and excluding the current workaround from Ramana, I get:
> 

IIUC and to make things explicit, the work-around is needed for any binutils prior to the 2.20 branch until the backport is done. If the backport is committed we should pull out my work around as well. 


Comment 9 Mikael Pettersson 2009-10-09 18:28:07 UTC
I've been testing a backport of Jakub's patch to gcc-4.4, but it breaks bootstrap on i686-linux with binutils-2.18.50.0.6 (Fedora 9) because stage1 gcc outputs .cfi_sections directives even though the assembler doesn't support them.
Current gcc-4.5 bootstraps Ok on the same machine.

The configure test correctly detects that cfi sections don't work with this as, and records that with "#define HAVE_GAS_CFI_SECTIONS_DIRECTIVE 0".

In gcc-4.5 dwarf2out_do_cfi_asm() returns true. The code in dwarf2out_init() inside #ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE finds that USING_SJLJ_EXCEPTIONS is false and !flag_exceptions is also false, so the call to emit a .cfi_sections directive is not made. (!flag_unwind_tables varies, but it does not matter since it's && with !flag_exceptions which always is false.)

In gcc-4.4 dwarf2out_do_cfi_asm() also returns true. The code in dwarf2out_init() finds that USING_SJLJ_EXCEPTIONS is false but both !flag_unwind_tables and !flag_exceptions are true, so a .cfi_sections directive is emitted, causing the assembler to signal an error.

One thing that I find strange is that dwarf2out_do_cfi_asm() unconditionally tests HAVE_GAS_CFI_SECTIONS_DIRECTIVE in an "if (!...)", which works since that symbol is #defined as 0 or 1, while dwarf2out_init() instead has an #ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE around the conditional output of the directive.
Shouldn't that #ifdef be an #if?
Comment 10 Jakub Jelinek 2009-10-09 18:54:45 UTC
Yes, it is a bug and I'll change it, but I wonder why it makes a difference (unless you're using PCH).  .cfi_sections is only emitted if:
  if (dwarf2out_do_cfi_asm ())
    {
#ifndef TARGET_UNWIND_INFO
      if (USING_SJLJ_EXCEPTIONS || (!flag_unwind_tables && !flag_exceptions))
#endif
        fprintf (asm_out_file, "\t.cfi_sections\t.debug_frame\n");
    }
#endif
but if !HAVE_CFI_SECTIONS_DIRECTIVE, dwarf2out_do_cfi_asm () has:
  if (!HAVE_GAS_CFI_SECTIONS_DIRECTIVE)
    {
#ifdef TARGET_UNWIND_INFO
      return false;
#else
      if (USING_SJLJ_EXCEPTIONS || (!flag_unwind_tables && !flag_exceptions))
        return false;
#endif
    }

i.e. will return false under the exact same condition that dwarf2_init would allow it.  The only exception is when using PCH, you could create PCH with saved_do_cfi_asm true and then load it.
Comment 11 Jakub Jelinek 2009-10-09 19:07:35 UTC
Subject: Bug 40521

Author: jakub
Date: Fri Oct  9 19:07:23 2009
New Revision: 152598

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=152598
Log:
	PR debug/40521
	* dwarf2out.c (dwarf2out_init): Test whether
	HAVE_GAS_CFI_SECTIONS_DIRECTIVE is non-zero instead of checking
	it is defined.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/dwarf2out.c

Comment 12 Jakub Jelinek 2009-10-09 19:17:25 UTC
Ah, now I see it in the 4.4 version.  Your backport is wrong then, you must not return true from dwarf2out_do_cfi_asm when !eh_personality_libfunc, but HAVE_GAS_CFI_SECTIONS_DIRECTIVE is 0 and not emitting normal unwind info.

Either you want:
int
dwarf2out_do_cfi_asm (void)
{
  int enc;

#ifdef MIPS_DEBUGGING_INFO
  return false;
#endif
  if (!flag_dwarf2_cfi_asm || !dwarf2out_do_frame ())
    return false;
  if (saved_do_cfi_asm)
    return true;
  if (eh_personality_libfunc)
    {
      if (!HAVE_GAS_CFI_PERSONALITY_DIRECTIVE)
        return false;

      /* Make sure the personality encoding is one the assembler can support.
         In particular, aligned addresses can't be handled.  */
      enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2,/*global=*/1);
      if ((enc & 0x70) != 0 && (enc & 0x70) != DW_EH_PE_pcrel)
        return false;
      enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0,/*global=*/0);
      if ((enc & 0x70) != 0 && (enc & 0x70) != DW_EH_PE_pcrel)
        return false;
    }

  if (!HAVE_GAS_CFI_SECTIONS_DIRECTIVE)
    {
#ifdef TARGET_UNWIND_INFO
      return false;
#else
      if (USING_SJLJ_EXCEPTIONS || (!flag_unwind_tables && !flag_exceptions))
        return false;
#endif
    }

  saved_do_cfi_asm = true;
  return true;
}

or move the !HAVE_GAS_CFI_SECTIONS_DIRECTIVE tests in between if (saved_do_cfi_asm) return true; and if (!eh_personality_libfunc) return true;.
Comment 13 Mikael Pettersson 2009-10-09 19:51:33 UTC
Thanks for clarifying the !eh_personality_libfunc requirement. I'll do some experiments to see which solution works best in 4.4.
Comment 14 Fabio Frumento 2009-10-11 22:52:00 UTC
(In reply to comment #0)
> Put this in main.c and build it with a 4.4-branch compiler using recent
> binutils:
> 
> int main ()
> {
>   return 0;
> }
> 
> Versions:
> 
> GNU assembler (GNU Binutils) 2.19.51.20090611
> i686-pc-linux-gnu-gcc (GCC) 4.4.1 20090611 (prerelease)
> 
> % i686-pc-linux-gnu-gcc -c main.c; objdump --wide -h main.o | grep ALLOC
>   0 .text         0000000a  00000000  00000000  00000034  2**2  CONTENTS,
> ALLOC, LOAD, READONLY, CODE
>   1 .data         00000000  00000000  00000000  00000040  2**2  CONTENTS,
> ALLOC, LOAD, DATA
>   2 .bss          00000000  00000000  00000000  00000040  2**2  ALLOC
> 
> % i686-pc-linux-gnu-gcc -c -g main.c; objdump --wide -h main.o | grep ALLOC
>   0 .text         0000000a  00000000  00000000  00000034  2**2  CONTENTS,
> ALLOC, LOAD, READONLY, CODE
>   1 .data         00000000  00000000  00000000  00000040  2**2  CONTENTS,
> ALLOC, LOAD, DATA
>   2 .bss          00000000  00000000  00000000  00000040  2**2  ALLOC
>  12 .eh_frame     00000034  00000000  00000000  000001c0  2**2  CONTENTS,
> ALLOC, LOAD, RELOC, READONLY, DATA
> 
> We're using GAS's .cfi_startproc et cetera directives to generate debug
> information.  But they only generate .eh_frame, not .debug_frame.
> 
> I also noticed this problem on an ARM EABI target.  ARM EABI does not use
> .eh_frame, only .debug_frame and .ARM.exidx.
> 
> The easiest fix is to disable use of the CFI directives when we are trying to
> generate .debug_frame.  I believe GCC used to generate both .debug_frame and
> .eh_frame for the same function.  If we want both to gain the advantages of
> using CFI directives (e.g. potentially accurate across inline asm), then we
> need to teach gas to emit .debug_frame/.eh_frame/both as requested.
> 

Hi all,

I've noticed ther behaviour differs for some platform

I've tested a cross compiler Gcc 4.4.1 on Cygwin and on Mac OSX 1.6,I've built it from vanilla sources (gcc.gnu.org), the final target is M68K/Coldfire

on mac no problem at all while on cygwin i've got a "no memory region ...omissis... for .eh_frame" error message, i've built the same files just checked out from svn repository. While i've solved disabling debug options i can't use this setup for long, I've also modified the linker script as follow:

MEMORY
{
	flash  : ORIGIN = 0x0000000, LENGTH = 0x100000
	dpram  : ORIGIN = 0x0FFFE000, LENGTH = 0x1000
}

SECTIONS {
	.text : {*(boot) *(text) *(eh_frame)} > flash
	.data : {} > dpram
	.bss : {} > dpram
	eh_frame :{} > flash
	/DISCARD/ : { *(eh_*)}
}

but it seems that on cygwin the /DISCARD/ special command doesn't work so my binary files is larger than the mac generated one.

Any idea ?

Comment 15 Sebastian Huber 2009-10-12 11:36:27 UTC
(In reply to comment #13)
> Thanks for clarifying the !eh_personality_libfunc requirement. I'll do some
> experiments to see which solution works best in 4.4.
> 

Is the target milestone 4.4.2 still true? In 4.4.2 20091008 the problem is still present.
Comment 16 Mikael Pettersson 2009-10-12 12:33:51 UTC
(In reply to comment #15)
> Is the target milestone 4.4.2 still true? In 4.4.2 20091008 the problem is
> still present.

I have a patch for 4.4 which bootstraps and passes regression testing on i686-linux and powerpc64-linux. It also bootstraps on armv5tel-linux-gnueabi (the platform for which I want this fix) with Ramana's workaround reverted, but the test suite is not yet finished; it should be done around midnight today. I plan to submit the patch tomorrow.
Comment 17 Mikael Pettersson 2009-10-13 12:52:58 UTC
Patch with proposed backport to 4.4 posted here:
http://gcc.gnu.org/ml/gcc-patches/2009-10/msg00818.html
Comment 18 Jakub Jelinek 2009-10-16 14:55:11 UTC
When testing this, I've noticed a major problem with Ada, supposedly on the trunk as well when using latest binutils.

The problem is that gnat_init_gcc_eh which can change flag_exceptions is called way too late, not from lang_hooks.init, but far after it.  This means by the time dwarf2out_init is called flag_exceptions might be still 0 and thus .cfi_sections .dwarf_frame is emitted.  But then gnat_init_gcc_eh changes flag_exception to 1 and excepts .eh_frame to be generated.
The reason I've put .cfi_sections directive addition to dwarf2out.c is to allow the user to override it within inline assembly, so I don't want to emit it at the end of the file.
Comment 19 Eric Botcazou 2009-10-16 17:35:21 UTC
> When testing this, I've noticed a major problem with Ada, supposedly on the
> trunk as well when using latest binutils.

Thanks for the heads up.

> The problem is that gnat_init_gcc_eh which can change flag_exceptions is
> called way too late, not from lang_hooks.init, but far after it.  This means
> by the time dwarf2out_init is called flag_exceptions might be still 0 and
> thus .cfi_sections .dwarf_frame is emitted.  But then gnat_init_gcc_eh
> changes flag_exception to 1 and excepts .eh_frame to be generated.

Can we arrange for making it safe to set flag_exceptions from lang_hooks.init and then clear it in gnat_init_gcc_eh?
Comment 20 Jakub Jelinek 2009-10-17 07:28:35 UTC
Subject: Bug 40521

Author: jakub
Date: Sat Oct 17 07:28:13 2009
New Revision: 152930

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=152930
Log:
	PR debug/40521
	* debug.h (struct gcc_debug_hooks): Add assembly_start hook.
	* cgraphunit.c (cgraph_optimize): Call it.
	* dwarf2out.c (dwarf2out_init): Move .cfi_sections printing into...
	(dwarf2out_assembly_start): ... here.  New hook.
	(dwarf2out_debug_hooks): Add dwarf2out_assembly_start.
	* debug.c (do_nothing_debug_hooks): Do nothing for assembly_start
	hook.
	* dbxout.c (dbx_debug_hooks, xcoff_debug_hooks): Likewise.
	* sdbout.c (sdb_debug_hooks): Likewise.
	* vmsdbgout.c (vmsdbg_debug_hooks): Add vmsdbgout_assembly_start.
	(vmsdbgout_assembly_start): New hook.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cgraphunit.c
    trunk/gcc/dbxout.c
    trunk/gcc/debug.c
    trunk/gcc/debug.h
    trunk/gcc/dwarf2out.c
    trunk/gcc/sdbout.c
    trunk/gcc/vmsdbgout.c

Comment 21 Jakub Jelinek 2009-10-19 12:15:47 UTC
Subject: Bug 40521

Author: jakub
Date: Mon Oct 19 12:15:27 2009
New Revision: 152974

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=152974
Log:
	Backport from mainline:
	2009-10-16  Jakub Jelinek  <jakub@redhat.com>

	PR debug/40521
	* debug.h (struct gcc_debug_hooks): Add assembly_start hook.
	* cgraphunit.c (cgraph_optimize): Call it.
	* dwarf2out.c (dwarf2out_init): Move .cfi_sections printing into...
	(dwarf2out_assembly_start): ... here.  New hook.
	(dwarf2out_debug_hooks): Add dwarf2out_assembly_start.
	* debug.c (do_nothing_debug_hooks): Do nothing for assembly_start
	hook.
	* dbxout.c (dbx_debug_hooks, xcoff_debug_hooks): Likewise.
	* sdbout.c (sdb_debug_hooks): Likewise.
	* vmsdbgout.c (vmsdbg_debug_hooks): Add vmsdbgout_assembly_start.
	(vmsdbgout_assembly_start): New hook.

	2009-10-09  Jakub Jelinek  <jakub@redhat.com>

	PR debug/40521
	* dwarf2out.c (dwarf2out_init): Test whether
	HAVE_GAS_CFI_SECTIONS_DIRECTIVE is non-zero instead of checking
	it is defined.

	2009-10-02  Jakub Jelinek  <jakub@redhat.com>

	PR debug/40521
	* configure.ac (HAVE_GAS_CFI_SECTIONS_DIRECTIVE): New test.
	* configure: Regenerated.
	* config.in: Regenerated.
	* dwarf2out.c (dwarf2out_do_cfi_asm): Return false if
	!HAVE_GAS_CFI_SECTIONS_DIRECTIVE and not emitting .eh_frame.
	(dwarf2out_init): If HAVE_GAS_CFI_SECTIONS_DIRECTIVE and
	not emitting .eh_frame, emit .cfi_sections .debug_frame
	directive.

Modified:
    branches/gcc-4_4-branch/gcc/ChangeLog
    branches/gcc-4_4-branch/gcc/cgraphunit.c
    branches/gcc-4_4-branch/gcc/config.in
    branches/gcc-4_4-branch/gcc/configure
    branches/gcc-4_4-branch/gcc/configure.ac
    branches/gcc-4_4-branch/gcc/dbxout.c
    branches/gcc-4_4-branch/gcc/debug.c
    branches/gcc-4_4-branch/gcc/debug.h
    branches/gcc-4_4-branch/gcc/dwarf2out.c
    branches/gcc-4_4-branch/gcc/sdbout.c
    branches/gcc-4_4-branch/gcc/vmsdbgout.c

Comment 22 Jakub Jelinek 2009-10-19 12:21:39 UTC
Fixed.
Comment 23 Mikael Pettersson 2009-10-21 10:48:41 UTC
(In reply to comment #8)
> (In reply to comment #7)
> > With binutils from the 2.20 branch, and gcc from the 4.4 branch, including
> > Jakub's patch, and excluding the current workaround from Ramana, I get:
> > 
> 
> IIUC and to make things explicit, the work-around is needed for any binutils
> prior to the 2.20 branch until the backport is done. If the backport is
> committed we should pull out my work around as well. 

The backport has been committed now, so your PR41533 workaround should not be needed any more.
Comment 24 Thomas Schwinge 2010-03-31 15:49:54 UTC
Regression report for arm-none-linux-gnueabi: <http://gcc.gnu.org/ml/gcc-patches/2010-03/msg01188.html>
Patch: <http://gcc.gnu.org/ml/gcc-patches/2010-03/msg01505.html>
Comment 25 Jackie Rosen 2014-02-16 13:14:39 UTC Comment hidden (spam)