1 //===-- StackFrame.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/StackFrame.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/Module.h" 17 #include "lldb/Core/Debugger.h" 18 #include "lldb/Core/Disassembler.h" 19 #include "lldb/Core/Value.h" 20 #include "lldb/Core/ValueObjectVariable.h" 21 #include "lldb/Symbol/Function.h" 22 #include "lldb/Symbol/VariableList.h" 23 #include "lldb/Target/ExecutionContext.h" 24 #include "lldb/Target/Process.h" 25 #include "lldb/Target/RegisterContext.h" 26 #include "lldb/Target/Target.h" 27 #include "lldb/Target/Thread.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 // The first bits in the flags are reserved for the SymbolContext::Scope bits 33 // so we know if we have tried to look up information in our internal symbol 34 // context (m_sc) already. 35 #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) 36 #define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1) 37 #define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1) 38 #define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) 39 #define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1) 40 41 StackFrame::StackFrame 42 ( 43 lldb::user_id_t frame_idx, 44 lldb::user_id_t unwind_frame_index, 45 Thread &thread, 46 lldb::addr_t cfa, 47 lldb::addr_t pc, 48 const SymbolContext *sc_ptr 49 ) : 50 m_frame_index (frame_idx), 51 m_unwind_frame_index (unwind_frame_index), 52 m_thread (thread), 53 m_reg_context_sp (), 54 m_id (pc, cfa, NULL), 55 m_frame_code_addr (NULL, pc), 56 m_sc (), 57 m_flags (), 58 m_frame_base (), 59 m_frame_base_error (), 60 m_variable_list_sp (), 61 m_variable_list_value_objects () 62 { 63 if (sc_ptr != NULL) 64 { 65 m_sc = *sc_ptr; 66 m_flags.Set(m_sc.GetResolvedMask ()); 67 } 68 } 69 70 StackFrame::StackFrame 71 ( 72 lldb::user_id_t frame_idx, 73 lldb::user_id_t unwind_frame_index, 74 Thread &thread, 75 const RegisterContextSP ®_context_sp, 76 lldb::addr_t cfa, 77 lldb::addr_t pc, 78 const SymbolContext *sc_ptr 79 ) : 80 m_frame_index (frame_idx), 81 m_unwind_frame_index (unwind_frame_index), 82 m_thread (thread), 83 m_reg_context_sp (reg_context_sp), 84 m_id (pc, cfa, NULL), 85 m_frame_code_addr (NULL, pc), 86 m_sc (), 87 m_flags (), 88 m_frame_base (), 89 m_frame_base_error (), 90 m_variable_list_sp (), 91 m_variable_list_value_objects () 92 { 93 if (sc_ptr != NULL) 94 { 95 m_sc = *sc_ptr; 96 m_flags.Set(m_sc.GetResolvedMask ()); 97 } 98 99 if (reg_context_sp && !m_sc.target_sp) 100 { 101 m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP(); 102 m_flags.Set (eSymbolContextTarget); 103 } 104 } 105 106 StackFrame::StackFrame 107 ( 108 lldb::user_id_t frame_idx, 109 lldb::user_id_t unwind_frame_index, 110 Thread &thread, 111 const RegisterContextSP ®_context_sp, 112 lldb::addr_t cfa, 113 const Address& pc_addr, 114 const SymbolContext *sc_ptr 115 ) : 116 m_frame_index (frame_idx), 117 m_unwind_frame_index (unwind_frame_index), 118 m_thread (thread), 119 m_reg_context_sp (reg_context_sp), 120 m_id (pc_addr.GetLoadAddress (&thread.GetProcess().GetTarget()), cfa, NULL), 121 m_frame_code_addr (pc_addr), 122 m_sc (), 123 m_flags (), 124 m_frame_base (), 125 m_frame_base_error (), 126 m_variable_list_sp (), 127 m_variable_list_value_objects () 128 { 129 if (sc_ptr != NULL) 130 { 131 m_sc = *sc_ptr; 132 m_flags.Set(m_sc.GetResolvedMask ()); 133 } 134 135 if (m_sc.target_sp.get() == NULL && reg_context_sp) 136 { 137 m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP(); 138 m_flags.Set (eSymbolContextTarget); 139 } 140 141 Module *pc_module = pc_addr.GetModule(); 142 if (m_sc.module_sp.get() == NULL || m_sc.module_sp.get() != pc_module) 143 { 144 if (pc_module) 145 { 146 m_sc.module_sp = pc_module->GetSP(); 147 m_flags.Set (eSymbolContextModule); 148 } 149 else 150 { 151 m_sc.module_sp.reset(); 152 } 153 154 } 155 } 156 157 158 //---------------------------------------------------------------------- 159 // Destructor 160 //---------------------------------------------------------------------- 161 StackFrame::~StackFrame() 162 { 163 } 164 165 StackID& 166 StackFrame::GetStackID() 167 { 168 // Make sure we have resolved the StackID object's symbol context scope if 169 // we already haven't looked it up. 170 171 if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE)) 172 { 173 if (m_id.GetSymbolContextScope ()) 174 { 175 // We already have a symbol context scope, we just don't have our 176 // flag bit set. 177 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 178 } 179 else 180 { 181 // Calculate the frame block and use this for the stack ID symbol 182 // context scope if we have one. 183 SymbolContextScope *scope = GetFrameBlock (); 184 if (scope == NULL) 185 { 186 // We don't have a block, so use the symbol 187 if (m_flags.IsClear (eSymbolContextSymbol)) 188 GetSymbolContext (eSymbolContextSymbol); 189 190 // It is ok if m_sc.symbol is NULL here 191 scope = m_sc.symbol; 192 } 193 // Set the symbol context scope (the accessor will set the 194 // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags). 195 SetSymbolContextScope (scope); 196 } 197 } 198 return m_id; 199 } 200 201 void 202 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) 203 { 204 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 205 m_id.SetSymbolContextScope (symbol_scope); 206 } 207 208 Address& 209 StackFrame::GetFrameCodeAddress() 210 { 211 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) 212 { 213 m_flags.Set (RESOLVED_FRAME_CODE_ADDR); 214 215 // Resolve the PC into a temporary address because if ResolveLoadAddress 216 // fails to resolve the address, it will clear the address object... 217 Address resolved_pc; 218 if (m_thread.GetProcess().GetTarget().GetSectionLoadList().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc)) 219 { 220 m_frame_code_addr = resolved_pc; 221 const Section *section = m_frame_code_addr.GetSection(); 222 if (section) 223 { 224 Module *module = section->GetModule(); 225 if (module) 226 { 227 m_sc.module_sp = module->GetSP(); 228 if (m_sc.module_sp) 229 m_flags.Set(eSymbolContextModule); 230 } 231 } 232 } 233 } 234 return m_frame_code_addr; 235 } 236 237 void 238 StackFrame::ChangePC (addr_t pc) 239 { 240 m_frame_code_addr.SetOffset(pc); 241 m_frame_code_addr.SetSection(NULL); 242 m_sc.Clear(); 243 m_flags.Reset(0); 244 m_thread.ClearStackFrames (); 245 } 246 247 const char * 248 StackFrame::Disassemble () 249 { 250 if (m_disassembly.GetSize() == 0) 251 { 252 ExecutionContext exe_ctx; 253 CalculateExecutionContext(exe_ctx); 254 Target &target = m_thread.GetProcess().GetTarget(); 255 Disassembler::Disassemble (target.GetDebugger(), 256 target.GetArchitecture(), 257 exe_ctx, 258 0, 259 false, 260 m_disassembly); 261 if (m_disassembly.GetSize() == 0) 262 return NULL; 263 } 264 return m_disassembly.GetData(); 265 } 266 267 Block * 268 StackFrame::GetFrameBlock () 269 { 270 if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock)) 271 GetSymbolContext (eSymbolContextBlock); 272 273 if (m_sc.block) 274 { 275 Block *inline_block = m_sc.block->GetContainingInlinedBlock(); 276 if (inline_block) 277 { 278 // Use the block with the inlined function info 279 // as the frame block we want this frame to have only the variables 280 // for the inlined function and its non-inlined block child blocks. 281 return inline_block; 282 } 283 else 284 { 285 // This block is not contained withing any inlined function blocks 286 // with so we want to use the top most function block. 287 return &m_sc.function->GetBlock (false); 288 } 289 } 290 return NULL; 291 } 292 293 //---------------------------------------------------------------------- 294 // Get the symbol context if we already haven't done so by resolving the 295 // PC address as much as possible. This way when we pass around a 296 // StackFrame object, everyone will have as much information as 297 // possible and no one will ever have to look things up manually. 298 //---------------------------------------------------------------------- 299 const SymbolContext& 300 StackFrame::GetSymbolContext (uint32_t resolve_scope) 301 { 302 // Copy our internal symbol context into "sc". 303 if ((m_flags.Get() & resolve_scope) != resolve_scope) 304 { 305 // Resolve our PC to section offset if we haven't alreday done so 306 // and if we don't have a module. The resolved address section will 307 // contain the module to which it belongs 308 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) 309 GetFrameCodeAddress(); 310 311 // If this is not frame zero, then we need to subtract 1 from the PC 312 // value when doing address lookups since the PC will be on the 313 // instruction following the function call instruction... 314 315 Address lookup_addr(GetFrameCodeAddress()); 316 if (m_frame_index > 0 && lookup_addr.IsValid()) 317 { 318 addr_t offset = lookup_addr.GetOffset(); 319 if (offset > 0) 320 lookup_addr.SetOffset(offset - 1); 321 } 322 323 324 uint32_t resolved = 0; 325 if (m_sc.module_sp) 326 { 327 // We have something in our stack frame symbol context, lets check 328 // if we haven't already tried to lookup one of those things. If we 329 // haven't then we will do the query. 330 331 uint32_t actual_resolve_scope = 0; 332 333 if (resolve_scope & eSymbolContextCompUnit) 334 { 335 if (m_flags.IsClear (eSymbolContextCompUnit)) 336 { 337 if (m_sc.comp_unit) 338 resolved |= eSymbolContextCompUnit; 339 else 340 actual_resolve_scope |= eSymbolContextCompUnit; 341 } 342 } 343 344 if (resolve_scope & eSymbolContextFunction) 345 { 346 if (m_flags.IsClear (eSymbolContextFunction)) 347 { 348 if (m_sc.function) 349 resolved |= eSymbolContextFunction; 350 else 351 actual_resolve_scope |= eSymbolContextFunction; 352 } 353 } 354 355 if (resolve_scope & eSymbolContextBlock) 356 { 357 if (m_flags.IsClear (eSymbolContextBlock)) 358 { 359 if (m_sc.block) 360 resolved |= eSymbolContextBlock; 361 else 362 actual_resolve_scope |= eSymbolContextBlock; 363 } 364 } 365 366 if (resolve_scope & eSymbolContextSymbol) 367 { 368 if (m_flags.IsClear (eSymbolContextSymbol)) 369 { 370 if (m_sc.symbol) 371 resolved |= eSymbolContextSymbol; 372 else 373 actual_resolve_scope |= eSymbolContextSymbol; 374 } 375 } 376 377 if (resolve_scope & eSymbolContextLineEntry) 378 { 379 if (m_flags.IsClear (eSymbolContextLineEntry)) 380 { 381 if (m_sc.line_entry.IsValid()) 382 resolved |= eSymbolContextLineEntry; 383 else 384 actual_resolve_scope |= eSymbolContextLineEntry; 385 } 386 } 387 388 if (actual_resolve_scope) 389 { 390 // We might be resolving less information than what is already 391 // in our current symbol context so resolve into a temporary 392 // symbol context "sc" so we don't clear out data we have 393 // already found in "m_sc" 394 SymbolContext sc; 395 // Set flags that indicate what we have tried to resolve 396 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); 397 // Only replace what we didn't already have as we may have 398 // information for an inlined function scope that won't match 399 // what a standard lookup by address would match 400 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL) 401 m_sc.comp_unit = sc.comp_unit; 402 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL) 403 m_sc.function = sc.function; 404 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL) 405 m_sc.block = sc.block; 406 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL) 407 m_sc.symbol = sc.symbol; 408 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) 409 m_sc.line_entry = sc.line_entry; 410 411 } 412 } 413 else 414 { 415 // If we don't have a module, then we can't have the compile unit, 416 // function, block, line entry or symbol, so we can safely call 417 // ResolveSymbolContextForAddress with our symbol context member m_sc. 418 resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 419 } 420 421 // If the target was requested add that: 422 if (m_sc.target_sp.get() == NULL) 423 { 424 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP(); 425 if (m_sc.target_sp) 426 resolved |= eSymbolContextTarget; 427 } 428 429 // Update our internal flags so we remember what we have tried to locate so 430 // we don't have to keep trying when more calls to this function are made. 431 // We might have dug up more information that was requested (for example 432 // if we were asked to only get the block, we will have gotten the 433 // compile unit, and function) so set any additional bits that we resolved 434 m_flags.Set (resolve_scope | resolved); 435 } 436 437 // Return the symbol context with everything that was possible to resolve 438 // resolved. 439 return m_sc; 440 } 441 442 443 VariableList * 444 StackFrame::GetVariableList (bool get_file_globals) 445 { 446 if (m_flags.IsClear(RESOLVED_VARIABLES)) 447 { 448 m_flags.Set(RESOLVED_VARIABLES); 449 450 Block *frame_block = GetFrameBlock(); 451 452 if (frame_block) 453 { 454 const bool get_child_variables = true; 455 const bool can_create = true; 456 m_variable_list_sp = frame_block->GetVariableList (get_child_variables, can_create); 457 } 458 } 459 460 if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && 461 get_file_globals) 462 { 463 m_flags.Set(RESOLVED_GLOBAL_VARIABLES); 464 465 if (m_flags.IsClear (eSymbolContextCompUnit)) 466 GetSymbolContext (eSymbolContextCompUnit); 467 468 if (m_sc.comp_unit) 469 { 470 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 471 if (m_variable_list_sp) 472 m_variable_list_sp->AddVariables (global_variable_list_sp.get()); 473 else 474 m_variable_list_sp = global_variable_list_sp; 475 } 476 } 477 478 return m_variable_list_sp.get(); 479 } 480 481 482 bool 483 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 484 { 485 if (m_flags.IsClear(GOT_FRAME_BASE)) 486 { 487 if (m_sc.function) 488 { 489 m_frame_base.Clear(); 490 m_frame_base_error.Clear(); 491 492 m_flags.Set(GOT_FRAME_BASE); 493 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this); 494 Value expr_value; 495 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; 496 if (m_sc.function->GetFrameBaseExpression().IsLocationList()) 497 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess().GetTarget()); 498 499 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false) 500 { 501 // We should really have an error if evaluate returns, but in case 502 // we don't, lets set the error to something at least. 503 if (m_frame_base_error.Success()) 504 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 505 } 506 else 507 { 508 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL); 509 } 510 } 511 else 512 { 513 m_frame_base_error.SetErrorString ("No function in symbol context."); 514 } 515 } 516 517 if (m_frame_base_error.Success()) 518 frame_base = m_frame_base; 519 520 if (error_ptr) 521 *error_ptr = m_frame_base_error; 522 return m_frame_base_error.Success(); 523 } 524 525 RegisterContext * 526 StackFrame::GetRegisterContext () 527 { 528 if (m_reg_context_sp.get() == NULL) 529 m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this)); 530 return m_reg_context_sp.get(); 531 } 532 533 bool 534 StackFrame::HasDebugInformation () 535 { 536 GetSymbolContext (eSymbolContextLineEntry); 537 return m_sc.line_entry.IsValid(); 538 } 539 540 541 ValueObjectSP 542 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp) 543 { 544 ValueObjectSP valobj_sp; 545 VariableList *var_list = GetVariableList (true); 546 if (var_list) 547 { 548 // Make sure the variable is a frame variable 549 const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get()); 550 const uint32_t num_variables = var_list->GetSize(); 551 if (var_idx < num_variables) 552 { 553 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); 554 if (valobj_sp.get() == NULL) 555 { 556 if (m_variable_list_value_objects.GetSize() < num_variables) 557 m_variable_list_value_objects.Resize(num_variables); 558 valobj_sp.reset (new ValueObjectVariable (variable_sp)); 559 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp); 560 } 561 } 562 } 563 return valobj_sp; 564 } 565 566 ValueObjectSP 567 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp) 568 { 569 // Check to make sure we aren't already tracking this variable? 570 ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp)); 571 if (!valobj_sp) 572 { 573 // We aren't already tracking this global 574 VariableList *var_list = GetVariableList (true); 575 // If this frame has no variables, create a new list 576 if (var_list == NULL) 577 m_variable_list_sp.reset (new VariableList()); 578 579 // Add the global/static variable to this frame 580 m_variable_list_sp->AddVariable (variable_sp); 581 582 // Now make a value object for it so we can track its changes 583 valobj_sp = GetValueObjectForFrameVariable (variable_sp); 584 } 585 return valobj_sp; 586 } 587 588 bool 589 StackFrame::IsInlined () 590 { 591 if (m_sc.block == NULL) 592 GetSymbolContext (eSymbolContextBlock); 593 if (m_sc.block) 594 return m_sc.block->GetContainingInlinedBlock() != NULL; 595 return false; 596 } 597 598 Target * 599 StackFrame::CalculateTarget () 600 { 601 return m_thread.CalculateTarget(); 602 } 603 604 Process * 605 StackFrame::CalculateProcess () 606 { 607 return m_thread.CalculateProcess(); 608 } 609 610 Thread * 611 StackFrame::CalculateThread () 612 { 613 return &m_thread; 614 } 615 616 StackFrame * 617 StackFrame::CalculateStackFrame () 618 { 619 return this; 620 } 621 622 623 void 624 StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx) 625 { 626 m_thread.CalculateExecutionContext (exe_ctx); 627 exe_ctx.frame = this; 628 } 629 630 void 631 StackFrame::DumpUsingSettingsFormat (Stream *strm) 632 { 633 if (strm == NULL) 634 return; 635 636 GetSymbolContext(eSymbolContextEverything); 637 ExecutionContext exe_ctx; 638 CalculateExecutionContext(exe_ctx); 639 const char *end = NULL; 640 StreamString s; 641 const char *frame_format = m_thread.GetProcess().GetTarget().GetDebugger().GetFrameFormat(); 642 if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s, &end)) 643 { 644 strm->Write(s.GetData(), s.GetSize()); 645 } 646 else 647 { 648 Dump (strm, true, false); 649 strm->EOL(); 650 } 651 } 652 653 void 654 StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) 655 { 656 if (strm == NULL) 657 return; 658 659 if (show_frame_index) 660 strm->Printf("frame #%u: ", m_frame_index); 661 strm->Printf("0x%0*llx ", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess().GetTarget())); 662 GetSymbolContext(eSymbolContextEverything); 663 const bool show_module = true; 664 const bool show_inline = true; 665 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_fullpaths, show_module, show_inline); 666 } 667 668 void 669 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) 670 { 671 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing 672 m_variable_list_sp = prev_frame.m_variable_list_sp; 673 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); 674 if (!m_disassembly.GetString().empty()) 675 m_disassembly.GetString().swap (m_disassembly.GetString()); 676 } 677 678 679 void 680 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) 681 { 682 assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing 683 m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value 684 assert (&m_thread == &curr_frame.m_thread); 685 m_frame_index = curr_frame.m_frame_index; 686 m_unwind_frame_index = curr_frame.m_unwind_frame_index; 687 m_reg_context_sp = curr_frame.m_reg_context_sp; 688 m_frame_code_addr = curr_frame.m_frame_code_addr; 689 assert (m_sc.target_sp.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); 690 assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get()); 691 assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); 692 assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); 693 m_sc = curr_frame.m_sc; 694 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); 695 m_flags.Set (m_sc.GetResolvedMask()); 696 m_frame_base.Clear(); 697 m_frame_base_error.Clear(); 698 } 699 700 701 bool 702 StackFrame::HasCachedData () const 703 { 704 if (m_variable_list_sp.get()) 705 return true; 706 if (m_variable_list_value_objects.GetSize() > 0) 707 return true; 708 if (!m_disassembly.GetString().empty()) 709 return true; 710 return false; 711 } 712 713 lldb::StackFrameSP 714 StackFrame::GetSP () 715 { 716 return m_thread.GetStackFrameSPForStackFramePtr (this); 717 }