Blame SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-2of7.patch

2c2fa1
  NOTE: The testcase part of this patch has been removed.
2c2fa1
2c2fa1
commit 5ce0145de764dc9c6e92daf2f843fa6e496c49d0
2c2fa1
Author: Pedro Alves <palves@redhat.com>
2c2fa1
Date:   Tue Dec 17 20:47:36 2013 +0000
2c2fa1
2c2fa1
    "tfind" across unavailable-stack frames.
2c2fa1
    
2c2fa1
    Like when stepping, the current stack frame location is expected to be
2c2fa1
    printed as result of tfind command, if that results in moving to a
2c2fa1
    different function.  In tfind_1 we see:
2c2fa1
    
2c2fa1
      if (from_tty
2c2fa1
          && (has_stack_frames () || traceframe_number >= 0))
2c2fa1
        {
2c2fa1
          enum print_what print_what;
2c2fa1
    
2c2fa1
          /* NOTE: in imitation of the step command, try to determine
2c2fa1
             whether we have made a transition from one function to
2c2fa1
             another.  If so, we'll print the "stack frame" (ie. the new
2c2fa1
             function and it's arguments) -- otherwise we'll just show the
2c2fa1
             new source line.  */
2c2fa1
    
2c2fa1
          if (frame_id_eq (old_frame_id,
2c2fa1
                           get_frame_id (get_current_frame ())))
2c2fa1
            print_what = SRC_LINE;
2c2fa1
          else
2c2fa1
            print_what = SRC_AND_LOC;
2c2fa1
    
2c2fa1
          print_stack_frame (get_selected_frame (NULL), 1, print_what, 1);
2c2fa1
          do_displays ();
2c2fa1
        }
2c2fa1
    
2c2fa1
    However, when we haven't collected any registers in the tracepoint
2c2fa1
    (collect $regs), that doesn't actually work:
2c2fa1
    
2c2fa1
     (gdb) tstart
2c2fa1
     (gdb) info tracepoints
2c2fa1
     Num     Type           Disp Enb Address    What
2c2fa1
     1       tracepoint     keep y   0x080483b7 in func0
2c2fa1
                                                at ../.././../git/gdb/testsuite/gdb.trace/circ.c:28
2c2fa1
             collect testload
2c2fa1
         installed on target
2c2fa1
     2       tracepoint     keep y   0x080483bc in func1
2c2fa1
                                                at ../.././../git/gdb/testsuite/gdb.trace/circ.c:32
2c2fa1
             collect testload
2c2fa1
         installed on target
2c2fa1
     (gdb) c
2c2fa1
     Continuing.
2c2fa1
    
2c2fa1
     Breakpoint 3, end () at ../.././../git/gdb/testsuite/gdb.trace/circ.c:72
2c2fa1
     72    }
2c2fa1
     (gdb) tstop
2c2fa1
     (gdb) tfind start
2c2fa1
     Found trace frame 0, tracepoint 1
2c2fa1
     #0  func0 () at ../.././../git/gdb/testsuite/gdb.trace/circ.c:28
2c2fa1
     28    }
2c2fa1
     (gdb) tfind
2c2fa1
     Found trace frame 1, tracepoint 2
2c2fa1
     32    }
2c2fa1
     (gdb)
2c2fa1
    
2c2fa1
    When we don't have info about the stack available
2c2fa1
    (UNWIND_UNAVAILABLE), frames end up with outer_frame_id as frame ID.
2c2fa1
    And in the scenario above, the issue is that both frames before and
2c2fa1
    after the second tfind (the frames for func0 an func1) have the same
2c2fa1
    id (outer_frame_id), so the frame_id_eq check returns false, even
2c2fa1
    though the frames were of different functions.  GDB knows that,
2c2fa1
    because the PC is inferred from the tracepoint's address, even if no
2c2fa1
    registers were collected.
2c2fa1
    
2c2fa1
    To fix this, this patch adds support for frame ids with a valid code
2c2fa1
    address, but <unavailable> stack address, and then makes the unwinders
2c2fa1
    use that instead of the catch-all outer_frame_id for such frames.  The
2c2fa1
    frame_id_eq check in tfind_1 then automatically does the right thing
2c2fa1
    as expected.
2c2fa1
    
2c2fa1
    I tested with --directory=gdb.trace/ , before/after the patch, and
2c2fa1
    compared the resulting gdb.logs, then adjusted the tests to expect the
2c2fa1
    extra output that came out.  Turns out that was only circ.exp, the
2c2fa1
    original test that actually brought this issue to light.
2c2fa1
    
2c2fa1
    Tested on x86_64 Fedora 17, native and gdbserver.
2c2fa1
    
2c2fa1
    gdb/
2c2fa1
    2013-12-17  Pedro Alves  <palves@redhat.com>
2c2fa1
    
2c2fa1
    	* frame.h (enum frame_id_stack_status): New enum.
2c2fa1
    	(struct frame_id) <stack_addr>: Adjust comment.
2c2fa1
    	<stack_addr_p>: Delete field, replaced with ...
2c2fa1
    	<stack_status>: ... this new field.
2c2fa1
    	(frame_id_build_unavailable_stack): Declare.
2c2fa1
    	* frame.c (frame_addr_hash, fprint_field, outer_frame_id)
2c2fa1
    	(frame_id_build_special): Adjust.
2c2fa1
    	(frame_id_build_unavailable_stack): New function.
2c2fa1
    	(frame_id_build, frame_id_build_wild): Adjust.
2c2fa1
    	(frame_id_p, frame_id_eq, frame_id_inner): Adjust to take into
2c2fa1
    	account frames with unavailable stack.
2c2fa1
    
2c2fa1
    	* amd64-tdep.c (amd64_frame_this_id)
2c2fa1
    	(amd64_sigtramp_frame_this_id, amd64_epilogue_frame_this_id): Use
2c2fa1
    	frame_id_build_unavailable_stack.
2c2fa1
    	* dwarf2-frame.c (dwarf2_frame_this_id): Likewise.
2c2fa1
    	* i386-tdep.c (i386_frame_this_id, i386_epilogue_frame_this_id)
2c2fa1
    	(i386_sigtramp_frame_this_id):  Likewise.
2c2fa1
    
2c2fa1
    gdb/testsuite/
2c2fa1
    2013-12-17  Pedro Alves  <palves@redhat.com>
2c2fa1
    
2c2fa1
    	* gdb.trace/circ.exp: Expect frame info to be printed when
2c2fa1
    	switching between frames with unavailable stack, but different
2c2fa1
    	functions.
2c2fa1
2c2fa1
Index: gdb-7.6.1/gdb/amd64-tdep.c
2c2fa1
===================================================================
2c2fa1
--- gdb-7.6.1.orig/gdb/amd64-tdep.c
2c2fa1
+++ gdb-7.6.1/gdb/amd64-tdep.c
2c2fa1
@@ -2403,15 +2403,16 @@ amd64_frame_this_id (struct frame_info *
2c2fa1
   struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
2c2fa1
 
2c2fa1
   if (!cache->base_p)
2c2fa1
-    return;
2c2fa1
-
2c2fa1
-  /* This marks the outermost frame.  */
2c2fa1
-  if (cache->base == 0)
2c2fa1
-    return;
2c2fa1
-
2c2fa1
-  /* Detect OS dependent outermost frames; such as `clone'.  */
2c2fa1
-  if (tdep->outermost_frame_p && tdep->outermost_frame_p (this_frame))
2c2fa1
-    return;
2c2fa1
+    (*this_id) = frame_id_build_unavailable_stack (cache->pc);
2c2fa1
+  else if (cache->base == 0)
2c2fa1
+    {
2c2fa1
+      /* This marks the outermost frame.  */
2c2fa1
+      return;
2c2fa1
+    }
2c2fa1
+  else
2c2fa1
+    /* Detect OS dependent outermost frames; such as `clone'.  */
2c2fa1
+    if (tdep->outermost_frame_p && tdep->outermost_frame_p (this_frame))
2c2fa1
+      return;
2c2fa1
 
2c2fa1
   (*this_id) = frame_id_build (cache->base + 16, cache->pc);
2c2fa1
 }
2c2fa1
@@ -2528,9 +2529,14 @@ amd64_sigtramp_frame_this_id (struct fra
2c2fa1
     amd64_sigtramp_frame_cache (this_frame, this_cache);
2c2fa1
 
2c2fa1
   if (!cache->base_p)
2c2fa1
-    return;
2c2fa1
-
2c2fa1
-  (*this_id) = frame_id_build (cache->base + 16, get_frame_pc (this_frame));
2c2fa1
+    (*this_id) = frame_id_build_unavailable_stack (get_frame_pc (this_frame));
2c2fa1
+  else if (cache->base == 0)
2c2fa1
+    {
2c2fa1
+      /* This marks the outermost frame.  */
2c2fa1
+      return;
2c2fa1
+    }
2c2fa1
+  else
2c2fa1
+    (*this_id) = frame_id_build (cache->base + 16, get_frame_pc (this_frame));
2c2fa1
 }
2c2fa1
 
2c2fa1
 static struct value *
2c2fa1
@@ -2699,9 +2705,9 @@ amd64_epilogue_frame_this_id (struct fra
2c2fa1
 							       this_cache);
2c2fa1
 
2c2fa1
   if (!cache->base_p)
2c2fa1
-    return;
2c2fa1
-
2c2fa1
-  (*this_id) = frame_id_build (cache->base + 8, cache->pc);
2c2fa1
+    (*this_id) = frame_id_build_unavailable_stack (cache->pc);
2c2fa1
+  else
2c2fa1
+    (*this_id) = frame_id_build (cache->base + 8, cache->pc);
2c2fa1
 }
2c2fa1
 
2c2fa1
 static const struct frame_unwind amd64_epilogue_frame_unwind =
2c2fa1
Index: gdb-7.6.1/gdb/dwarf2-frame.c
2c2fa1
===================================================================
2c2fa1
--- gdb-7.6.1.orig/gdb/dwarf2-frame.c
2c2fa1
+++ gdb-7.6.1/gdb/dwarf2-frame.c
2c2fa1
@@ -1265,12 +1265,11 @@ dwarf2_frame_this_id (struct frame_info
2c2fa1
     dwarf2_frame_cache (this_frame, this_cache);
2c2fa1
 
2c2fa1
   if (cache->unavailable_retaddr)
2c2fa1
+    (*this_id) = frame_id_build_unavailable_stack (get_frame_func (this_frame));
2c2fa1
+  else if (cache->undefined_retaddr)
2c2fa1
     return;
2c2fa1
-
2c2fa1
-  if (cache->undefined_retaddr)
2c2fa1
-    return;
2c2fa1
-
2c2fa1
-  (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame));
2c2fa1
+  else
2c2fa1
+    (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame));
2c2fa1
 }
2c2fa1
 
2c2fa1
 static struct value *
2c2fa1
Index: gdb-7.6.1/gdb/frame.c
2c2fa1
===================================================================
2c2fa1
--- gdb-7.6.1.orig/gdb/frame.c
2c2fa1
+++ gdb-7.6.1/gdb/frame.c
2c2fa1
@@ -147,10 +147,11 @@ frame_addr_hash (const void *ap)
2c2fa1
   const struct frame_id f_id = frame->this_id.value;
2c2fa1
   hashval_t hash = 0;
2c2fa1
 
2c2fa1
-  gdb_assert (f_id.stack_addr_p || f_id.code_addr_p
2c2fa1
+  gdb_assert (f_id.stack_status != FID_STACK_INVALID
2c2fa1
+	      || f_id.code_addr_p
2c2fa1
 	      || f_id.special_addr_p);
2c2fa1
 
2c2fa1
-  if (f_id.stack_addr_p)
2c2fa1
+  if (f_id.stack_status == FID_STACK_VALID)
2c2fa1
     hash = iterative_hash (&f_id.stack_addr,
2c2fa1
 			   sizeof (f_id.stack_addr), hash);
2c2fa1
   if (f_id.code_addr_p)
2c2fa1
@@ -290,13 +291,23 @@ void
2c2fa1
 fprint_frame_id (struct ui_file *file, struct frame_id id)
2c2fa1
 {
2c2fa1
   fprintf_unfiltered (file, "{");
2c2fa1
-  fprint_field (file, "stack", id.stack_addr_p, id.stack_addr);
2c2fa1
+
2c2fa1
+  if (id.stack_status == FID_STACK_INVALID)
2c2fa1
+    fprintf_unfiltered (file, "!stack");
2c2fa1
+  else if (id.stack_status == FID_STACK_UNAVAILABLE)
2c2fa1
+    fprintf_unfiltered (file, "stack=<unavailable>");
2c2fa1
+  else
2c2fa1
+    fprintf_unfiltered (file, "stack=%s", hex_string (id.stack_addr));
2c2fa1
   fprintf_unfiltered (file, ",");
2c2fa1
+
2c2fa1
   fprint_field (file, "code", id.code_addr_p, id.code_addr);
2c2fa1
   fprintf_unfiltered (file, ",");
2c2fa1
+
2c2fa1
   fprint_field (file, "special", id.special_addr_p, id.special_addr);
2c2fa1
+
2c2fa1
   if (id.artificial_depth)
2c2fa1
     fprintf_unfiltered (file, ",artificial=%d", id.artificial_depth);
2c2fa1
+
2c2fa1
   fprintf_unfiltered (file, "}");
2c2fa1
 }
2c2fa1
 
2c2fa1
@@ -446,7 +457,7 @@ frame_unwind_caller_id (struct frame_inf
2c2fa1
 }
2c2fa1
 
2c2fa1
 const struct frame_id null_frame_id; /* All zeros.  */
2c2fa1
-const struct frame_id outer_frame_id = { 0, 0, 0, 0, 0, 1, 0 };
2c2fa1
+const struct frame_id outer_frame_id = { 0, 0, 0, FID_STACK_INVALID, 0, 1, 0 };
2c2fa1
 
2c2fa1
 struct frame_id
2c2fa1
 frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr,
2c2fa1
@@ -455,7 +466,7 @@ frame_id_build_special (CORE_ADDR stack_
2c2fa1
   struct frame_id id = null_frame_id;
2c2fa1
 
2c2fa1
   id.stack_addr = stack_addr;
2c2fa1
-  id.stack_addr_p = 1;
2c2fa1
+  id.stack_status = FID_STACK_VALID;
2c2fa1
   id.code_addr = code_addr;
2c2fa1
   id.code_addr_p = 1;
2c2fa1
   id.special_addr = special_addr;
2c2fa1
@@ -463,13 +474,26 @@ frame_id_build_special (CORE_ADDR stack_
2c2fa1
   return id;
2c2fa1
 }
2c2fa1
 
2c2fa1
+/* See frame.h.  */
2c2fa1
+
2c2fa1
+struct frame_id
2c2fa1
+frame_id_build_unavailable_stack (CORE_ADDR code_addr)
2c2fa1
+{
2c2fa1
+  struct frame_id id = null_frame_id;
2c2fa1
+
2c2fa1
+  id.stack_status = FID_STACK_UNAVAILABLE;
2c2fa1
+  id.code_addr = code_addr;
2c2fa1
+  id.code_addr_p = 1;
2c2fa1
+  return id;
2c2fa1
+}
2c2fa1
+
2c2fa1
 struct frame_id
2c2fa1
 frame_id_build (CORE_ADDR stack_addr, CORE_ADDR code_addr)
2c2fa1
 {
2c2fa1
   struct frame_id id = null_frame_id;
2c2fa1
 
2c2fa1
   id.stack_addr = stack_addr;
2c2fa1
-  id.stack_addr_p = 1;
2c2fa1
+  id.stack_status = FID_STACK_VALID;
2c2fa1
   id.code_addr = code_addr;
2c2fa1
   id.code_addr_p = 1;
2c2fa1
   return id;
2c2fa1
@@ -481,7 +505,7 @@ frame_id_build_wild (CORE_ADDR stack_add
2c2fa1
   struct frame_id id = null_frame_id;
2c2fa1
 
2c2fa1
   id.stack_addr = stack_addr;
2c2fa1
-  id.stack_addr_p = 1;
2c2fa1
+  id.stack_status = FID_STACK_VALID;
2c2fa1
   return id;
2c2fa1
 }
2c2fa1
 
2c2fa1
@@ -491,7 +515,7 @@ frame_id_p (struct frame_id l)
2c2fa1
   int p;
2c2fa1
 
2c2fa1
   /* The frame is valid iff it has a valid stack address.  */
2c2fa1
-  p = l.stack_addr_p;
2c2fa1
+  p = l.stack_status != FID_STACK_INVALID;
2c2fa1
   /* outer_frame_id is also valid.  */
2c2fa1
   if (!p && memcmp (&l, &outer_frame_id, sizeof (l)) == 0)
2c2fa1
     p = 1;
2c2fa1
@@ -518,19 +542,20 @@ frame_id_eq (struct frame_id l, struct f
2c2fa1
 {
2c2fa1
   int eq;
2c2fa1
 
2c2fa1
-  if (!l.stack_addr_p && l.special_addr_p
2c2fa1
-      && !r.stack_addr_p && r.special_addr_p)
2c2fa1
+  if (l.stack_status == FID_STACK_INVALID && l.special_addr_p
2c2fa1
+      && r.stack_status == FID_STACK_INVALID && r.special_addr_p)
2c2fa1
     /* The outermost frame marker is equal to itself.  This is the
2c2fa1
        dodgy thing about outer_frame_id, since between execution steps
2c2fa1
        we might step into another function - from which we can't
2c2fa1
        unwind either.  More thought required to get rid of
2c2fa1
        outer_frame_id.  */
2c2fa1
     eq = 1;
2c2fa1
-  else if (!l.stack_addr_p || !r.stack_addr_p)
2c2fa1
+  else if (l.stack_status == FID_STACK_INVALID
2c2fa1
+	   || r.stack_status == FID_STACK_INVALID)
2c2fa1
     /* Like a NaN, if either ID is invalid, the result is false.
2c2fa1
        Note that a frame ID is invalid iff it is the null frame ID.  */
2c2fa1
     eq = 0;
2c2fa1
-  else if (l.stack_addr != r.stack_addr)
2c2fa1
+  else if (l.stack_status != r.stack_status || l.stack_addr != r.stack_addr)
2c2fa1
     /* If .stack addresses are different, the frames are different.  */
2c2fa1
     eq = 0;
2c2fa1
   else if (l.code_addr_p && r.code_addr_p && l.code_addr != r.code_addr)
2c2fa1
@@ -597,8 +622,9 @@ frame_id_inner (struct gdbarch *gdbarch,
2c2fa1
 {
2c2fa1
   int inner;
2c2fa1
 
2c2fa1
-  if (!l.stack_addr_p || !r.stack_addr_p)
2c2fa1
-    /* Like NaN, any operation involving an invalid ID always fails.  */
2c2fa1
+  if (l.stack_status != FID_STACK_VALID || r.stack_status != FID_STACK_VALID)
2c2fa1
+    /* Like NaN, any operation involving an invalid ID always fails.
2c2fa1
+       Likewise if either ID has an unavailable stack address.  */
2c2fa1
     inner = 0;
2c2fa1
   else if (l.artificial_depth > r.artificial_depth
2c2fa1
 	   && l.stack_addr == r.stack_addr
2c2fa1
Index: gdb-7.6.1/gdb/frame.h
2c2fa1
===================================================================
2c2fa1
--- gdb-7.6.1.orig/gdb/frame.h
2c2fa1
+++ gdb-7.6.1/gdb/frame.h
2c2fa1
@@ -76,6 +76,23 @@ struct block;
2c2fa1
 struct gdbarch;
2c2fa1
 struct ui_file;
2c2fa1
 
2c2fa1
+/* Status of a given frame's stack.  */
2c2fa1
+
2c2fa1
+enum frame_id_stack_status
2c2fa1
+{
2c2fa1
+  /* Stack address is invalid.  E.g., this frame is the outermost
2c2fa1
+     (i.e., _start), and the stack hasn't been setup yet.  */
2c2fa1
+  FID_STACK_INVALID = 0,
2c2fa1
+
2c2fa1
+  /* Stack address is valid, and is found in the stack_addr field.  */
2c2fa1
+  FID_STACK_VALID = 1,
2c2fa1
+
2c2fa1
+  /* Stack address is unavailable.  I.e., there's a valid stack, but
2c2fa1
+     we don't know where it is (because memory or registers we'd
2c2fa1
+     compute it from were not collected).  */
2c2fa1
+  FID_STACK_UNAVAILABLE = -1
2c2fa1
+};
2c2fa1
+
2c2fa1
 /* The frame object.  */
2c2fa1
 
2c2fa1
 struct frame_info;
2c2fa1
@@ -97,8 +114,9 @@ struct frame_id
2c2fa1
      function pointer register or stack pointer register.  They are
2c2fa1
      wrong.
2c2fa1
 
2c2fa1
-     This field is valid only if stack_addr_p is true.  Otherwise, this
2c2fa1
-     frame represents the null frame.  */
2c2fa1
+     This field is valid only if frame_id.stack_status is
2c2fa1
+     FID_STACK_VALID.  It will be 0 for other
2c2fa1
+     FID_STACK_... statuses.  */
2c2fa1
   CORE_ADDR stack_addr;
2c2fa1
 
2c2fa1
   /* The frame's code address.  This shall be constant through out the
2c2fa1
@@ -129,7 +147,7 @@ struct frame_id
2c2fa1
   CORE_ADDR special_addr;
2c2fa1
 
2c2fa1
   /* Flags to indicate the above fields have valid contents.  */
2c2fa1
-  unsigned int stack_addr_p : 1;
2c2fa1
+  ENUM_BITFIELD(frame_id_stack_status) stack_status : 2;
2c2fa1
   unsigned int code_addr_p : 1;
2c2fa1
   unsigned int special_addr_p : 1;
2c2fa1
 
2c2fa1
@@ -169,6 +187,12 @@ extern struct frame_id frame_id_build_sp
2c2fa1
 					       CORE_ADDR code_addr,
2c2fa1
 					       CORE_ADDR special_addr);
2c2fa1
 
2c2fa1
+/* Construct a frame ID representing a frame where the stack address
2c2fa1
+   exists, but is unavailable.  CODE_ADDR is the frame's constant code
2c2fa1
+   address (typically the entry point).  The special identifier
2c2fa1
+   address is set to indicate a wild card.  */
2c2fa1
+extern struct frame_id frame_id_build_unavailable_stack (CORE_ADDR code_addr);
2c2fa1
+
2c2fa1
 /* Construct a wild card frame ID.  The parameter is the frame's constant
2c2fa1
    stack address (typically the outer-bound).  The code address as well
2c2fa1
    as the special identifier address are set to indicate wild cards.  */
2c2fa1
Index: gdb-7.6.1/gdb/i386-tdep.c
2c2fa1
===================================================================
2c2fa1
--- gdb-7.6.1.orig/gdb/i386-tdep.c
2c2fa1
+++ gdb-7.6.1/gdb/i386-tdep.c
2c2fa1
@@ -1846,12 +1846,17 @@ i386_frame_this_id (struct frame_info *t
2c2fa1
 {
2c2fa1
   struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
2c2fa1
 
2c2fa1
-  /* This marks the outermost frame.  */
2c2fa1
-  if (cache->base == 0)
2c2fa1
-    return;
2c2fa1
-
2c2fa1
-  /* See the end of i386_push_dummy_call.  */
2c2fa1
-  (*this_id) = frame_id_build (cache->base + 8, cache->pc);
2c2fa1
+  if (!cache->base_p)
2c2fa1
+    (*this_id) = frame_id_build_unavailable_stack (cache->pc);
2c2fa1
+  else if (cache->base == 0)
2c2fa1
+    {
2c2fa1
+      /* This marks the outermost frame.  */
2c2fa1
+    }
2c2fa1
+  else
2c2fa1
+    {
2c2fa1
+      /* See the end of i386_push_dummy_call.  */
2c2fa1
+      (*this_id) = frame_id_build (cache->base + 8, cache->pc);
2c2fa1
+    }
2c2fa1
 }
2c2fa1
 
2c2fa1
 static enum unwind_stop_reason
2c2fa1
@@ -2032,9 +2037,9 @@ i386_epilogue_frame_this_id (struct fram
2c2fa1
     i386_epilogue_frame_cache (this_frame, this_cache);
2c2fa1
 
2c2fa1
   if (!cache->base_p)
2c2fa1
-    return;
2c2fa1
-
2c2fa1
-  (*this_id) = frame_id_build (cache->base + 8, cache->pc);
2c2fa1
+    (*this_id) = frame_id_build_unavailable_stack (cache->pc);
2c2fa1
+  else
2c2fa1
+    (*this_id) = frame_id_build (cache->base + 8, cache->pc);
2c2fa1
 }
2c2fa1
 
2c2fa1
 static struct value *
2c2fa1
@@ -2226,10 +2231,12 @@ i386_sigtramp_frame_this_id (struct fram
2c2fa1
     i386_sigtramp_frame_cache (this_frame, this_cache);
2c2fa1
 
2c2fa1
   if (!cache->base_p)
2c2fa1
-    return;
2c2fa1
-
2c2fa1
-  /* See the end of i386_push_dummy_call.  */
2c2fa1
-  (*this_id) = frame_id_build (cache->base + 8, get_frame_pc (this_frame));
2c2fa1
+    (*this_id) = frame_id_build_unavailable_stack (get_frame_pc (this_frame));
2c2fa1
+  else
2c2fa1
+    {
2c2fa1
+      /* See the end of i386_push_dummy_call.  */
2c2fa1
+      (*this_id) = frame_id_build (cache->base + 8, get_frame_pc (this_frame));
2c2fa1
+    }
2c2fa1
 }
2c2fa1
 
2c2fa1
 static struct value *