From: Jan Kratochvil <jan.kratochvil@redhat.com>
To: gdb-patches@sourceware.org
Subject: [patch] Stop runaway unwinding on stripped executables
Date: Fri, 16 Mar 2012 12:02:00 -0000 [thread overview]
Message-ID: <20120316120207.GA10006@host2.jankratochvil.net> (raw)
Hi,
this situation came from the real world out there:
# inferior has symbols
echo 'main(){pause();}'|gcc -x c -; ./a.out& gdb -p $! -ex bt
#0 0x00007f9dc4d4f0d0 in __pause_nocancel () at ../sysdeps/unix/syscall-template.S:82
#1 0x00000000004004ea in main ()
(gdb) q
PROBLEM:
--------
# -s: inferior has no symbols
echo 'main(){pause();}'|gcc -x c - -s; ./a.out& gdb -p $! -ex bt
#0 0x00007f274fd5a0d0 in __pause_nocancel () at ../sysdeps/unix/syscall-template.S:82
#1 0x00000000004004ea in ?? ()
#2 0x00007f274fcc1735 in __libc_start_main (main=0x4004dc, ...) at libc-start.c:226
#3 0x00000000004003f9 in ?? ()
#4 0x00007fffdbdec7a8 in ?? ()
#5 0x000000000000001c in ?? ()
#6 0x0000000000000001 in ?? ()
#7 0x00007fffdbdede72 in ?? ()
#8 0x0000000000000000 in ?? ()
(gdb) q
--- In reality this backtrace can be much longer confusing the people
thinking they have wrong backtrace; it is correctly unwound, it is just
runaway unwinding garbage.
# -s, now with the fix below:
#0 0x00007f1b912b80d0 in __pause_nocancel () at ../sysdeps/unix/syscall-template.S:82
#1 0x00000000004004ea in ?? ()
#2 0x00007f1b9121f735 in __libc_start_main (main=0x4004dc, argc=1, ubp_av=0x7fff150f9038, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff150f9028) at libc-start.c:226
# inferior has symbols, with set backtrace past-main
echo 'main(){pause();}'|gcc -x c -; ./a.out& ./gdb -nx -p $! -ex 'set backtrace past-main' -ex bt
#0 0x00007f8930f090d0 in __pause_nocancel () at ../sysdeps/unix/syscall-template.S:82
#1 0x00000000004004ea in main ()
^^^^^^^ Both addresses were unwound above but not
printed.
#2 0x00007f8930e70735 in __libc_start_main (main=0x4004dc <main>, ...) at libc-start.c:226
#3 0x00000000004003f9 in _start ()
^^^^^^^^^ Both addresses were unwound above but not
printed. GDB needs to know at least size
of "_start" for inside_entry_func but
without symbols it knows neither.
(gdb) q
One can see that with stripped inferior (-s) GDB cannot even stop at the entry
symbol as "_start" is also missing there.
I find the patch safe enough, if we want to stop at "main" and we see
"__libc_start_main" there is no chance "main" would be seen anymore.
Sure this whole patch has no effect with "set backtrace past-main".
I do not think a testcase makes sense, it would just duplicate the C code
logic in TCL being untested if "__libc_start_main" is not found.
No regressions on {x86_64,x86_64-m32,i686}-fedora17-linux-gnu.
Thanks,
Jan
gdb/
2012-03-16 Jan Kratochvil <jan.kratochvil@redhat.com>
Stop runaway unwinding of stripped executables.
* frame.c: Include objfiles.h.
(past_main_func): New function.
(get_prev_frame): Call it besides inside_main_func.
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -43,7 +43,8 @@
#include "gdbthread.h"
#include "block.h"
#include "inline-frame.h"
-#include "tracepoint.h"
+#include "tracepoint.h"
+#include "objfiles.h"
static struct frame_info *get_prev_frame_1 (struct frame_info *this_frame);
static struct frame_info *get_prev_frame_raw (struct frame_info *this_frame);
@@ -1856,6 +1857,43 @@ inside_main_func (struct frame_info *this_frame)
return maddr == get_frame_func (this_frame);
}
+/* Is this (non-sentinel) frame verified to be after (missed) "main"()
+ function? This is a safety stop of runaway unwinding on stripped
+ executables missing both "main" and "_start" (entry) symbols when
+ "set backtrace past-main on" in in use. */
+
+static int
+past_main_func (struct frame_info *this_frame)
+{
+ struct objfile *objfile;
+
+ ALL_OBJFILES (objfile)
+ {
+ struct minimal_symbol *msymbol;
+ CORE_ADDR maddr;
+
+ if (objfile->separate_debug_objfile_backlink)
+ continue;
+
+ if (strcmp (lbasename (objfile->name), "libc.so.6") != 0)
+ continue;
+
+ msymbol = lookup_minimal_symbol ("__libc_start_main", NULL, objfile);
+ if (msymbol == NULL)
+ continue;
+
+ /* Make certain that the code, and not descriptor, address is
+ returned. */
+ maddr = gdbarch_convert_from_func_ptr_addr (get_frame_arch (this_frame),
+ SYMBOL_VALUE_ADDRESS (msymbol),
+ ¤t_target);
+ if (maddr == get_frame_func (this_frame))
+ return 1;
+ }
+
+ return 0;
+}
+
/* Test whether THIS_FRAME is inside the process entry point function. */
static int
@@ -1904,7 +1942,7 @@ get_prev_frame (struct frame_info *this_frame)
&& get_frame_type (this_frame) == NORMAL_FRAME
&& !backtrace_past_main
&& frame_pc_p
- && inside_main_func (this_frame))
+ && (inside_main_func (this_frame) || past_main_func (this_frame)))
/* Don't unwind past main(). Note, this is done _before_ the
frame has been marked as previously unwound. That way if the
user later decides to enable unwinds past main(), that will
next reply other threads:[~2012-03-16 12:02 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-16 12:02 Jan Kratochvil [this message]
2012-03-16 13:51 ` Mark Kettenis
2012-03-16 14:46 ` Jan Kratochvil
2012-03-16 16:14 ` Mark Kettenis
2012-03-16 16:57 ` Jan Kratochvil
2012-03-16 19:28 ` cancel: " Jan Kratochvil
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=20120316120207.GA10006@host2.jankratochvil.net \
--to=jan.kratochvil@redhat.com \
--cc=gdb-patches@sourceware.org \
/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