Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
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,

  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