From: Jan Kratochvil <jan.kratochvil@redhat.com>
To: "Metzger, Markus T" <markus.t.metzger@intel.com>
Cc: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Subject: Re: [patch v4 18/24] record-btrace: extend unwinder
Date: Fri, 27 Sep 2013 13:55:00 -0000 [thread overview]
Message-ID: <20130927135521.GB13376@host2.jankratochvil.net> (raw)
In-Reply-To: <A78C989F6D9628469189715575E55B230A9CEAB0@IRSMSX104.ger.corp.intel.com>
[-- Attachment #1: Type: text/plain, Size: 4232 bytes --]
On Mon, 16 Sep 2013 13:21:29 +0200, Metzger, Markus T wrote:
> > > An assertion in get_frame_id at frame.c:340 requires that a frame
> > > provides a stack address. The record-btrace unwinder can't provide
> > > this since the trace does not contain data. I incorrectly set
> > > stack_addr_p to 1 to avoid the assertion.
> >
> > Primarily record-btrace can provide the stack address. You know $sp at the
> > end of the recoding and you can query .eh_frame/.debug_frame at any PC
> > address what is the difference between $sp and caller's $sp at that exact PC.
> > This assumes either all the involved binaries were built with -fasynchronous-
> > unwind-tables (for .eh_frame) or that debug info (for .debug_frame) is
> > present. The former is true in Fedora / Red Hat distros, unaware how others.
>
> This would only hold for functions that have not yet returned to their caller.
> If we go back far enough, the branch trace will also contain functions that
> have already returned to their caller for which we do not have any information.
> I would even argue that this is the majority of functions in the branch trace.
In many cases one can reconstruct $sp. But for example if alloca() was in use
I see now $sp cannot be reconstructed. So I agree now GDB has to handle cases
when $sp is not known for a frame_id.
BTW in many cases one realy can reconstruct all past $sp addresses from the
btrace buffer. I have tried it for one backtrace of /usr/bin/gdb :
It will not work (at least) in two cases:
* for -O0 code (not -O2) GCC does not produce DW_CFA_def_cfa_offset but it
provides just:
DW_CFA_def_cfa_register: r6 (rbp)
As you describe we do not know $rbp that time anymore.
* Even in -O2 code if a function uses alloca() GCC will produce again:
DW_CFA_def_cfa_register: r6 (rbp)
I have no idea in which percentage of real world code the
DW_CFA_def_cfa_offset dependency would work, C++ code CFI may look differently
than GDB in plain C I tried below:
CIE has always:
DW_CFA_def_cfa: r7 (rsp) ofs 8
#0 0x00007ffff5eef950 in __poll_nocancel
DW_CFA_def_cfa: r7 (rsp) ofs 8
#1 0x000000000059bb63 in poll
DW_CFA_def_cfa_offset: 80
#2 gdb_wait_for_event
#3 0x000000000059c2da in gdb_do_one_event
DW_CFA_def_cfa_offset: 64
#4 0x000000000059c517 in start_event_loop
DW_CFA_def_cfa_offset: 48
#5 0x00000000005953a3 in captured_command_loop
DW_CFA_def_cfa_offset: 16
#6 0x00000000005934aa in catch_errors
DW_CFA_def_cfa_offset: 112
#7 0x000000000059607e in captured_main
DW_CFA_def_cfa_offset: 192
#8 0x00000000005934aa in catch_errors
DW_CFA_def_cfa_offset: 112
#9 0x0000000000596c44 in gdb_main
DW_CFA_def_cfa_offset: 16
#10 0x000000000045526e in main
DW_CFA_def_cfa_offset: 64
As an obvious check $sp in #10 main 0x7fffffffd940 - $sp in #0 0x7fffffffd6b8:
(gdb) p 0x7fffffffd940 - 0x7fffffffd6b8
$1 = 648
8+80+64+48+16+112+192+112+16 = 648
This is just FYI, I do not ask to implement it. I do not think knowing just
$sp is too important when it works only sometimes.
> > The current method of constant STACK_ADDR may have some problems with
> > frame_id_inner() but I did not investigate it more.
>
> By looking at the code, frame_id_inner () should always fail since all btrace
> frames have stack_addr == 0.
>
> On the other hand, frame_id_inner is only called for frames of type
> NORMAL_FRAME, whereas btrace frames have type BTRACE_FRAME.
OK, I agree now frame_id_inner() is not needed.
> This has meanwhile been resolved. This had been a side-effect of throwing
> an error in to_fetch_registers. When I just return, function arguments are
> correctly displayed as unavailable and the "can't compute CFA for this frame"
> message is gone.
With v6 patchset it is only sometimes gone, I still get it.
Tested with (results are the same):
gcc (GCC) 4.8.2 20130927 (prerelease)
gcc-4.8.1-10.fc21.x86_64
int f(int i) {
return i;
}
int main(void) {
f(1);
return 0;
}
gcc -o test3 test3.c -Wall -g
./gdb ./test3 -ex start -ex 'record btrace' -ex step -ex step -ex reverse-step -ex frame
#0 f (i=<error reading variable: can't compute CFA for this frame>) at test3.c:2
2 return i;
(gdb) _
It gets fixed by the attached patch.
Thanks,
Jan
[-- Attachment #2: cfa.patch --]
[-- Type: text/plain, Size: 1824 bytes --]
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 2aff23e..518b0b9 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -1495,9 +1495,13 @@ dwarf2_frame_base_sniffer (struct frame_info *this_frame)
CORE_ADDR
dwarf2_frame_cfa (struct frame_info *this_frame)
{
+ extern const struct frame_unwind record_btrace_frame_unwind;
+ extern const struct frame_unwind record_btrace_tailcall_frame_unwind;
while (get_frame_type (this_frame) == INLINE_FRAME)
this_frame = get_prev_frame (this_frame);
- if (get_frame_unwind_stop_reason (this_frame) == UNWIND_UNAVAILABLE)
+ if (get_frame_unwind_stop_reason (this_frame) == UNWIND_UNAVAILABLE
+ || frame_unwinder_is (this_frame, &record_btrace_frame_unwind)
+ || frame_unwinder_is (this_frame, &record_btrace_tailcall_frame_unwind))
throw_error (NOT_AVAILABLE_ERROR,
_("can't compute CFA for this frame: "
"required registers or memory are unavailable"));
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index d634712..9a4287b 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1217,7 +1217,7 @@ record_btrace_frame_dealloc_cache (struct frame_info *self, void *this_cache)
Therefore this unwinder reports any possibly unwound registers as
<unavailable>. */
-static const struct frame_unwind record_btrace_frame_unwind =
+const struct frame_unwind record_btrace_frame_unwind =
{
BTRACE_FRAME,
record_btrace_frame_unwind_stop_reason,
@@ -1228,7 +1228,7 @@ static const struct frame_unwind record_btrace_frame_unwind =
record_btrace_frame_dealloc_cache
};
-static const struct frame_unwind record_btrace_tailcall_frame_unwind =
+const struct frame_unwind record_btrace_tailcall_frame_unwind =
{
BTRACE_TAILCALL_FRAME,
record_btrace_frame_unwind_stop_reason,
next prev parent reply other threads:[~2013-09-27 13:55 UTC|newest]
Thread overview: 88+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-03 9:15 [patch v4 00/24] record-btrace: reverse Markus Metzger
2013-07-03 9:14 ` [patch v4 05/24] record-btrace: start counting at one Markus Metzger
2013-08-18 19:11 ` Jan Kratochvil
2013-07-03 9:14 ` [patch v4 09/24] btrace: add replay position to btrace thread info Markus Metzger
2013-08-18 19:07 ` Jan Kratochvil
2013-09-10 13:24 ` Metzger, Markus T
2013-09-12 20:19 ` Jan Kratochvil
2013-07-03 9:14 ` [patch v4 14/24] record-btrace: provide xfer_partial target method Markus Metzger
2013-08-18 19:08 ` Jan Kratochvil
2013-09-16 9:30 ` Metzger, Markus T
2013-09-22 14:18 ` Jan Kratochvil
2013-07-03 9:14 ` [patch v4 02/24] record: upcase record_print_flag enumeration constants Markus Metzger
2013-08-18 19:11 ` Jan Kratochvil
2013-07-03 9:14 ` [patch v4 16/24] record-btrace: provide target_find_new_threads method Markus Metzger
2013-08-18 19:15 ` Jan Kratochvil
2013-07-03 9:14 ` [patch v4 08/24] record-btrace: make ranges include begin and end Markus Metzger
2013-08-18 19:12 ` Jan Kratochvil
2013-07-03 9:14 ` [patch v4 07/24] record-btrace: optionally indent function call history Markus Metzger
2013-08-18 19:06 ` Jan Kratochvil
2013-09-10 13:06 ` Metzger, Markus T
2013-09-10 13:08 ` Jan Kratochvil
2013-07-03 9:14 ` [patch v4 22/24] infrun: reverse stepping from unknown functions Markus Metzger
2013-08-18 19:09 ` Jan Kratochvil
2013-07-03 9:14 ` [patch v4 24/24] record-btrace: skip tail calls in back trace Markus Metzger
2013-08-18 19:10 ` Jan Kratochvil
2013-09-17 14:28 ` Metzger, Markus T
2013-09-18 8:28 ` Metzger, Markus T
2013-09-18 9:52 ` Metzger, Markus T
2013-07-03 9:14 ` [patch v4 20/24] btrace, gdbserver: read branch trace incrementally Markus Metzger
2013-08-18 19:09 ` Jan Kratochvil
2013-09-16 12:48 ` Metzger, Markus T
2013-09-22 14:42 ` Jan Kratochvil
2013-09-23 7:09 ` Metzger, Markus T
2013-09-25 19:05 ` Jan Kratochvil
2013-09-26 6:27 ` Metzger, Markus T
2013-07-03 9:14 ` [patch v4 11/24] record-btrace: supply register target methods Markus Metzger
2013-08-18 19:07 ` Jan Kratochvil
2013-09-16 9:19 ` Metzger, Markus T
2013-09-22 13:55 ` Jan Kratochvil
2013-09-23 6:55 ` Metzger, Markus T
2013-07-03 9:14 ` [patch v4 19/24] btrace, linux: fix memory leak when reading branch trace Markus Metzger
2013-08-18 19:09 ` Jan Kratochvil
2013-07-03 9:14 ` [patch v4 03/24] btrace: change branch trace data structure Markus Metzger
2013-08-18 19:05 ` Jan Kratochvil
2013-09-10 9:11 ` Metzger, Markus T
2013-09-12 20:09 ` Jan Kratochvil
2013-09-16 9:01 ` Metzger, Markus T
2013-09-21 19:44 ` Jan Kratochvil
2013-09-23 6:54 ` Metzger, Markus T
2013-09-23 7:15 ` Jan Kratochvil
2013-09-23 7:27 ` Metzger, Markus T
2013-09-22 16:57 ` Jan Kratochvil
2013-09-22 17:16 ` Jan Kratochvil
2013-07-03 9:14 ` [patch v4 10/24] target: add ops parameter to to_prepare_to_store method Markus Metzger
2013-08-18 19:07 ` Jan Kratochvil
2013-07-03 9:15 ` [patch v4 13/24] record-btrace, frame: supply target-specific unwinder Markus Metzger
2013-08-18 19:07 ` Jan Kratochvil
2013-07-03 9:15 ` [patch v4 15/24] record-btrace: add to_wait and to_resume target methods Markus Metzger
2013-08-18 19:08 ` Jan Kratochvil
2013-07-03 9:15 ` [patch v4 17/24] record-btrace: add record goto " Markus Metzger
2013-08-18 19:08 ` Jan Kratochvil
2013-07-03 9:15 ` [patch v4 06/24] btrace: increase buffer size Markus Metzger
2013-08-18 19:06 ` Jan Kratochvil
2013-07-03 9:15 ` [patch v4 23/24] record-btrace: add (reverse-)stepping support Markus Metzger
2013-08-18 19:09 ` Jan Kratochvil
2013-09-17 9:43 ` Metzger, Markus T
2013-09-29 17:24 ` Jan Kratochvil
2013-09-30 9:30 ` Metzger, Markus T
2013-09-30 10:25 ` Jan Kratochvil
2013-07-03 9:15 ` [patch v4 01/24] gdbarch: add instruction predicate methods Markus Metzger
2013-07-03 9:49 ` Mark Kettenis
2013-07-03 11:10 ` Metzger, Markus T
2013-08-18 19:04 ` Jan Kratochvil
2013-07-03 9:15 ` [patch v4 04/24] record-btrace: fix insn range in function call history Markus Metzger
2013-08-18 19:06 ` Jan Kratochvil
2013-07-03 9:15 ` [patch v4 18/24] record-btrace: extend unwinder Markus Metzger
2013-08-18 19:08 ` Jan Kratochvil
2013-09-16 11:21 ` Metzger, Markus T
2013-09-27 13:55 ` Jan Kratochvil [this message]
2013-09-30 9:45 ` Metzger, Markus T
2013-09-30 10:26 ` Jan Kratochvil
2013-07-03 9:15 ` [patch v4 21/24] record-btrace: show trace from enable location Markus Metzger
2013-08-18 19:10 ` instruction_history.exp unset variable [Re: [patch v4 21/24] record-btrace: show trace from enable location] Jan Kratochvil
2013-09-16 14:11 ` Metzger, Markus T
2013-08-18 19:16 ` [patch v4 21/24] record-btrace: show trace from enable location Jan Kratochvil
2013-07-03 9:15 ` [patch v4 12/24] frame, backtrace: allow targets to supply a frame unwinder Markus Metzger
2013-08-18 19:14 ` Jan Kratochvil
2013-08-18 19:04 ` [patch v4 00/24] record-btrace: reverse 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=20130927135521.GB13376@host2.jankratochvil.net \
--to=jan.kratochvil@redhat.com \
--cc=gdb-patches@sourceware.org \
--cc=markus.t.metzger@intel.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