Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* determining whether page 0 (or low addresses in general) is executable
@ 2008-04-16 22:20 Doug Evans
  2008-04-16 22:25 ` Daniel Jacobowitz
  0 siblings, 1 reply; 4+ messages in thread
From: Doug Evans @ 2008-04-16 22:20 UTC (permalink / raw)
  To: gdb; +Cc: ppluzhnikov

Hi.  We're trying to come up with a workaround for an apparent gcc/linker issue
where debug info can be left behind that messes up backtraces.
The erroneous debug info shouldn't be generated, but gdb could do a better
job when faced with it.

foo.h:
struct Foo { Foo() { } };

foo.cc:
#include "foo.h"
typedef void (*FN)(void);
void crash()
{
  FN f = (FN)1;
  f();
}
int main()
{
  Foo f;
  crash();
  return 0;
}

bar.cc:
#include "foo.h"
int bar() { Foo f; return 0; }

bash$ x86_64-linux-g++ --version
x86_64-linux-g++ (GCC) 4.2.1
[...]
bash$ x86_64-linux-g++ -g foo.cc bar.cc
bash$ readelf -wf a.out | grep -A5 pc=0000
00000090 0000001c 00000078 FDE cie=00000078 pc=00000000..0000000a
  DW_CFA_advance_loc: 1 to 00000001
  DW_CFA_def_cfa_offset: 16
  DW_CFA_offset: r6 at cfa-16
  DW_CFA_advance_loc: 3 to 00000004
  DW_CFA_def_cfa_reg: r6

The constructor for Foo is emitted in both foo.o and bar.o, but
the duplicate is only partially removed.

bash$ gdb a.out
GNU gdb 6.8
[...]
(gdb) r
Starting program: /tmp/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000001 in ?? ()
(gdb) bt
#0  0x0000000000000001 in ?? ()
#1  0x0000000000400670 in ?? ()
#2  0x0000000000000001 in ?? ()
#3  0x0000000000400642 in main () at foo.cc:21
(gdb) 

If we apply the following hack, which makes GDB ignore unwind descriptors
in the first page, we get the expected backtrace.

*** dwarf2-frame.c~	Wed Apr 16 11:16:43 2008
--- dwarf2-frame.c	Wed Apr 16 11:16:43 2008
*************** dwarf2_frame_find_fde (CORE_ADDR *pc)
*** 1571,1576 ****
--- 1571,1583 ----
  {
    struct objfile *objfile;
  
+   if (*pc < (CORE_ADDR)0x1000)
+     {
+       /* Workaround for apparent toolchain issue,
+          ignore any unwind descriptors that describe code on the zero page.
+          We know there is no code there. */
+       return NULL;
+     }
    ALL_OBJFILES (objfile)
      {
        struct dwarf2_fde *fde;

bash$ hacked-gdb a.out
(gdb) r
Starting program: /tmp/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000001 in ?? ()
(gdb) bt
#0  0x0000000000000001 in ?? ()
#1  0x000000000040062a in crash () at foo.cc:15
#2  0x0000000000400642 in main () at foo.cc:21
(gdb) 

Assuming we want to have dwarf2_frame_find_fde reject clearly bogus
pc values, the issue is of course how to cleanly recognize them.
Suggestions?

One alternative is something like this, the catch being
how to write is_zero_page_executable.

*************** dwarf2_frame_find_fde (CORE_ADDR *pc)
@@ -1585,6 +1608,13 @@

     while (fde)
       {
+        if (fde->initial_location + offset == 0
+            && !is_zero_page_executable ())
+          {
+            /* Ignore this FDE -- linker bug.  */
+            fde = fde->next;
+            continue;
+          }


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

* Re: determining whether page 0 (or low addresses in general) is  executable
  2008-04-16 22:20 determining whether page 0 (or low addresses in general) is executable Doug Evans
@ 2008-04-16 22:25 ` Daniel Jacobowitz
  2008-04-17 10:10   ` Doug Evans
  0 siblings, 1 reply; 4+ messages in thread
From: Daniel Jacobowitz @ 2008-04-16 22:25 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb, ppluzhnikov

On Wed, Apr 16, 2008 at 12:20:47PM -0700, Doug Evans wrote:
> Hi.  We're trying to come up with a workaround for an apparent gcc/linker issue
> where debug info can be left behind that messes up backtraces.
> The erroneous debug info shouldn't be generated, but gdb could do a better
> job when faced with it.

Not much better; I would suggest effort be spent on the
linker/compiler limitations, instead.  For instance moving debug info
into comdat sections.

I thought GNU ld only had this problem for .debug_info and already
edited out discarded FDEs from .debug_frame / .eh_frame.  Are you
using GNU ld or gold?  Maybe the linker only edits .eh_frame.

> *************** dwarf2_frame_find_fde (CORE_ADDR *pc)
> @@ -1585,6 +1608,13 @@
> 
>      while (fde)
>        {
> +        if (fde->initial_location + offset == 0
> +            && !is_zero_page_executable ())
> +          {
> +            /* Ignore this FDE -- linker bug.  */
> +            fde = fde->next;
> +            continue;
> +          }
> 

See has_section_at_zero in dwarf2read.c.  It's just the same hack.

-- 
Daniel Jacobowitz
CodeSourcery


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

* Re: determining whether page 0 (or low addresses in general) is executable
  2008-04-16 22:25 ` Daniel Jacobowitz
@ 2008-04-17 10:10   ` Doug Evans
  2008-04-17 10:20     ` Daniel Jacobowitz
  0 siblings, 1 reply; 4+ messages in thread
From: Doug Evans @ 2008-04-17 10:10 UTC (permalink / raw)
  To: gdb, ppluzhnikov

On Wed, Apr 16, 2008 at 12:33 PM, Daniel Jacobowitz <drow@false.org> wrote:
> On Wed, Apr 16, 2008 at 12:20:47PM -0700, Doug Evans wrote:
>  > Hi.  We're trying to come up with a workaround for an apparent gcc/linker issue
>  > where debug info can be left behind that messes up backtraces.
>  > The erroneous debug info shouldn't be generated, but gdb could do a better
>  > job when faced with it.
>
>  Not much better; I would suggest effort be spent on the
>  linker/compiler limitations, instead.  For instance moving debug info
>  into comdat sections.

Hopefully that'll get done too of course.

>  I thought GNU ld only had this problem for .debug_info and already
>  edited out discarded FDEs from .debug_frame / .eh_frame.  Are you
>  using GNU ld or gold?  Maybe the linker only edits .eh_frame.

Actually the problem occurs with both gld and gold.  The linker does
explicitly handle .eh_frame, and I'm told the debug info doesn't go
into comdat on purpose (complexity issues I gather).

>
>
>  > *************** dwarf2_frame_find_fde (CORE_ADDR *pc)
>  > @@ -1585,6 +1608,13 @@
>  >
>  >      while (fde)
>  >        {
>  > +        if (fde->initial_location + offset == 0
>  > +            && !is_zero_page_executable ())
>  > +          {
>  > +            /* Ignore this FDE -- linker bug.  */
>  > +            fde = fde->next;
>  > +            continue;
>  > +          }
>  >
>
>  See has_section_at_zero in dwarf2read.c.  It's just the same hack.

Ah.  Thanks.


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

* Re: determining whether page 0 (or low addresses in general) is  executable
  2008-04-17 10:10   ` Doug Evans
@ 2008-04-17 10:20     ` Daniel Jacobowitz
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Jacobowitz @ 2008-04-17 10:20 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb, ppluzhnikov

On Wed, Apr 16, 2008 at 06:02:24PM -0700, Doug Evans wrote:
> >  I thought GNU ld only had this problem for .debug_info and already
> >  edited out discarded FDEs from .debug_frame / .eh_frame.  Are you
> >  using GNU ld or gold?  Maybe the linker only edits .eh_frame.
> 
> Actually the problem occurs with both gld and gold.  The linker does
> explicitly handle .eh_frame, and I'm told the debug info doesn't go
> into comdat on purpose (complexity issues I gather).

OK, so we could probably fix this in GNU ld by reusing the eh-frame
editor for .debug_frame too.  COMDAT is better, of course.  It's just
hard :-(

-- 
Daniel Jacobowitz
CodeSourcery


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

end of thread, other threads:[~2008-04-17  2:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-04-16 22:20 determining whether page 0 (or low addresses in general) is executable Doug Evans
2008-04-16 22:25 ` Daniel Jacobowitz
2008-04-17 10:10   ` Doug Evans
2008-04-17 10:20     ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox