GDB/MI: identifying changed frames

Jan Vrany <[email protected]>
Newsgroups gmane.comp.gdb.devel
Message-ID <[email protected]>
Hi there, 

I'm using GDB/MI and -stack-list-frames to retrieve a backtrace 
at given point for given thread. Now I'd also like to know, what 
frames are "new" compared to previous backtrace (retrieved earlier).

It looks to me that this is not easy with data currently exposed by the
MI interface. frame's "addr" field is a PC, so single-stepping changes
it. Comparing function name and source file seems to be too unreliable.
   

What would make things a lot easier would be if "frame" records in 
-stack-list-frames output would contain an "id" field with some value
solely for the purpose of comparing. 

After digging through the code, I found out that there's a 
struct frame_id and the comments around suggest that this just
what I need. I modified GDB to output a textual 
representation of it. It appears to work, at least in simple
cases I tried so far. See the patch below. 

Obviously, I have no idea what I'm doing so I'd appreciate any 
comments on this. Is there any other (better) way to match frames 
from two -stack-list-frames? If not, is using frame_id data to 
outout an "id" field the way to go? Also, do you think it would make
sense to integrate it (after polishing it, of course)?

Best, Jan

----
From 089751824fc1bb26f309a582b58095d6dfbd2f14 Mon Sep 17 00:00:00 2001
From: Jan Vrany <[email protected]>
Date: Wed, 31 Jan 2018 19:31:05 +0000
Subject: [PATCH] GDB/MI: add new "id" field to "frame" records in
results of
 -stack-list-variables.

This field can be used by GDB/MI clients to tell "new" frames from
"old" ones
between two invocations of -stack-list-frames. The value of the "id"
field is
a textual representation of struct frame_id.
---
 gdb/stack.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/gdb/stack.c b/gdb/stack.c
index 9993ae654a..3e9e98543f 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -771,6 +771,22 @@ do_gdb_disassembly (struct gdbarch *gdbarch,
   END_CATCH
 }
 
+/* Print textual representation of a frame id of a FRAME as MI record
field. 
+   
+   Used in "-stack-list-frames" */
+
+static void
+print_frame_id(struct frame_info *frame) 
+{
+  struct frame_id id = get_frame_id(frame);
+  struct ui_out *uiout = current_uiout;
+  uiout->field_fmt("id", 
+                    "id%s_%s_%s",
+                    id.stack_status == FID_STACK_VALID ?
hex_string(id.stack_addr) : "NV",
+                    id.code_addr_p ? hex_string(id.code_addr) : "NV",
+                    id.special_addr_p ? hex_string(id.special_addr) :
"NV");
+}
+
 /* Print information about frame FRAME.  The output is format
according
    to PRINT_LEVEL and PRINT_WHAT and PRINT_ARGS.  The meaning of
    PRINT_WHAT is:
@@ -801,6 +817,11 @@ print_frame_info (struct frame_info *frame, int
print_level,
       annotate_frame_begin (print_level ? frame_relative_level (frame)
: 0,
 			    gdbarch, get_frame_pc (frame));
 
+      if (uiout->is_mi_like_p ())
+        {
+          print_frame_id(frame);
+        }
+
       /* Do this regardless of SOURCE because we don't have any source
          to list for this frame.  */
       if (print_level)
@@ -1153,6 +1174,11 @@ print_frame (struct frame_info *frame, int
print_level,
   {
     ui_out_emit_tuple tuple_emitter (uiout, "frame");
 
+    if (uiout->is_mi_like_p ())
+      {
+        print_frame_id(frame);
+      }
+
     if (print_level)
       {
 	uiout->text ("#");
-- 
2.15.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.