gdb: introduce explicit outer frame id kind
authorSimon Marchi <simon.marchi@efficios.com>
Mon, 31 Aug 2020 17:23:12 +0000 (13:23 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Mon, 31 Aug 2020 17:23:12 +0000 (13:23 -0400)
In the following patch, we'll need to easily differentiate the frame_id
of the outer frame (or the frame id of a frame inlined into the outer
frame) from a simply invalid frame id.

Currently, the frame id of the outer frame has `stack_status` set to
FID_STACK_INVALID plus special_addr_p set.  A frame inlined into the
outer frame would also have `artificial_depth` set to greater than one.
That makes the job of differntiating the frame id of the outer frame (or a
frame inlined into the outer frame) cumbersome.

To make it easier, give the outer frame id its own frame_id_stack_status
enum value.  outer_frame_id then becomes very similar to
sentinel_frame_id, another "special" frame id value.

In frame_id_p, we don't need a special case for the outer frame id, as
it's no long a special case of FID_STACK_INVALID.  Same goes for
frame_id_eq.

So in the end, FID_STACK_OUTER isn't even used (except in
fprint_frame_id).  But that's expected: all the times we wanted to
identify an outer frame was to differentiate it from an otherwise
invalid frame.  Since their frame_id_stack_status value is different
now, that is done naturally.

gdb/ChangeLog:

* frame.h (enum frame_id_stack_status) <FID_STACK_OUTER>: New.
* frame.c (fprint_frame_id): Handle FID_STACK_OUTER.
(outer_frame_id): Use FID_STACK_OUTER instead of
FID_STACK_INVALID.
(frame_id_p): Don't check for outer_frame_id.

Change-Id: I654e7f936349debc4f04f7f684b15e71a0c37619

gdb/ChangeLog
gdb/frame.c
gdb/frame.h

index a982d917057a80bd1e38a31b7caf1f01f6d7a542..3a0d371a87cca059ed5c5074c275cba210e53f28 100644 (file)
@@ -1,3 +1,11 @@
+2020-08-31  Simon Marchi  <simon.marchi@efficios.com>
+
+       * frame.h (enum frame_id_stack_status) <FID_STACK_OUTER>: New.
+       * frame.c (fprint_frame_id): Handle FID_STACK_OUTER.
+       (outer_frame_id): Use FID_STACK_OUTER instead of
+       FID_STACK_INVALID.
+       (frame_id_p): Don't check for outer_frame_id.
+
 2020-08-31  Simon Marchi  <simon.marchi@efficios.com>
 
        * frame-unwind.c (frame_unwind_got_optimized): Don't set
index ccaf97dc7e9112aa2658055fa58ff437c6ddbef3..54f4c613c9e870d857e3c9c01bc9ac6b7f738360 100644 (file)
@@ -396,8 +396,11 @@ fprint_frame_id (struct ui_file *file, struct frame_id id)
     fprintf_unfiltered (file, "stack=<unavailable>");
   else if (id.stack_status == FID_STACK_SENTINEL)
     fprintf_unfiltered (file, "stack=<sentinel>");
+  else if (id.stack_status == FID_STACK_OUTER)
+    fprintf_unfiltered (file, "stack=<outer>");
   else
     fprintf_unfiltered (file, "stack=%s", hex_string (id.stack_addr));
+
   fprintf_unfiltered (file, ",");
 
   fprint_field (file, "code", id.code_addr_p, id.code_addr);
@@ -672,7 +675,7 @@ frame_unwind_caller_id (struct frame_info *next_frame)
 
 const struct frame_id null_frame_id = { 0 }; /* All zeros.  */
 const struct frame_id sentinel_frame_id = { 0, 0, 0, FID_STACK_SENTINEL, 0, 1, 0 };
-const struct frame_id outer_frame_id = { 0, 0, 0, FID_STACK_INVALID, 0, 1, 0 };
+const struct frame_id outer_frame_id = { 0, 0, 0, FID_STACK_OUTER, 0, 1, 0 };
 
 struct frame_id
 frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr,
@@ -746,10 +749,6 @@ frame_id_p (frame_id l)
   /* The frame is valid iff it has a valid stack address.  */
   bool p = l.stack_status != FID_STACK_INVALID;
 
-  /* outer_frame_id is also valid.  */
-  if (!p && memcmp (&l, &outer_frame_id, sizeof (l)) == 0)
-    p = true;
-
   if (frame_debug)
     {
       fprintf_unfiltered (gdb_stdlog, "{ frame_id_p (l=");
@@ -774,15 +773,7 @@ frame_id_eq (frame_id l, frame_id r)
 {
   bool eq;
 
-  if (l.stack_status == FID_STACK_INVALID && l.special_addr_p
-      && r.stack_status == FID_STACK_INVALID && r.special_addr_p)
-    /* The outermost frame marker is equal to itself.  This is the
-       dodgy thing about outer_frame_id, since between execution steps
-       we might step into another function - from which we can't
-       unwind either.  More thought required to get rid of
-       outer_frame_id.  */
-    eq = true;
-  else if (l.stack_status == FID_STACK_INVALID
+  if (l.stack_status == FID_STACK_INVALID
           || r.stack_status == FID_STACK_INVALID)
     /* Like a NaN, if either ID is invalid, the result is false.
        Note that a frame ID is invalid iff it is the null frame ID.  */
index 1c6afad1ae954e72c50725aeb1f363339eba10cd..3ceb7b32effaf9c7cc12905e67af2a6100bb2736 100644 (file)
@@ -85,8 +85,7 @@ struct frame_print_options;
 
 enum frame_id_stack_status
 {
-  /* Stack address is invalid.  E.g., this frame is the outermost
-     (i.e., _start), and the stack hasn't been setup yet.  */
+  /* Stack address is invalid.  */
   FID_STACK_INVALID = 0,
 
   /* Stack address is valid, and is found in the stack_addr field.  */
@@ -95,6 +94,12 @@ enum frame_id_stack_status
   /* Sentinel frame.  */
   FID_STACK_SENTINEL = 2,
 
+  /* Outer frame.  Since a frame's stack address is typically defined as the
+     value the stack pointer had prior to the activation of the frame, an outer
+     frame doesn't have a stack address.  The frame ids of frames inlined in the
+     outer frame are also of this type.  */
+  FID_STACK_OUTER = 3,
+
   /* Stack address is unavailable.  I.e., there's a valid stack, but
      we don't know where it is (because memory or registers we'd
      compute it from were not collected).  */