From: dje@google.com (Doug Evans)
To: gdb@sourceware.org
Cc: ppluzhnikov@google.com
Subject: determining whether page 0 (or low addresses in general) is executable
Date: Wed, 16 Apr 2008 22:20:00 -0000 [thread overview]
Message-ID: <20080416192047.984F91C75AD@localhost> (raw)
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;
+ }
next reply other threads:[~2008-04-16 19:22 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-16 22:20 Doug Evans [this message]
2008-04-16 22:25 ` Daniel Jacobowitz
2008-04-17 10:10 ` Doug Evans
2008-04-17 10:20 ` Daniel Jacobowitz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080416192047.984F91C75AD@localhost \
--to=dje@google.com \
--cc=gdb@sourceware.org \
--cc=ppluzhnikov@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox