GDB (API)
|
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 }