* 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