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