1 //===-- StackFrameList.cpp --------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Target/StackFrameList.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/StreamFile.h" 17 #include "lldb/Symbol/Block.h" 18 #include "lldb/Symbol/Function.h" 19 #include "lldb/Symbol/Symbol.h" 20 #include "lldb/Target/RegisterContext.h" 21 #include "lldb/Target/StackFrame.h" 22 #include "lldb/Target/Thread.h" 23 #include "lldb/Target/Unwind.h" 24 25 //#define DEBUG_STACK_FRAMES 1 26 27 using namespace lldb; 28 using namespace lldb_private; 29 30 //---------------------------------------------------------------------- 31 // StackFrameList constructor 32 //---------------------------------------------------------------------- 33 StackFrameList::StackFrameList 34 ( 35 Thread &thread, 36 const lldb::StackFrameListSP &prev_frames_sp, 37 bool show_inline_frames 38 ) : 39 m_thread (thread), 40 m_prev_frames_sp (prev_frames_sp), 41 m_mutex (Mutex::eMutexTypeRecursive), 42 m_frames (), 43 m_selected_frame_idx (0), 44 m_show_inlined_frames (show_inline_frames) 45 { 46 } 47 48 //---------------------------------------------------------------------- 49 // Destructor 50 //---------------------------------------------------------------------- 51 StackFrameList::~StackFrameList() 52 { 53 } 54 55 56 uint32_t 57 StackFrameList::GetNumFrames (bool can_create) 58 { 59 Mutex::Locker locker (m_mutex); 60 61 if (can_create && m_frames.size() <= 1) 62 { 63 if (m_show_inlined_frames) 64 { 65 #if defined (DEBUG_STACK_FRAMES) 66 StreamFile s(stdout); 67 #endif 68 Unwind *unwinder = m_thread.GetUnwinder (); 69 addr_t pc = LLDB_INVALID_ADDRESS; 70 addr_t cfa = LLDB_INVALID_ADDRESS; 71 72 // If we are going to show inlined stack frames as actual frames, 73 // we need to calculate all concrete frames first, then iterate 74 // through all of them and count up how many inlined functions are 75 // in each frame. 76 const uint32_t unwind_frame_count = unwinder->GetFrameCount(); 77 78 StackFrameSP unwind_frame_sp; 79 for (uint32_t idx=0; idx<unwind_frame_count; ++idx) 80 { 81 if (idx == 0) 82 { 83 // We might have already created frame zero, only create it 84 // if we need to 85 if (m_frames.empty()) 86 { 87 cfa = m_thread.m_reg_context_sp->GetSP(); 88 m_thread.GetRegisterContext(); 89 unwind_frame_sp.reset (new StackFrame (m_frames.size(), 90 idx, 91 m_thread, 92 m_thread.m_reg_context_sp, 93 cfa, 94 m_thread.m_reg_context_sp->GetPC(), 95 NULL)); 96 m_frames.push_back (unwind_frame_sp); 97 } 98 else 99 { 100 unwind_frame_sp = m_frames.front(); 101 cfa = unwind_frame_sp->m_id.GetCallFrameAddress(); 102 } 103 } 104 else 105 { 106 const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc); 107 assert (success); 108 unwind_frame_sp.reset (new StackFrame (m_frames.size(), idx, m_thread, cfa, pc, NULL)); 109 m_frames.push_back (unwind_frame_sp); 110 } 111 112 Block *unwind_block = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock).block; 113 114 if (unwind_block) 115 { 116 Block *inlined_block = unwind_block->GetContainingInlinedBlock(); 117 if (inlined_block) 118 { 119 for (; inlined_block != NULL; inlined_block = inlined_block->GetInlinedParent ()) 120 { 121 SymbolContext inline_sc; 122 Block *parent_block = inlined_block->GetInlinedParent(); 123 124 const bool is_inlined_frame = parent_block != NULL; 125 126 if (parent_block == NULL) 127 parent_block = inlined_block->GetParent(); 128 129 parent_block->CalculateSymbolContext (&inline_sc); 130 131 Address previous_frame_lookup_addr (m_frames.back()->GetFrameCodeAddress()); 132 if (unwind_frame_sp->GetFrameIndex() > 0 && m_frames.back().get() == unwind_frame_sp.get()) 133 previous_frame_lookup_addr.Slide (-1); 134 135 AddressRange range; 136 inlined_block->GetRangeContainingAddress (previous_frame_lookup_addr, range); 137 138 const InlineFunctionInfo* inline_info = inlined_block->GetInlinedFunctionInfo(); 139 assert (inline_info); 140 inline_sc.line_entry.range.GetBaseAddress() = m_frames.back()->GetFrameCodeAddress(); 141 inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); 142 inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); 143 inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); 144 145 StackFrameSP frame_sp(new StackFrame (m_frames.size(), 146 idx, 147 m_thread, 148 unwind_frame_sp->GetRegisterContextSP (), 149 cfa, 150 range.GetBaseAddress(), 151 &inline_sc)); // The symbol context for this inline frame 152 153 if (is_inlined_frame) 154 { 155 // Use the block with the inlined function info 156 // as the symbol context since we want this frame 157 // to have only the variables for the inlined function 158 frame_sp->SetSymbolContextScope (parent_block); 159 } 160 else 161 { 162 // This block is not inlined with means it has no 163 // inlined parents either, so we want to use the top 164 // most function block. 165 frame_sp->SetSymbolContextScope (&unwind_frame_sp->GetSymbolContext (eSymbolContextFunction).function->GetBlock(false)); 166 } 167 168 m_frames.push_back (frame_sp); 169 } 170 } 171 } 172 } 173 174 if (m_prev_frames_sp) 175 { 176 StackFrameList *prev_frames = m_prev_frames_sp.get(); 177 StackFrameList *curr_frames = this; 178 179 #if defined (DEBUG_STACK_FRAMES) 180 s.PutCString("\nprev_frames:\n"); 181 prev_frames->Dump (&s); 182 s.PutCString("\ncurr_frames:\n"); 183 curr_frames->Dump (&s); 184 s.EOL(); 185 #endif 186 size_t curr_frame_num, prev_frame_num; 187 188 for (curr_frame_num = curr_frames->m_frames.size(), prev_frame_num = prev_frames->m_frames.size(); 189 curr_frame_num > 0 && prev_frame_num > 0; 190 --curr_frame_num, --prev_frame_num) 191 { 192 const size_t curr_frame_idx = curr_frame_num-1; 193 const size_t prev_frame_idx = prev_frame_num-1; 194 StackFrameSP curr_frame_sp (curr_frames->m_frames[curr_frame_idx]); 195 StackFrameSP prev_frame_sp (prev_frames->m_frames[prev_frame_idx]); 196 197 #if defined (DEBUG_STACK_FRAMES) 198 s.Printf("\n\nCurr frame #%u ", curr_frame_idx); 199 if (curr_frame_sp) 200 curr_frame_sp->Dump (&s, true, false); 201 else 202 s.PutCString("NULL"); 203 s.Printf("\nPrev frame #%u ", prev_frame_idx); 204 if (prev_frame_sp) 205 prev_frame_sp->Dump (&s, true, false); 206 else 207 s.PutCString("NULL"); 208 #endif 209 210 StackFrame *curr_frame = curr_frame_sp.get(); 211 StackFrame *prev_frame = prev_frame_sp.get(); 212 213 if (curr_frame == NULL || prev_frame == NULL) 214 break; 215 216 // Check the stack ID to make sure they are equal 217 if (curr_frame->GetStackID() != prev_frame->GetStackID()) 218 break; 219 220 prev_frame->UpdatePreviousFrameFromCurrentFrame (*curr_frame); 221 // Now copy the fixed up previous frame into the current frames 222 // so the pointer doesn't change 223 m_frames[curr_frame_idx] = prev_frame_sp; 224 //curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame); 225 226 #if defined (DEBUG_STACK_FRAMES) 227 s.Printf("\n Copying previous frame to current frame"); 228 #endif 229 } 230 // We are done with the old stack frame list, we can release it now 231 m_prev_frames_sp.reset(); 232 } 233 234 #if defined (DEBUG_STACK_FRAMES) 235 s.PutCString("\n\nNew frames:\n"); 236 Dump (&s); 237 s.EOL(); 238 #endif 239 } 240 else 241 { 242 m_frames.resize(m_thread.GetUnwinder()->GetFrameCount()); 243 } 244 } 245 return m_frames.size(); 246 } 247 248 void 249 StackFrameList::Dump (Stream *s) 250 { 251 if (s == NULL) 252 return; 253 Mutex::Locker locker (m_mutex); 254 255 const_iterator pos, begin = m_frames.begin(), end = m_frames.end(); 256 for (pos = begin; pos != end; ++pos) 257 { 258 StackFrame *frame = (*pos).get(); 259 s->Printf("%p: ", frame); 260 if (frame) 261 { 262 frame->GetStackID().Dump (s); 263 frame->DumpUsingSettingsFormat (s); 264 } 265 else 266 s->Printf("frame #%u", std::distance (begin, pos)); 267 s->EOL(); 268 } 269 s->EOL(); 270 } 271 272 StackFrameSP 273 StackFrameList::GetFrameAtIndex (uint32_t idx) 274 { 275 StackFrameSP frame_sp; 276 Mutex::Locker locker (m_mutex); 277 if (idx < m_frames.size()) 278 frame_sp = m_frames[idx]; 279 280 if (frame_sp) 281 return frame_sp; 282 283 // Special case the first frame (idx == 0) so that we don't need to 284 // know how many stack frames there are to get it. If we need any other 285 // frames, then we do need to know if "idx" is a valid index. 286 if (idx == 0) 287 { 288 // If this is the first frame, we want to share the thread register 289 // context with the stack frame at index zero. 290 m_thread.GetRegisterContext(); 291 assert (m_thread.m_reg_context_sp.get()); 292 frame_sp.reset (new StackFrame (0, 293 0, 294 m_thread, 295 m_thread.m_reg_context_sp, 296 m_thread.m_reg_context_sp->GetSP(), 297 m_thread.m_reg_context_sp->GetPC(), 298 NULL)); 299 300 SetFrameAtIndex(idx, frame_sp); 301 } 302 else if (idx < GetNumFrames()) 303 { 304 if (m_show_inlined_frames) 305 { 306 // When inline frames are enabled we cache up all frames in GetNumFrames() 307 frame_sp = m_frames[idx]; 308 } 309 else 310 { 311 Unwind *unwinder = m_thread.GetUnwinder (); 312 if (unwinder) 313 { 314 addr_t pc, cfa; 315 if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) 316 { 317 frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, pc, NULL)); 318 319 Function *function = frame_sp->GetSymbolContext (eSymbolContextFunction).function; 320 if (function) 321 { 322 // When we aren't showing inline functions we always use 323 // the top most function block as the scope. 324 frame_sp->SetSymbolContextScope (&function->GetBlock(false)); 325 } 326 else 327 { 328 // Set the symbol scope from the symbol regardless if it is NULL or valid. 329 frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol); 330 } 331 SetFrameAtIndex(idx, frame_sp); 332 } 333 } 334 } 335 } 336 return frame_sp; 337 } 338 339 StackFrameSP 340 StackFrameList::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx) 341 { 342 // First try assuming the unwind index is the same as the frame index. The 343 // unwind index is always greater than or equal to the frame index, so it 344 // is a good place to start. If we have inlined frames we might have 5 345 // concrete frames (frame unwind indexes go from 0-4), but we might have 15 346 // frames after we make all the inlined frames. Most of the time the unwind 347 // frame index (or the concrete frame index) is the same as the frame index. 348 uint32_t frame_idx = unwind_idx; 349 StackFrameSP frame_sp (GetFrameAtIndex (frame_idx)); 350 while (frame_sp) 351 { 352 if (frame_sp->GetFrameIndex() == unwind_idx) 353 break; 354 frame_sp = GetFrameAtIndex (++frame_idx); 355 } 356 return frame_sp; 357 } 358 359 StackFrameSP 360 StackFrameList::GetFrameWithStackID (StackID &stack_id) 361 { 362 uint32_t frame_idx = 0; 363 StackFrameSP frame_sp; 364 do 365 { 366 frame_sp = GetFrameAtIndex (frame_idx); 367 if (frame_sp && frame_sp->GetStackID() == stack_id) 368 break; 369 frame_idx++; 370 } 371 while (frame_sp); 372 return frame_sp; 373 } 374 375 bool 376 StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) 377 { 378 if (idx >= m_frames.size()) 379 m_frames.resize(idx + 1); 380 // Make sure allocation succeeded by checking bounds again 381 if (idx < m_frames.size()) 382 { 383 m_frames[idx] = frame_sp; 384 return true; 385 } 386 return false; // resize failed, out of memory? 387 } 388 389 uint32_t 390 StackFrameList::GetSelectedFrameIndex () const 391 { 392 Mutex::Locker locker (m_mutex); 393 return m_selected_frame_idx; 394 } 395 396 397 uint32_t 398 StackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame) 399 { 400 Mutex::Locker locker (m_mutex); 401 const_iterator pos; 402 const_iterator begin = m_frames.begin(); 403 const_iterator end = m_frames.end(); 404 for (pos = begin; pos != end; ++pos) 405 { 406 if (pos->get() == frame) 407 { 408 m_selected_frame_idx = std::distance (begin, pos); 409 return m_selected_frame_idx; 410 } 411 } 412 m_selected_frame_idx = 0; 413 return m_selected_frame_idx; 414 } 415 416 // Mark a stack frame as the current frame using the frame index 417 void 418 StackFrameList::SetSelectedFrameByIndex (uint32_t idx) 419 { 420 Mutex::Locker locker (m_mutex); 421 m_selected_frame_idx = idx; 422 } 423 424 // The thread has been run, reset the number stack frames to zero so we can 425 // determine how many frames we have lazily. 426 void 427 StackFrameList::Clear () 428 { 429 Mutex::Locker locker (m_mutex); 430 m_frames.clear(); 431 } 432 433 void 434 StackFrameList::InvalidateFrames (uint32_t start_idx) 435 { 436 Mutex::Locker locker (m_mutex); 437 if (m_show_inlined_frames) 438 { 439 Clear(); 440 } 441 else 442 { 443 const size_t num_frames = m_frames.size(); 444 while (start_idx < num_frames) 445 { 446 m_frames[start_idx].reset(); 447 ++start_idx; 448 } 449 } 450 } 451 452 void 453 StackFrameList::Merge (std::auto_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp) 454 { 455 Mutex::Locker curr_locker (curr_ap.get() ? curr_ap->m_mutex.GetMutex() : NULL); 456 Mutex::Locker prev_locker (prev_sp.get() ? prev_sp->m_mutex.GetMutex() : NULL); 457 458 #if defined (DEBUG_STACK_FRAMES) 459 StreamFile s(stdout); 460 s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n"); 461 if (prev_sp.get()) 462 prev_sp->Dump (&s); 463 else 464 s.PutCString ("NULL"); 465 s.PutCString("\nCurr:\n"); 466 if (curr_ap.get()) 467 curr_ap->Dump (&s); 468 else 469 s.PutCString ("NULL"); 470 s.EOL(); 471 #endif 472 473 if (curr_ap.get() == NULL || curr_ap->GetNumFrames (false) == 0) 474 { 475 #if defined (DEBUG_STACK_FRAMES) 476 s.PutCString("No current frames, leave previous frames alone...\n"); 477 #endif 478 curr_ap.release(); 479 return; 480 } 481 482 if (prev_sp.get() == NULL || prev_sp->GetNumFrames (false) == 0) 483 { 484 #if defined (DEBUG_STACK_FRAMES) 485 s.PutCString("No previous frames, so use current frames...\n"); 486 #endif 487 // We either don't have any previous frames, or since we have more than 488 // one current frames it means we have all the frames and can safely 489 // replace our previous frames. 490 prev_sp.reset (curr_ap.release()); 491 return; 492 } 493 494 const uint32_t num_curr_frames = curr_ap->GetNumFrames (false); 495 496 if (num_curr_frames > 1) 497 { 498 #if defined (DEBUG_STACK_FRAMES) 499 s.PutCString("We have more than one current frame, so use current frames...\n"); 500 #endif 501 // We have more than one current frames it means we have all the frames 502 // and can safely replace our previous frames. 503 prev_sp.reset (curr_ap.release()); 504 505 #if defined (DEBUG_STACK_FRAMES) 506 s.PutCString("\nMerged:\n"); 507 prev_sp->Dump (&s); 508 #endif 509 return; 510 } 511 512 StackFrameSP prev_frame_zero_sp(prev_sp->GetFrameAtIndex (0)); 513 StackFrameSP curr_frame_zero_sp(curr_ap->GetFrameAtIndex (0)); 514 StackID curr_stack_id (curr_frame_zero_sp->GetStackID()); 515 StackID prev_stack_id (prev_frame_zero_sp->GetStackID()); 516 517 //const uint32_t num_prev_frames = prev_sp->GetNumFrames (false); 518 519 #if defined (DEBUG_STACK_FRAMES) 520 s.Printf("\n%u previous frames with one current frame\n", num_prev_frames); 521 #endif 522 523 // We have only a single current frame 524 // Our previous stack frames only had a single frame as well... 525 if (curr_stack_id == prev_stack_id) 526 { 527 #if defined (DEBUG_STACK_FRAMES) 528 s.Printf("\nPrevious frame #0 is same as current frame #0, merge the cached data\n"); 529 #endif 530 531 curr_frame_zero_sp->UpdateCurrentFrameFromPreviousFrame (*prev_frame_zero_sp); 532 // prev_frame_zero_sp->UpdatePreviousFrameFromCurrentFrame (*curr_frame_zero_sp); 533 // prev_sp->SetFrameAtIndex (0, prev_frame_zero_sp); 534 } 535 else if (curr_stack_id < prev_stack_id) 536 { 537 #if defined (DEBUG_STACK_FRAMES) 538 s.Printf("\nCurrent frame #0 has a stack ID that is less than the previous frame #0, insert current frame zero in front of previous\n"); 539 #endif 540 prev_sp->m_frames.insert (prev_sp->m_frames.begin(), curr_frame_zero_sp); 541 } 542 543 curr_ap.release(); 544 545 #if defined (DEBUG_STACK_FRAMES) 546 s.PutCString("\nMerged:\n"); 547 prev_sp->Dump (&s); 548 #endif 549 550 551 } 552 553 lldb::StackFrameSP 554 StackFrameList::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr) 555 { 556 const_iterator pos; 557 const_iterator begin = m_frames.begin(); 558 const_iterator end = m_frames.end(); 559 lldb::StackFrameSP ret_sp; 560 561 for (pos = begin; pos != end; ++pos) 562 { 563 if (pos->get() == stack_frame_ptr) 564 { 565 ret_sp = (*pos); 566 break; 567 } 568 } 569 return ret_sp; 570 } 571 572