GDB (API)
/home/stan/gdb/src/gdb/inline-frame.c
Go to the documentation of this file.
00001 /* Inline frame unwinder for GDB.
00002 
00003    Copyright (C) 2008-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "inline-frame.h"
00022 #include "addrmap.h"
00023 #include "block.h"
00024 #include "frame-unwind.h"
00025 #include "inferior.h"
00026 #include "regcache.h"
00027 #include "symtab.h"
00028 #include "vec.h"
00029 
00030 #include "gdb_assert.h"
00031 
00032 /* We need to save a few variables for every thread stopped at the
00033    virtual call site of an inlined function.  If there was always a
00034    "struct thread_info", we could hang it off that; in the mean time,
00035    keep our own list.  */
00036 struct inline_state
00037 {
00038   /* The thread this data relates to.  It should be a currently
00039      stopped thread; we assume thread IDs never change while the
00040      thread is stopped.  */
00041   ptid_t ptid;
00042 
00043   /* The number of inlined functions we are skipping.  Each of these
00044      functions can be stepped in to.  */
00045   int skipped_frames;
00046 
00047   /* Only valid if SKIPPED_FRAMES is non-zero.  This is the PC used
00048      when calculating SKIPPED_FRAMES; used to check whether we have
00049      moved to a new location by user request.  If so, we invalidate
00050      any skipped frames.  */
00051   CORE_ADDR saved_pc;
00052 
00053   /* Only valid if SKIPPED_FRAMES is non-zero.  This is the symbol
00054      of the outermost skipped inline function.  It's used to find the
00055      call site of the current frame.  */
00056   struct symbol *skipped_symbol;
00057 };
00058 
00059 typedef struct inline_state inline_state_s;
00060 DEF_VEC_O(inline_state_s);
00061 
00062 static VEC(inline_state_s) *inline_states;
00063 
00064 /* Locate saved inlined frame state for PTID, if it exists
00065    and is valid.  */
00066 
00067 static struct inline_state *
00068 find_inline_frame_state (ptid_t ptid)
00069 {
00070   struct inline_state *state;
00071   int ix;
00072 
00073   for (ix = 0; VEC_iterate (inline_state_s, inline_states, ix, state); ix++)
00074     {
00075       if (ptid_equal (state->ptid, ptid))
00076         {
00077           struct regcache *regcache = get_thread_regcache (ptid);
00078           CORE_ADDR current_pc = regcache_read_pc (regcache);
00079 
00080           if (current_pc != state->saved_pc)
00081             {
00082               /* PC has changed - this context is invalid.  Use the
00083                  default behavior.  */
00084               VEC_unordered_remove (inline_state_s, inline_states, ix);
00085               return NULL;
00086             }
00087           else
00088             return state;
00089         }
00090     }
00091 
00092   return NULL;
00093 }
00094 
00095 /* Allocate saved inlined frame state for PTID.  */
00096 
00097 static struct inline_state *
00098 allocate_inline_frame_state (ptid_t ptid)
00099 {
00100   struct inline_state *state;
00101 
00102   state = VEC_safe_push (inline_state_s, inline_states, NULL);
00103   memset (state, 0, sizeof (*state));
00104   state->ptid = ptid;
00105 
00106   return state;
00107 }
00108 
00109 /* Forget about any hidden inlined functions in PTID, which is new or
00110    about to be resumed.  PTID may be minus_one_ptid (all processes)
00111    or a PID (all threads in this process).  */
00112 
00113 void
00114 clear_inline_frame_state (ptid_t ptid)
00115 {
00116   struct inline_state *state;
00117   int ix;
00118 
00119   if (ptid_equal (ptid, minus_one_ptid))
00120     {
00121       VEC_free (inline_state_s, inline_states);
00122       return;
00123     }
00124 
00125   if (ptid_is_pid (ptid))
00126     {
00127       VEC (inline_state_s) *new_states = NULL;
00128       int pid = ptid_get_pid (ptid);
00129 
00130       for (ix = 0;
00131            VEC_iterate (inline_state_s, inline_states, ix, state);
00132            ix++)
00133         if (pid != ptid_get_pid (state->ptid))
00134           VEC_safe_push (inline_state_s, new_states, state);
00135       VEC_free (inline_state_s, inline_states);
00136       inline_states = new_states;
00137       return;
00138     }
00139 
00140   for (ix = 0; VEC_iterate (inline_state_s, inline_states, ix, state); ix++)
00141     if (ptid_equal (state->ptid, ptid))
00142       {
00143         VEC_unordered_remove (inline_state_s, inline_states, ix);
00144         return;
00145       }
00146 }
00147 
00148 static void
00149 inline_frame_this_id (struct frame_info *this_frame,
00150                       void **this_cache,
00151                       struct frame_id *this_id)
00152 {
00153   struct symbol *func;
00154 
00155   /* In order to have a stable frame ID for a given inline function,
00156      we must get the stack / special addresses from the underlying
00157      real frame's this_id method.  So we must call get_prev_frame.
00158      Because we are inlined into some function, there must be previous
00159      frames, so this is safe - as long as we're careful not to
00160      create any cycles.  */
00161   *this_id = get_frame_id (get_prev_frame (this_frame));
00162 
00163   /* We need a valid frame ID, so we need to be based on a valid
00164      frame.  FSF submission NOTE: this would be a good assertion to
00165      apply to all frames, all the time.  That would fix the ambiguity
00166      of null_frame_id (between "no/any frame" and "the outermost
00167      frame").  This will take work.  */
00168   gdb_assert (frame_id_p (*this_id));
00169 
00170   /* For now, require we don't match outer_frame_id either (see
00171      comment above).  */
00172   gdb_assert (!frame_id_eq (*this_id, outer_frame_id));
00173 
00174   /* Future work NOTE: Alexandre Oliva applied a patch to GCC 4.3
00175      which generates DW_AT_entry_pc for inlined functions when
00176      possible.  If this attribute is available, we should use it
00177      in the frame ID (and eventually, to set breakpoints).  */
00178   func = get_frame_function (this_frame);
00179   gdb_assert (func != NULL);
00180   (*this_id).code_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
00181   (*this_id).artificial_depth++;
00182 }
00183 
00184 static struct value *
00185 inline_frame_prev_register (struct frame_info *this_frame, void **this_cache,
00186                             int regnum)
00187 {
00188   /* Use get_frame_register_value instead of
00189      frame_unwind_got_register, to avoid requiring this frame's ID.
00190      This frame's ID depends on the previous frame's ID (unusual), and
00191      the previous frame's ID depends on this frame's unwound
00192      registers.  If unwinding registers from this frame called
00193      get_frame_id, there would be a loop.
00194 
00195      Do not copy this code into any other unwinder!  Inlined functions
00196      are special; other unwinders must not have a dependency on the
00197      previous frame's ID, and therefore can and should use
00198      frame_unwind_got_register instead.  */
00199   return get_frame_register_value (this_frame, regnum);
00200 }
00201 
00202 /* Check whether we are at an inlining site that does not already
00203    have an associated frame.  */
00204 
00205 static int
00206 inline_frame_sniffer (const struct frame_unwind *self,
00207                       struct frame_info *this_frame,
00208                       void **this_cache)
00209 {
00210   CORE_ADDR this_pc;
00211   struct block *frame_block, *cur_block;
00212   int depth;
00213   struct frame_info *next_frame;
00214   struct inline_state *state = find_inline_frame_state (inferior_ptid);
00215 
00216   this_pc = get_frame_address_in_block (this_frame);
00217   frame_block = block_for_pc (this_pc);
00218   if (frame_block == NULL)
00219     return 0;
00220 
00221   /* Calculate DEPTH, the number of inlined functions at this
00222      location.  */
00223   depth = 0;
00224   cur_block = frame_block;
00225   while (BLOCK_SUPERBLOCK (cur_block))
00226     {
00227       if (block_inlined_p (cur_block))
00228         depth++;
00229 
00230       cur_block = BLOCK_SUPERBLOCK (cur_block);
00231     }
00232 
00233   /* Check how many inlined functions already have frames.  */
00234   for (next_frame = get_next_frame (this_frame);
00235        next_frame && get_frame_type (next_frame) == INLINE_FRAME;
00236        next_frame = get_next_frame (next_frame))
00237     {
00238       gdb_assert (depth > 0);
00239       depth--;
00240     }
00241 
00242   /* If this is the topmost frame, or all frames above us are inlined,
00243      then check whether we were requested to skip some frames (so they
00244      can be stepped into later).  */
00245   if (state != NULL && state->skipped_frames > 0 && next_frame == NULL)
00246     {
00247       gdb_assert (depth >= state->skipped_frames);
00248       depth -= state->skipped_frames;
00249     }
00250 
00251   /* If all the inlined functions here already have frames, then pass
00252      to the normal unwinder for this PC.  */
00253   if (depth == 0)
00254     return 0;
00255 
00256   /* If the next frame is an inlined function, but not the outermost, then
00257      we are the next outer.  If it is not an inlined function, then we
00258      are the innermost inlined function of a different real frame.  */
00259   return 1;
00260 }
00261 
00262 const struct frame_unwind inline_frame_unwind = {
00263   INLINE_FRAME,
00264   default_frame_unwind_stop_reason,
00265   inline_frame_this_id,
00266   inline_frame_prev_register,
00267   NULL,
00268   inline_frame_sniffer
00269 };
00270 
00271 /* Return non-zero if BLOCK, an inlined function block containing PC,
00272    has a group of contiguous instructions starting at PC (but not
00273    before it).  */
00274 
00275 static int
00276 block_starting_point_at (CORE_ADDR pc, struct block *block)
00277 {
00278   struct blockvector *bv;
00279   struct block *new_block;
00280 
00281   bv = blockvector_for_pc (pc, NULL);
00282   if (BLOCKVECTOR_MAP (bv) == NULL)
00283     return 0;
00284 
00285   new_block = addrmap_find (BLOCKVECTOR_MAP (bv), pc - 1);
00286   if (new_block == NULL)
00287     return 1;
00288 
00289   if (new_block == block || contained_in (new_block, block))
00290     return 0;
00291 
00292   /* The immediately preceding address belongs to a different block,
00293      which is not a child of this one.  Treat this as an entrance into
00294      BLOCK.  */
00295   return 1;
00296 }
00297 
00298 /* Skip all inlined functions whose call sites are at the current PC.
00299    Frames for the hidden functions will not appear in the backtrace until the
00300    user steps into them.  */
00301 
00302 void
00303 skip_inline_frames (ptid_t ptid)
00304 {
00305   CORE_ADDR this_pc;
00306   struct block *frame_block, *cur_block;
00307   struct symbol *last_sym = NULL;
00308   int skip_count = 0;
00309   struct inline_state *state;
00310 
00311   /* This function is called right after reinitializing the frame
00312      cache.  We try not to do more unwinding than absolutely
00313      necessary, for performance.  */
00314   this_pc = get_frame_pc (get_current_frame ());
00315   frame_block = block_for_pc (this_pc);
00316 
00317   if (frame_block != NULL)
00318     {
00319       cur_block = frame_block;
00320       while (BLOCK_SUPERBLOCK (cur_block))
00321         {
00322           if (block_inlined_p (cur_block))
00323             {
00324               /* See comments in inline_frame_this_id about this use
00325                  of BLOCK_START.  */
00326               if (BLOCK_START (cur_block) == this_pc
00327                   || block_starting_point_at (this_pc, cur_block))
00328                 {
00329                   skip_count++;
00330                   last_sym = BLOCK_FUNCTION (cur_block);
00331                 }
00332               else
00333                 break;
00334             }
00335           cur_block = BLOCK_SUPERBLOCK (cur_block);
00336         }
00337     }
00338 
00339   gdb_assert (find_inline_frame_state (ptid) == NULL);
00340   state = allocate_inline_frame_state (ptid);
00341   state->skipped_frames = skip_count;
00342   state->saved_pc = this_pc;
00343   state->skipped_symbol = last_sym;
00344 
00345   if (skip_count != 0)
00346     reinit_frame_cache ();
00347 }
00348 
00349 /* Step into an inlined function by unhiding it.  */
00350 
00351 void
00352 step_into_inline_frame (ptid_t ptid)
00353 {
00354   struct inline_state *state = find_inline_frame_state (ptid);
00355 
00356   gdb_assert (state != NULL && state->skipped_frames > 0);
00357   state->skipped_frames--;
00358   reinit_frame_cache ();
00359 }
00360 
00361 /* Return the number of hidden functions inlined into the current
00362    frame.  */
00363 
00364 int
00365 inline_skipped_frames (ptid_t ptid)
00366 {
00367   struct inline_state *state = find_inline_frame_state (ptid);
00368 
00369   if (state == NULL)
00370     return 0;
00371   else
00372     return state->skipped_frames;
00373 }
00374 
00375 /* If one or more inlined functions are hidden, return the symbol for
00376    the function inlined into the current frame.  */
00377 
00378 struct symbol *
00379 inline_skipped_symbol (ptid_t ptid)
00380 {
00381   struct inline_state *state = find_inline_frame_state (ptid);
00382 
00383   gdb_assert (state != NULL);
00384   return state->skipped_symbol;
00385 }
00386 
00387 /* Return the number of functions inlined into THIS_FRAME.  Some of
00388    the callees may not have associated frames (see
00389    skip_inline_frames).  */
00390 
00391 int
00392 frame_inlined_callees (struct frame_info *this_frame)
00393 {
00394   struct frame_info *next_frame;
00395   int inline_count = 0;
00396 
00397   /* First count how many inlined functions at this PC have frames
00398      above FRAME (are inlined into FRAME).  */
00399   for (next_frame = get_next_frame (this_frame);
00400        next_frame && get_frame_type (next_frame) == INLINE_FRAME;
00401        next_frame = get_next_frame (next_frame))
00402     inline_count++;
00403 
00404   /* Simulate some most-inner inlined frames which were suppressed, so
00405      they can be stepped into later.  If we are unwinding already
00406      outer frames from some non-inlined frame this does not apply.  */
00407   if (next_frame == NULL)
00408     inline_count += inline_skipped_frames (inferior_ptid);
00409 
00410   return inline_count;
00411 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines