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 ValueObjectSP 482 StackFrame::GetValueForVariableExpressionPath (const char *var_expr) 483 { 484 bool deref = false; 485 bool address_of = false; 486 ValueObjectSP valobj_sp; 487 const bool get_file_globals = true; 488 VariableList *variable_list = GetVariableList (get_file_globals); 489 490 if (variable_list) 491 { 492 // If first character is a '*', then show pointer contents 493 if (var_expr[0] == '*') 494 { 495 deref = true; 496 var_expr++; // Skip the '*' 497 } 498 else if (var_expr[0] == '&') 499 { 500 address_of = true; 501 var_expr++; // Skip the '&' 502 } 503 504 std::string var_path (var_expr); 505 size_t separator_idx = var_path.find_first_of(".-["); 506 507 ConstString name_const_string; 508 if (separator_idx == std::string::npos) 509 name_const_string.SetCString (var_path.c_str()); 510 else 511 name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); 512 513 VariableSP var_sp (variable_list->FindVariable(name_const_string)); 514 if (var_sp) 515 { 516 valobj_sp = GetValueObjectForFrameVariable (var_sp); 517 518 var_path.erase (0, name_const_string.GetLength ()); 519 // We are dumping at least one child 520 while (separator_idx != std::string::npos) 521 { 522 // Calculate the next separator index ahead of time 523 ValueObjectSP child_valobj_sp; 524 const char separator_type = var_path[0]; 525 switch (separator_type) 526 { 527 528 case '-': 529 if (var_path.size() >= 2 && var_path[1] != '>') 530 return ValueObjectSP(); 531 532 var_path.erase (0, 1); // Remove the '-' 533 // Fall through 534 case '.': 535 { 536 // We either have a pointer type and need to verify 537 // valobj_sp is a pointer, or we have a member of a 538 // class/union/struct being accessed with the . syntax 539 // and need to verify we don't have a pointer. 540 const bool is_ptr = var_path[0] == '>'; 541 542 if (valobj_sp->IsPointerType () != is_ptr) 543 { 544 // Incorrect use of "." with a pointer, or "->" with 545 // a class/union/struct instance or reference. 546 return ValueObjectSP(); 547 } 548 549 var_path.erase (0, 1); // Remove the '.' or '>' 550 separator_idx = var_path.find_first_of(".-["); 551 ConstString child_name; 552 if (separator_idx == std::string::npos) 553 child_name.SetCString (var_path.c_str()); 554 else 555 child_name.SetCStringWithLength(var_path.c_str(), separator_idx); 556 557 child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); 558 if (!child_valobj_sp) 559 { 560 // No child member with name "child_name" 561 return ValueObjectSP(); 562 } 563 // Remove the child name from the path 564 var_path.erase(0, child_name.GetLength()); 565 } 566 break; 567 568 case '[': 569 // Array member access, or treating pointer as an array 570 if (var_path.size() > 2) // Need at least two brackets and a number 571 { 572 char *end = NULL; 573 int32_t child_index = ::strtol (&var_path[1], &end, 0); 574 if (end && *end == ']') 575 { 576 577 if (valobj_sp->IsPointerType ()) 578 { 579 child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true); 580 } 581 else 582 { 583 child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); 584 } 585 586 if (!child_valobj_sp) 587 { 588 // Invalid array index... 589 return ValueObjectSP(); 590 } 591 592 // Erase the array member specification '[%i]' where 593 // %i is the array index 594 var_path.erase(0, (end - var_path.c_str()) + 1); 595 separator_idx = var_path.find_first_of(".-["); 596 597 // Break out early from the switch since we were 598 // able to find the child member 599 break; 600 } 601 } 602 return ValueObjectSP(); 603 604 default: 605 // Failure... 606 return ValueObjectSP(); 607 } 608 609 if (child_valobj_sp) 610 valobj_sp = child_valobj_sp; 611 612 if (var_path.empty()) 613 break; 614 615 } 616 if (valobj_sp) 617 { 618 if (deref) 619 { 620 ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(this, NULL)); 621 valobj_sp = deref_valobj_sp; 622 } 623 else if (address_of) 624 { 625 ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf()); 626 valobj_sp = address_of_valobj_sp; 627 } 628 } 629 return valobj_sp; 630 } 631 } 632 return ValueObjectSP(); 633 } 634 635 bool 636 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 637 { 638 if (m_flags.IsClear(GOT_FRAME_BASE)) 639 { 640 if (m_sc.function) 641 { 642 m_frame_base.Clear(); 643 m_frame_base_error.Clear(); 644 645 m_flags.Set(GOT_FRAME_BASE); 646 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this); 647 Value expr_value; 648 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; 649 if (m_sc.function->GetFrameBaseExpression().IsLocationList()) 650 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess().GetTarget()); 651 652 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false) 653 { 654 // We should really have an error if evaluate returns, but in case 655 // we don't, lets set the error to something at least. 656 if (m_frame_base_error.Success()) 657 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 658 } 659 else 660 { 661 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL); 662 } 663 } 664 else 665 { 666 m_frame_base_error.SetErrorString ("No function in symbol context."); 667 } 668 } 669 670 if (m_frame_base_error.Success()) 671 frame_base = m_frame_base; 672 673 if (error_ptr) 674 *error_ptr = m_frame_base_error; 675 return m_frame_base_error.Success(); 676 } 677 678 RegisterContext * 679 StackFrame::GetRegisterContext () 680 { 681 if (m_reg_context_sp.get() == NULL) 682 m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this)); 683 return m_reg_context_sp.get(); 684 } 685 686 bool 687 StackFrame::HasDebugInformation () 688 { 689 GetSymbolContext (eSymbolContextLineEntry); 690 return m_sc.line_entry.IsValid(); 691 } 692 693 694 ValueObjectSP 695 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp) 696 { 697 ValueObjectSP valobj_sp; 698 VariableList *var_list = GetVariableList (true); 699 if (var_list) 700 { 701 // Make sure the variable is a frame variable 702 const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get()); 703 const uint32_t num_variables = var_list->GetSize(); 704 if (var_idx < num_variables) 705 { 706 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); 707 if (valobj_sp.get() == NULL) 708 { 709 if (m_variable_list_value_objects.GetSize() < num_variables) 710 m_variable_list_value_objects.Resize(num_variables); 711 valobj_sp.reset (new ValueObjectVariable (variable_sp)); 712 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp); 713 } 714 } 715 } 716 return valobj_sp; 717 } 718 719 ValueObjectSP 720 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp) 721 { 722 // Check to make sure we aren't already tracking this variable? 723 ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp)); 724 if (!valobj_sp) 725 { 726 // We aren't already tracking this global 727 VariableList *var_list = GetVariableList (true); 728 // If this frame has no variables, create a new list 729 if (var_list == NULL) 730 m_variable_list_sp.reset (new VariableList()); 731 732 // Add the global/static variable to this frame 733 m_variable_list_sp->AddVariable (variable_sp); 734 735 // Now make a value object for it so we can track its changes 736 valobj_sp = GetValueObjectForFrameVariable (variable_sp); 737 } 738 return valobj_sp; 739 } 740 741 bool 742 StackFrame::IsInlined () 743 { 744 if (m_sc.block == NULL) 745 GetSymbolContext (eSymbolContextBlock); 746 if (m_sc.block) 747 return m_sc.block->GetContainingInlinedBlock() != NULL; 748 return false; 749 } 750 751 Target * 752 StackFrame::CalculateTarget () 753 { 754 return m_thread.CalculateTarget(); 755 } 756 757 Process * 758 StackFrame::CalculateProcess () 759 { 760 return m_thread.CalculateProcess(); 761 } 762 763 Thread * 764 StackFrame::CalculateThread () 765 { 766 return &m_thread; 767 } 768 769 StackFrame * 770 StackFrame::CalculateStackFrame () 771 { 772 return this; 773 } 774 775 776 void 777 StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx) 778 { 779 m_thread.CalculateExecutionContext (exe_ctx); 780 exe_ctx.frame = this; 781 } 782 783 void 784 StackFrame::DumpUsingSettingsFormat (Stream *strm) 785 { 786 if (strm == NULL) 787 return; 788 789 GetSymbolContext(eSymbolContextEverything); 790 ExecutionContext exe_ctx; 791 CalculateExecutionContext(exe_ctx); 792 const char *end = NULL; 793 StreamString s; 794 const char *frame_format = m_thread.GetProcess().GetTarget().GetDebugger().GetFrameFormat(); 795 if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s, &end)) 796 { 797 strm->Write(s.GetData(), s.GetSize()); 798 } 799 else 800 { 801 Dump (strm, true, false); 802 strm->EOL(); 803 } 804 } 805 806 void 807 StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) 808 { 809 if (strm == NULL) 810 return; 811 812 if (show_frame_index) 813 strm->Printf("frame #%u: ", m_frame_index); 814 strm->Printf("0x%0*llx ", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess().GetTarget())); 815 GetSymbolContext(eSymbolContextEverything); 816 const bool show_module = true; 817 const bool show_inline = true; 818 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_fullpaths, show_module, show_inline); 819 } 820 821 void 822 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) 823 { 824 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing 825 m_variable_list_sp = prev_frame.m_variable_list_sp; 826 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); 827 if (!m_disassembly.GetString().empty()) 828 m_disassembly.GetString().swap (m_disassembly.GetString()); 829 } 830 831 832 void 833 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) 834 { 835 assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing 836 m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value 837 assert (&m_thread == &curr_frame.m_thread); 838 m_frame_index = curr_frame.m_frame_index; 839 m_unwind_frame_index = curr_frame.m_unwind_frame_index; 840 m_reg_context_sp = curr_frame.m_reg_context_sp; 841 m_frame_code_addr = curr_frame.m_frame_code_addr; 842 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()); 843 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()); 844 assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); 845 assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); 846 m_sc = curr_frame.m_sc; 847 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); 848 m_flags.Set (m_sc.GetResolvedMask()); 849 m_frame_base.Clear(); 850 m_frame_base_error.Clear(); 851 } 852 853 854 bool 855 StackFrame::HasCachedData () const 856 { 857 if (m_variable_list_sp.get()) 858 return true; 859 if (m_variable_list_value_objects.GetSize() > 0) 860 return true; 861 if (!m_disassembly.GetString().empty()) 862 return true; 863 return false; 864 } 865 866 lldb::StackFrameSP 867 StackFrame::GetSP () 868 { 869 return m_thread.GetStackFrameSPForStackFramePtr (this); 870 }