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/FormatEntity.h" 20 #include "lldb/Core/Value.h" 21 #include "lldb/Core/ValueObjectVariable.h" 22 #include "lldb/Core/ValueObjectConstResult.h" 23 #include "lldb/Symbol/CompileUnit.h" 24 #include "lldb/Symbol/Function.h" 25 #include "lldb/Symbol/Symbol.h" 26 #include "lldb/Symbol/SymbolContextScope.h" 27 #include "lldb/Symbol/Type.h" 28 #include "lldb/Symbol/VariableList.h" 29 #include "lldb/Target/ExecutionContext.h" 30 #include "lldb/Target/Process.h" 31 #include "lldb/Target/RegisterContext.h" 32 #include "lldb/Target/Target.h" 33 #include "lldb/Target/Thread.h" 34 35 using namespace lldb; 36 using namespace lldb_private; 37 38 // The first bits in the flags are reserved for the SymbolContext::Scope bits 39 // so we know if we have tried to look up information in our internal symbol 40 // context (m_sc) already. 41 #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) 42 #define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1) 43 #define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1) 44 #define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) 45 #define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1) 46 47 StackFrame::StackFrame (const ThreadSP &thread_sp, 48 user_id_t frame_idx, 49 user_id_t unwind_frame_index, 50 addr_t cfa, 51 bool cfa_is_valid, 52 addr_t pc, 53 uint32_t stop_id, 54 bool stop_id_is_valid, 55 bool is_history_frame, 56 const SymbolContext *sc_ptr) : 57 m_thread_wp (thread_sp), 58 m_frame_index (frame_idx), 59 m_concrete_frame_index (unwind_frame_index), 60 m_reg_context_sp (), 61 m_id (pc, cfa, NULL), 62 m_frame_code_addr (pc), 63 m_sc (), 64 m_flags (), 65 m_frame_base (), 66 m_frame_base_error (), 67 m_cfa_is_valid (cfa_is_valid), 68 m_stop_id (stop_id), 69 m_stop_id_is_valid (stop_id_is_valid), 70 m_is_history_frame (is_history_frame), 71 m_variable_list_sp (), 72 m_variable_list_value_objects (), 73 m_disassembly (), 74 m_mutex (Mutex::eMutexTypeRecursive) 75 { 76 // If we don't have a CFA value, use the frame index for our StackID so that recursive 77 // functions properly aren't confused with one another on a history stack. 78 if (m_is_history_frame && m_cfa_is_valid == false) 79 { 80 m_id.SetCFA (m_frame_index); 81 } 82 83 if (sc_ptr != NULL) 84 { 85 m_sc = *sc_ptr; 86 m_flags.Set(m_sc.GetResolvedMask ()); 87 } 88 } 89 90 StackFrame::StackFrame (const ThreadSP &thread_sp, 91 user_id_t frame_idx, 92 user_id_t unwind_frame_index, 93 const RegisterContextSP ®_context_sp, 94 addr_t cfa, 95 addr_t pc, 96 const SymbolContext *sc_ptr) : 97 m_thread_wp (thread_sp), 98 m_frame_index (frame_idx), 99 m_concrete_frame_index (unwind_frame_index), 100 m_reg_context_sp (reg_context_sp), 101 m_id (pc, cfa, NULL), 102 m_frame_code_addr (pc), 103 m_sc (), 104 m_flags (), 105 m_frame_base (), 106 m_frame_base_error (), 107 m_cfa_is_valid (true), 108 m_stop_id (0), 109 m_stop_id_is_valid (false), 110 m_is_history_frame (false), 111 m_variable_list_sp (), 112 m_variable_list_value_objects (), 113 m_disassembly (), 114 m_mutex (Mutex::eMutexTypeRecursive) 115 { 116 if (sc_ptr != NULL) 117 { 118 m_sc = *sc_ptr; 119 m_flags.Set(m_sc.GetResolvedMask ()); 120 } 121 122 if (reg_context_sp && !m_sc.target_sp) 123 { 124 m_sc.target_sp = reg_context_sp->CalculateTarget(); 125 if (m_sc.target_sp) 126 m_flags.Set (eSymbolContextTarget); 127 } 128 } 129 130 StackFrame::StackFrame (const ThreadSP &thread_sp, 131 user_id_t frame_idx, 132 user_id_t unwind_frame_index, 133 const RegisterContextSP ®_context_sp, 134 addr_t cfa, 135 const Address& pc_addr, 136 const SymbolContext *sc_ptr) : 137 m_thread_wp (thread_sp), 138 m_frame_index (frame_idx), 139 m_concrete_frame_index (unwind_frame_index), 140 m_reg_context_sp (reg_context_sp), 141 m_id (pc_addr.GetLoadAddress (thread_sp->CalculateTarget().get()), cfa, NULL), 142 m_frame_code_addr (pc_addr), 143 m_sc (), 144 m_flags (), 145 m_frame_base (), 146 m_frame_base_error (), 147 m_cfa_is_valid (true), 148 m_stop_id (0), 149 m_stop_id_is_valid (false), 150 m_is_history_frame (false), 151 m_variable_list_sp (), 152 m_variable_list_value_objects (), 153 m_disassembly (), 154 m_mutex (Mutex::eMutexTypeRecursive) 155 { 156 if (sc_ptr != NULL) 157 { 158 m_sc = *sc_ptr; 159 m_flags.Set(m_sc.GetResolvedMask ()); 160 } 161 162 if (m_sc.target_sp.get() == NULL && reg_context_sp) 163 { 164 m_sc.target_sp = reg_context_sp->CalculateTarget(); 165 if (m_sc.target_sp) 166 m_flags.Set (eSymbolContextTarget); 167 } 168 169 ModuleSP pc_module_sp (pc_addr.GetModule()); 170 if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) 171 { 172 if (pc_module_sp) 173 { 174 m_sc.module_sp = pc_module_sp; 175 m_flags.Set (eSymbolContextModule); 176 } 177 else 178 { 179 m_sc.module_sp.reset(); 180 } 181 } 182 } 183 184 185 //---------------------------------------------------------------------- 186 // Destructor 187 //---------------------------------------------------------------------- 188 StackFrame::~StackFrame() 189 { 190 } 191 192 StackID& 193 StackFrame::GetStackID() 194 { 195 Mutex::Locker locker(m_mutex); 196 // Make sure we have resolved the StackID object's symbol context scope if 197 // we already haven't looked it up. 198 199 if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE)) 200 { 201 if (m_id.GetSymbolContextScope ()) 202 { 203 // We already have a symbol context scope, we just don't have our 204 // flag bit set. 205 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 206 } 207 else 208 { 209 // Calculate the frame block and use this for the stack ID symbol 210 // context scope if we have one. 211 SymbolContextScope *scope = GetFrameBlock (); 212 if (scope == NULL) 213 { 214 // We don't have a block, so use the symbol 215 if (m_flags.IsClear (eSymbolContextSymbol)) 216 GetSymbolContext (eSymbolContextSymbol); 217 218 // It is ok if m_sc.symbol is NULL here 219 scope = m_sc.symbol; 220 } 221 // Set the symbol context scope (the accessor will set the 222 // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags). 223 SetSymbolContextScope (scope); 224 } 225 } 226 return m_id; 227 } 228 229 uint32_t 230 StackFrame::GetFrameIndex () const 231 { 232 ThreadSP thread_sp = GetThread(); 233 if (thread_sp) 234 return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index); 235 else 236 return m_frame_index; 237 } 238 239 void 240 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) 241 { 242 Mutex::Locker locker(m_mutex); 243 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 244 m_id.SetSymbolContextScope (symbol_scope); 245 } 246 247 const Address& 248 StackFrame::GetFrameCodeAddress() 249 { 250 Mutex::Locker locker(m_mutex); 251 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) 252 { 253 m_flags.Set (RESOLVED_FRAME_CODE_ADDR); 254 255 // Resolve the PC into a temporary address because if ResolveLoadAddress 256 // fails to resolve the address, it will clear the address object... 257 ThreadSP thread_sp (GetThread()); 258 if (thread_sp) 259 { 260 TargetSP target_sp (thread_sp->CalculateTarget()); 261 if (target_sp) 262 { 263 if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), target_sp.get(), eAddressClassCode)) 264 { 265 ModuleSP module_sp (m_frame_code_addr.GetModule()); 266 if (module_sp) 267 { 268 m_sc.module_sp = module_sp; 269 m_flags.Set(eSymbolContextModule); 270 } 271 } 272 } 273 } 274 } 275 return m_frame_code_addr; 276 } 277 278 bool 279 StackFrame::ChangePC (addr_t pc) 280 { 281 Mutex::Locker locker(m_mutex); 282 // We can't change the pc value of a history stack frame - it is immutable. 283 if (m_is_history_frame) 284 return false; 285 m_frame_code_addr.SetRawAddress(pc); 286 m_sc.Clear(false); 287 m_flags.Reset(0); 288 ThreadSP thread_sp (GetThread()); 289 if (thread_sp) 290 thread_sp->ClearStackFrames (); 291 return true; 292 } 293 294 const char * 295 StackFrame::Disassemble () 296 { 297 Mutex::Locker locker(m_mutex); 298 if (m_disassembly.GetSize() == 0) 299 { 300 ExecutionContext exe_ctx (shared_from_this()); 301 Target *target = exe_ctx.GetTargetPtr(); 302 if (target) 303 { 304 const char *plugin_name = NULL; 305 const char *flavor = NULL; 306 Disassembler::Disassemble (target->GetDebugger(), 307 target->GetArchitecture(), 308 plugin_name, 309 flavor, 310 exe_ctx, 311 0, 312 0, 313 0, 314 m_disassembly); 315 } 316 if (m_disassembly.GetSize() == 0) 317 return NULL; 318 } 319 return m_disassembly.GetData(); 320 } 321 322 Block * 323 StackFrame::GetFrameBlock () 324 { 325 if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock)) 326 GetSymbolContext (eSymbolContextBlock); 327 328 if (m_sc.block) 329 { 330 Block *inline_block = m_sc.block->GetContainingInlinedBlock(); 331 if (inline_block) 332 { 333 // Use the block with the inlined function info 334 // as the frame block we want this frame to have only the variables 335 // for the inlined function and its non-inlined block child blocks. 336 return inline_block; 337 } 338 else 339 { 340 // This block is not contained withing any inlined function blocks 341 // with so we want to use the top most function block. 342 return &m_sc.function->GetBlock (false); 343 } 344 } 345 return NULL; 346 } 347 348 //---------------------------------------------------------------------- 349 // Get the symbol context if we already haven't done so by resolving the 350 // PC address as much as possible. This way when we pass around a 351 // StackFrame object, everyone will have as much information as 352 // possible and no one will ever have to look things up manually. 353 //---------------------------------------------------------------------- 354 const SymbolContext& 355 StackFrame::GetSymbolContext (uint32_t resolve_scope) 356 { 357 Mutex::Locker locker(m_mutex); 358 // Copy our internal symbol context into "sc". 359 if ((m_flags.Get() & resolve_scope) != resolve_scope) 360 { 361 uint32_t resolved = 0; 362 363 // If the target was requested add that: 364 if (!m_sc.target_sp) 365 { 366 m_sc.target_sp = CalculateTarget(); 367 if (m_sc.target_sp) 368 resolved |= eSymbolContextTarget; 369 } 370 371 372 // Resolve our PC to section offset if we haven't already done so 373 // and if we don't have a module. The resolved address section will 374 // contain the module to which it belongs 375 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) 376 GetFrameCodeAddress(); 377 378 // If this is not frame zero, then we need to subtract 1 from the PC 379 // value when doing address lookups since the PC will be on the 380 // instruction following the function call instruction... 381 382 Address lookup_addr(GetFrameCodeAddress()); 383 if (m_frame_index > 0 && lookup_addr.IsValid()) 384 { 385 addr_t offset = lookup_addr.GetOffset(); 386 if (offset > 0) 387 { 388 lookup_addr.SetOffset(offset - 1); 389 390 } 391 else 392 { 393 // lookup_addr is the start of a section. We need 394 // do the math on the actual load address and re-compute 395 // the section. We're working with a 'noreturn' function 396 // at the end of a section. 397 ThreadSP thread_sp (GetThread()); 398 if (thread_sp) 399 { 400 TargetSP target_sp (thread_sp->CalculateTarget()); 401 if (target_sp) 402 { 403 addr_t addr_minus_one = lookup_addr.GetLoadAddress(target_sp.get()) - 1; 404 lookup_addr.SetLoadAddress (addr_minus_one, target_sp.get()); 405 } 406 else 407 { 408 lookup_addr.SetOffset(offset - 1); 409 } 410 } 411 } 412 } 413 414 415 if (m_sc.module_sp) 416 { 417 // We have something in our stack frame symbol context, lets check 418 // if we haven't already tried to lookup one of those things. If we 419 // haven't then we will do the query. 420 421 uint32_t actual_resolve_scope = 0; 422 423 if (resolve_scope & eSymbolContextCompUnit) 424 { 425 if (m_flags.IsClear (eSymbolContextCompUnit)) 426 { 427 if (m_sc.comp_unit) 428 resolved |= eSymbolContextCompUnit; 429 else 430 actual_resolve_scope |= eSymbolContextCompUnit; 431 } 432 } 433 434 if (resolve_scope & eSymbolContextFunction) 435 { 436 if (m_flags.IsClear (eSymbolContextFunction)) 437 { 438 if (m_sc.function) 439 resolved |= eSymbolContextFunction; 440 else 441 actual_resolve_scope |= eSymbolContextFunction; 442 } 443 } 444 445 if (resolve_scope & eSymbolContextBlock) 446 { 447 if (m_flags.IsClear (eSymbolContextBlock)) 448 { 449 if (m_sc.block) 450 resolved |= eSymbolContextBlock; 451 else 452 actual_resolve_scope |= eSymbolContextBlock; 453 } 454 } 455 456 if (resolve_scope & eSymbolContextSymbol) 457 { 458 if (m_flags.IsClear (eSymbolContextSymbol)) 459 { 460 if (m_sc.symbol) 461 resolved |= eSymbolContextSymbol; 462 else 463 actual_resolve_scope |= eSymbolContextSymbol; 464 } 465 } 466 467 if (resolve_scope & eSymbolContextLineEntry) 468 { 469 if (m_flags.IsClear (eSymbolContextLineEntry)) 470 { 471 if (m_sc.line_entry.IsValid()) 472 resolved |= eSymbolContextLineEntry; 473 else 474 actual_resolve_scope |= eSymbolContextLineEntry; 475 } 476 } 477 478 if (actual_resolve_scope) 479 { 480 // We might be resolving less information than what is already 481 // in our current symbol context so resolve into a temporary 482 // symbol context "sc" so we don't clear out data we have 483 // already found in "m_sc" 484 SymbolContext sc; 485 // Set flags that indicate what we have tried to resolve 486 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); 487 // Only replace what we didn't already have as we may have 488 // information for an inlined function scope that won't match 489 // what a standard lookup by address would match 490 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL) 491 m_sc.comp_unit = sc.comp_unit; 492 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL) 493 m_sc.function = sc.function; 494 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL) 495 m_sc.block = sc.block; 496 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL) 497 m_sc.symbol = sc.symbol; 498 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) 499 { 500 m_sc.line_entry = sc.line_entry; 501 if (m_sc.target_sp) 502 { 503 // Be sure to apply and file remappings to our file and line 504 // entries when handing out a line entry 505 FileSpec new_file_spec; 506 if (m_sc.target_sp->GetSourcePathMap().FindFile (m_sc.line_entry.file, new_file_spec)) 507 m_sc.line_entry.file = new_file_spec; 508 } 509 } 510 } 511 } 512 else 513 { 514 // If we don't have a module, then we can't have the compile unit, 515 // function, block, line entry or symbol, so we can safely call 516 // ResolveSymbolContextForAddress with our symbol context member m_sc. 517 if (m_sc.target_sp) 518 { 519 resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 520 } 521 } 522 523 // Update our internal flags so we remember what we have tried to locate so 524 // we don't have to keep trying when more calls to this function are made. 525 // We might have dug up more information that was requested (for example 526 // if we were asked to only get the block, we will have gotten the 527 // compile unit, and function) so set any additional bits that we resolved 528 m_flags.Set (resolve_scope | resolved); 529 } 530 531 // Return the symbol context with everything that was possible to resolve 532 // resolved. 533 return m_sc; 534 } 535 536 537 VariableList * 538 StackFrame::GetVariableList (bool get_file_globals) 539 { 540 Mutex::Locker locker(m_mutex); 541 if (m_flags.IsClear(RESOLVED_VARIABLES)) 542 { 543 m_flags.Set(RESOLVED_VARIABLES); 544 545 Block *frame_block = GetFrameBlock(); 546 547 if (frame_block) 548 { 549 const bool get_child_variables = true; 550 const bool can_create = true; 551 const bool stop_if_child_block_is_inlined_function = true; 552 m_variable_list_sp.reset(new VariableList()); 553 frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, m_variable_list_sp.get()); 554 } 555 } 556 557 if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && 558 get_file_globals) 559 { 560 m_flags.Set(RESOLVED_GLOBAL_VARIABLES); 561 562 if (m_flags.IsClear (eSymbolContextCompUnit)) 563 GetSymbolContext (eSymbolContextCompUnit); 564 565 if (m_sc.comp_unit) 566 { 567 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 568 if (m_variable_list_sp) 569 m_variable_list_sp->AddVariables (global_variable_list_sp.get()); 570 else 571 m_variable_list_sp = global_variable_list_sp; 572 } 573 } 574 575 return m_variable_list_sp.get(); 576 } 577 578 VariableListSP 579 StackFrame::GetInScopeVariableList (bool get_file_globals) 580 { 581 Mutex::Locker locker(m_mutex); 582 // We can't fetch variable information for a history stack frame. 583 if (m_is_history_frame) 584 return VariableListSP(); 585 586 VariableListSP var_list_sp(new VariableList); 587 GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock); 588 589 if (m_sc.block) 590 { 591 const bool can_create = true; 592 const bool get_parent_variables = true; 593 const bool stop_if_block_is_inlined_function = true; 594 m_sc.block->AppendVariables (can_create, 595 get_parent_variables, 596 stop_if_block_is_inlined_function, 597 var_list_sp.get()); 598 } 599 600 if (m_sc.comp_unit) 601 { 602 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 603 if (global_variable_list_sp) 604 var_list_sp->AddVariables (global_variable_list_sp.get()); 605 } 606 607 return var_list_sp; 608 } 609 610 611 ValueObjectSP 612 StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, 613 DynamicValueType use_dynamic, 614 uint32_t options, 615 VariableSP &var_sp, 616 Error &error) 617 { 618 // We can't fetch variable information for a history stack frame. 619 if (m_is_history_frame) 620 return ValueObjectSP(); 621 622 if (var_expr_cstr && var_expr_cstr[0]) 623 { 624 const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0; 625 const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0; 626 const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0; 627 //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0; 628 error.Clear(); 629 bool deref = false; 630 bool address_of = false; 631 ValueObjectSP valobj_sp; 632 const bool get_file_globals = true; 633 // When looking up a variable for an expression, we need only consider the 634 // variables that are in scope. 635 VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals)); 636 VariableList *variable_list = var_list_sp.get(); 637 638 if (variable_list) 639 { 640 // If first character is a '*', then show pointer contents 641 const char *var_expr = var_expr_cstr; 642 if (var_expr[0] == '*') 643 { 644 deref = true; 645 var_expr++; // Skip the '*' 646 } 647 else if (var_expr[0] == '&') 648 { 649 address_of = true; 650 var_expr++; // Skip the '&' 651 } 652 653 std::string var_path (var_expr); 654 size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}"); 655 StreamString var_expr_path_strm; 656 657 ConstString name_const_string; 658 if (separator_idx == std::string::npos) 659 name_const_string.SetCString (var_path.c_str()); 660 else 661 name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); 662 663 var_sp = variable_list->FindVariable(name_const_string, false); 664 665 bool synthetically_added_instance_object = false; 666 667 if (var_sp) 668 { 669 var_path.erase (0, name_const_string.GetLength ()); 670 } 671 672 if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) 673 { 674 // Check for direct ivars access which helps us with implicit 675 // access to ivars with the "this->" or "self->" 676 GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock); 677 lldb::LanguageType method_language = eLanguageTypeUnknown; 678 bool is_instance_method = false; 679 ConstString method_object_name; 680 if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name)) 681 { 682 if (is_instance_method && method_object_name) 683 { 684 var_sp = variable_list->FindVariable(method_object_name); 685 if (var_sp) 686 { 687 separator_idx = 0; 688 var_path.insert(0, "->"); 689 synthetically_added_instance_object = true; 690 } 691 } 692 } 693 } 694 695 if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) 696 { 697 // Check if any anonymous unions are there which contain a variable with the name we need 698 for (size_t i = 0; 699 i < variable_list->GetSize(); 700 i++) 701 { 702 if (VariableSP variable_sp = variable_list->GetVariableAtIndex(i)) 703 { 704 if (variable_sp->GetName().IsEmpty()) 705 { 706 if (Type *var_type = variable_sp->GetType()) 707 { 708 if (var_type->GetForwardCompilerType().IsAnonymousType()) 709 { 710 valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic); 711 if (!valobj_sp) 712 return valobj_sp; 713 valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string, true); 714 if (valobj_sp) 715 break; 716 } 717 } 718 } 719 } 720 } 721 } 722 723 if (var_sp && !valobj_sp) 724 { 725 valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic); 726 if (!valobj_sp) 727 return valobj_sp; 728 } 729 if (valobj_sp) 730 { 731 // We are dumping at least one child 732 while (separator_idx != std::string::npos) 733 { 734 // Calculate the next separator index ahead of time 735 ValueObjectSP child_valobj_sp; 736 const char separator_type = var_path[0]; 737 switch (separator_type) 738 { 739 740 case '-': 741 if (var_path.size() >= 2 && var_path[1] != '>') 742 return ValueObjectSP(); 743 744 if (no_fragile_ivar) 745 { 746 // Make sure we aren't trying to deref an objective 747 // C ivar if this is not allowed 748 const uint32_t pointer_type_flags = valobj_sp->GetCompilerType().GetTypeInfo (NULL); 749 if ((pointer_type_flags & eTypeIsObjC) && 750 (pointer_type_flags & eTypeIsPointer)) 751 { 752 // This was an objective C object pointer and 753 // it was requested we skip any fragile ivars 754 // so return nothing here 755 return ValueObjectSP(); 756 } 757 } 758 var_path.erase (0, 1); // Remove the '-' 759 // Fall through 760 case '.': 761 { 762 const bool expr_is_ptr = var_path[0] == '>'; 763 764 var_path.erase (0, 1); // Remove the '.' or '>' 765 separator_idx = var_path.find_first_of(".-["); 766 ConstString child_name; 767 if (separator_idx == std::string::npos) 768 child_name.SetCString (var_path.c_str()); 769 else 770 child_name.SetCStringWithLength(var_path.c_str(), separator_idx); 771 772 if (check_ptr_vs_member) 773 { 774 // We either have a pointer type and need to verify 775 // valobj_sp is a pointer, or we have a member of a 776 // class/union/struct being accessed with the . syntax 777 // and need to verify we don't have a pointer. 778 const bool actual_is_ptr = valobj_sp->IsPointerType (); 779 780 if (actual_is_ptr != expr_is_ptr) 781 { 782 // Incorrect use of "." with a pointer, or "->" with 783 // a class/union/struct instance or reference. 784 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 785 if (actual_is_ptr) 786 error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?", 787 var_expr_path_strm.GetString().c_str(), 788 child_name.GetCString(), 789 var_expr_path_strm.GetString().c_str(), 790 var_path.c_str()); 791 else 792 error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?", 793 var_expr_path_strm.GetString().c_str(), 794 child_name.GetCString(), 795 var_expr_path_strm.GetString().c_str(), 796 var_path.c_str()); 797 return ValueObjectSP(); 798 } 799 } 800 child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); 801 if (!child_valobj_sp) 802 { 803 if (no_synth_child == false) 804 { 805 child_valobj_sp = valobj_sp->GetSyntheticValue(); 806 if (child_valobj_sp) 807 child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true); 808 } 809 810 if (no_synth_child || !child_valobj_sp) 811 { 812 // No child member with name "child_name" 813 if (synthetically_added_instance_object) 814 { 815 // We added a "this->" or "self->" to the beginning of the expression 816 // and this is the first pointer ivar access, so just return the normal 817 // error 818 error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame", 819 name_const_string.GetCString()); 820 } 821 else 822 { 823 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 824 if (child_name) 825 { 826 error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"", 827 child_name.GetCString(), 828 valobj_sp->GetTypeName().AsCString("<invalid type>"), 829 var_expr_path_strm.GetString().c_str()); 830 } 831 else 832 { 833 error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"", 834 var_expr_path_strm.GetString().c_str(), 835 var_expr_cstr); 836 } 837 } 838 return ValueObjectSP(); 839 } 840 } 841 synthetically_added_instance_object = false; 842 // Remove the child name from the path 843 var_path.erase(0, child_name.GetLength()); 844 if (use_dynamic != eNoDynamicValues) 845 { 846 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 847 if (dynamic_value_sp) 848 child_valobj_sp = dynamic_value_sp; 849 } 850 } 851 break; 852 853 case '[': 854 // Array member access, or treating pointer as an array 855 if (var_path.size() > 2) // Need at least two brackets and a number 856 { 857 char *end = NULL; 858 long child_index = ::strtol (&var_path[1], &end, 0); 859 if (end && *end == ']' 860 && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go 861 { 862 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) 863 { 864 // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr 865 // and extract bit low out of it. reading array item low 866 // would be done by saying ptr[low], without a deref * sign 867 Error error; 868 ValueObjectSP temp(valobj_sp->Dereference(error)); 869 if (error.Fail()) 870 { 871 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 872 error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 873 valobj_sp->GetTypeName().AsCString("<invalid type>"), 874 var_expr_path_strm.GetString().c_str()); 875 return ValueObjectSP(); 876 } 877 valobj_sp = temp; 878 deref = false; 879 } 880 else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) 881 { 882 // what we have is *arr[low]. the most similar C++ syntax is to get arr[0] 883 // (an operation that is equivalent to deref-ing arr) 884 // and extract bit low out of it. reading array item low 885 // would be done by saying arr[low], without a deref * sign 886 Error error; 887 ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 888 if (error.Fail()) 889 { 890 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 891 error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 892 valobj_sp->GetTypeName().AsCString("<invalid type>"), 893 var_expr_path_strm.GetString().c_str()); 894 return ValueObjectSP(); 895 } 896 valobj_sp = temp; 897 deref = false; 898 } 899 900 bool is_incomplete_array = false; 901 if (valobj_sp->IsPointerType ()) 902 { 903 bool is_objc_pointer = true; 904 905 if (valobj_sp->GetCompilerType().GetMinimumLanguage() != eLanguageTypeObjC) 906 is_objc_pointer = false; 907 else if (!valobj_sp->GetCompilerType().IsPointerType()) 908 is_objc_pointer = false; 909 910 if (no_synth_child && is_objc_pointer) 911 { 912 error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted", 913 valobj_sp->GetTypeName().AsCString("<invalid type>"), 914 var_expr_path_strm.GetString().c_str()); 915 916 return ValueObjectSP(); 917 } 918 else if (is_objc_pointer) 919 { 920 // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children 921 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 922 if (synthetic.get() == NULL /* no synthetic */ 923 || synthetic == valobj_sp) /* synthetic is the same as the original object */ 924 { 925 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 926 error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 927 valobj_sp->GetTypeName().AsCString("<invalid type>"), 928 var_expr_path_strm.GetString().c_str()); 929 } 930 else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 931 { 932 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 933 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 934 child_index, 935 valobj_sp->GetTypeName().AsCString("<invalid type>"), 936 var_expr_path_strm.GetString().c_str()); 937 } 938 else 939 { 940 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 941 if (!child_valobj_sp) 942 { 943 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 944 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 945 child_index, 946 valobj_sp->GetTypeName().AsCString("<invalid type>"), 947 var_expr_path_strm.GetString().c_str()); 948 } 949 } 950 } 951 else 952 { 953 child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true); 954 if (!child_valobj_sp) 955 { 956 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 957 error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"", 958 child_index, 959 valobj_sp->GetTypeName().AsCString("<invalid type>"), 960 var_expr_path_strm.GetString().c_str()); 961 } 962 } 963 } 964 else if (valobj_sp->GetCompilerType().IsArrayType (NULL, NULL, &is_incomplete_array)) 965 { 966 // Pass false to dynamic_value here so we can tell the difference between 967 // no dynamic value and no member of this type... 968 child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); 969 if (!child_valobj_sp && (is_incomplete_array || no_synth_child == false)) 970 child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true); 971 972 if (!child_valobj_sp) 973 { 974 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 975 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 976 child_index, 977 valobj_sp->GetTypeName().AsCString("<invalid type>"), 978 var_expr_path_strm.GetString().c_str()); 979 } 980 } 981 else if (valobj_sp->GetCompilerType().IsScalarType()) 982 { 983 // this is a bitfield asking to display just one bit 984 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true); 985 if (!child_valobj_sp) 986 { 987 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 988 error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 989 child_index, child_index, 990 valobj_sp->GetTypeName().AsCString("<invalid type>"), 991 var_expr_path_strm.GetString().c_str()); 992 } 993 } 994 else 995 { 996 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 997 if (no_synth_child /* synthetic is forbidden */ || 998 synthetic.get() == NULL /* no synthetic */ 999 || synthetic == valobj_sp) /* synthetic is the same as the original object */ 1000 { 1001 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1002 error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 1003 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1004 var_expr_path_strm.GetString().c_str()); 1005 } 1006 else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 1007 { 1008 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1009 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 1010 child_index, 1011 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1012 var_expr_path_strm.GetString().c_str()); 1013 } 1014 else 1015 { 1016 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 1017 if (!child_valobj_sp) 1018 { 1019 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1020 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 1021 child_index, 1022 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1023 var_expr_path_strm.GetString().c_str()); 1024 } 1025 } 1026 } 1027 1028 if (!child_valobj_sp) 1029 { 1030 // Invalid array index... 1031 return ValueObjectSP(); 1032 } 1033 1034 // Erase the array member specification '[%i]' where 1035 // %i is the array index 1036 var_path.erase(0, (end - var_path.c_str()) + 1); 1037 separator_idx = var_path.find_first_of(".-["); 1038 if (use_dynamic != eNoDynamicValues) 1039 { 1040 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 1041 if (dynamic_value_sp) 1042 child_valobj_sp = dynamic_value_sp; 1043 } 1044 // Break out early from the switch since we were 1045 // able to find the child member 1046 break; 1047 } 1048 else if (end && *end == '-') 1049 { 1050 // this is most probably a BitField, let's take a look 1051 char *real_end = NULL; 1052 long final_index = ::strtol (end+1, &real_end, 0); 1053 bool expand_bitfield = true; 1054 if (real_end && *real_end == ']') 1055 { 1056 // if the format given is [high-low], swap range 1057 if (child_index > final_index) 1058 { 1059 long temp = child_index; 1060 child_index = final_index; 1061 final_index = temp; 1062 } 1063 1064 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) 1065 { 1066 // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr 1067 // and extract bits low thru high out of it. reading array items low thru high 1068 // would be done by saying ptr[low-high], without a deref * sign 1069 Error error; 1070 ValueObjectSP temp(valobj_sp->Dereference(error)); 1071 if (error.Fail()) 1072 { 1073 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1074 error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 1075 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1076 var_expr_path_strm.GetString().c_str()); 1077 return ValueObjectSP(); 1078 } 1079 valobj_sp = temp; 1080 deref = false; 1081 } 1082 else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) 1083 { 1084 // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0] 1085 // (an operation that is equivalent to deref-ing arr) 1086 // and extract bits low thru high out of it. reading array items low thru high 1087 // would be done by saying arr[low-high], without a deref * sign 1088 Error error; 1089 ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 1090 if (error.Fail()) 1091 { 1092 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1093 error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 1094 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1095 var_expr_path_strm.GetString().c_str()); 1096 return ValueObjectSP(); 1097 } 1098 valobj_sp = temp; 1099 deref = false; 1100 } 1101 /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType()) 1102 { 1103 child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true); 1104 expand_bitfield = false; 1105 if (!child_valobj_sp) 1106 { 1107 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1108 error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"", 1109 child_index, final_index, 1110 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1111 var_expr_path_strm.GetString().c_str()); 1112 } 1113 }*/ 1114 1115 if (expand_bitfield) 1116 { 1117 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true); 1118 if (!child_valobj_sp) 1119 { 1120 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1121 error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 1122 child_index, final_index, 1123 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1124 var_expr_path_strm.GetString().c_str()); 1125 } 1126 } 1127 } 1128 1129 if (!child_valobj_sp) 1130 { 1131 // Invalid bitfield range... 1132 return ValueObjectSP(); 1133 } 1134 1135 // Erase the bitfield member specification '[%i-%i]' where 1136 // %i is the index 1137 var_path.erase(0, (real_end - var_path.c_str()) + 1); 1138 separator_idx = var_path.find_first_of(".-["); 1139 if (use_dynamic != eNoDynamicValues) 1140 { 1141 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 1142 if (dynamic_value_sp) 1143 child_valobj_sp = dynamic_value_sp; 1144 } 1145 // Break out early from the switch since we were 1146 // able to find the child member 1147 break; 1148 1149 } 1150 } 1151 else 1152 { 1153 error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"", 1154 var_expr_path_strm.GetString().c_str(), 1155 var_path.c_str()); 1156 } 1157 return ValueObjectSP(); 1158 1159 default: 1160 // Failure... 1161 { 1162 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1163 error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"", 1164 separator_type, 1165 var_expr_path_strm.GetString().c_str(), 1166 var_path.c_str()); 1167 1168 return ValueObjectSP(); 1169 } 1170 } 1171 1172 if (child_valobj_sp) 1173 valobj_sp = child_valobj_sp; 1174 1175 if (var_path.empty()) 1176 break; 1177 1178 } 1179 if (valobj_sp) 1180 { 1181 if (deref) 1182 { 1183 ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error)); 1184 valobj_sp = deref_valobj_sp; 1185 } 1186 else if (address_of) 1187 { 1188 ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error)); 1189 valobj_sp = address_of_valobj_sp; 1190 } 1191 } 1192 return valobj_sp; 1193 } 1194 else 1195 { 1196 error.SetErrorStringWithFormat("no variable named '%s' found in this frame", 1197 name_const_string.GetCString()); 1198 } 1199 } 1200 } 1201 else 1202 { 1203 error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr); 1204 } 1205 return ValueObjectSP(); 1206 } 1207 1208 bool 1209 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 1210 { 1211 Mutex::Locker locker(m_mutex); 1212 if (m_cfa_is_valid == false) 1213 { 1214 m_frame_base_error.SetErrorString("No frame base available for this historical stack frame."); 1215 return false; 1216 } 1217 1218 if (m_flags.IsClear(GOT_FRAME_BASE)) 1219 { 1220 if (m_sc.function) 1221 { 1222 m_frame_base.Clear(); 1223 m_frame_base_error.Clear(); 1224 1225 m_flags.Set(GOT_FRAME_BASE); 1226 ExecutionContext exe_ctx (shared_from_this()); 1227 Value expr_value; 1228 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; 1229 if (m_sc.function->GetFrameBaseExpression().IsLocationList()) 1230 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr()); 1231 1232 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false) 1233 { 1234 // We should really have an error if evaluate returns, but in case 1235 // we don't, lets set the error to something at least. 1236 if (m_frame_base_error.Success()) 1237 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 1238 } 1239 else 1240 { 1241 m_frame_base = expr_value.ResolveValue(&exe_ctx); 1242 } 1243 } 1244 else 1245 { 1246 m_frame_base_error.SetErrorString ("No function in symbol context."); 1247 } 1248 } 1249 1250 if (m_frame_base_error.Success()) 1251 frame_base = m_frame_base; 1252 1253 if (error_ptr) 1254 *error_ptr = m_frame_base_error; 1255 return m_frame_base_error.Success(); 1256 } 1257 1258 RegisterContextSP 1259 StackFrame::GetRegisterContext () 1260 { 1261 Mutex::Locker locker(m_mutex); 1262 if (!m_reg_context_sp) 1263 { 1264 ThreadSP thread_sp (GetThread()); 1265 if (thread_sp) 1266 m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this); 1267 } 1268 return m_reg_context_sp; 1269 } 1270 1271 bool 1272 StackFrame::HasDebugInformation () 1273 { 1274 GetSymbolContext (eSymbolContextLineEntry); 1275 return m_sc.line_entry.IsValid(); 1276 } 1277 1278 1279 ValueObjectSP 1280 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 1281 { 1282 Mutex::Locker locker(m_mutex); 1283 ValueObjectSP valobj_sp; 1284 if (m_is_history_frame) 1285 { 1286 return valobj_sp; 1287 } 1288 VariableList *var_list = GetVariableList (true); 1289 if (var_list) 1290 { 1291 // Make sure the variable is a frame variable 1292 const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get()); 1293 const uint32_t num_variables = var_list->GetSize(); 1294 if (var_idx < num_variables) 1295 { 1296 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); 1297 if (valobj_sp.get() == NULL) 1298 { 1299 if (m_variable_list_value_objects.GetSize() < num_variables) 1300 m_variable_list_value_objects.Resize(num_variables); 1301 valobj_sp = ValueObjectVariable::Create (this, variable_sp); 1302 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp); 1303 } 1304 } 1305 } 1306 if (use_dynamic != eNoDynamicValues && valobj_sp) 1307 { 1308 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic); 1309 if (dynamic_sp) 1310 return dynamic_sp; 1311 } 1312 return valobj_sp; 1313 } 1314 1315 ValueObjectSP 1316 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 1317 { 1318 Mutex::Locker locker(m_mutex); 1319 if (m_is_history_frame) 1320 return ValueObjectSP(); 1321 1322 // Check to make sure we aren't already tracking this variable? 1323 ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic)); 1324 if (!valobj_sp) 1325 { 1326 // We aren't already tracking this global 1327 VariableList *var_list = GetVariableList (true); 1328 // If this frame has no variables, create a new list 1329 if (var_list == NULL) 1330 m_variable_list_sp.reset (new VariableList()); 1331 1332 // Add the global/static variable to this frame 1333 m_variable_list_sp->AddVariable (variable_sp); 1334 1335 // Now make a value object for it so we can track its changes 1336 valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic); 1337 } 1338 return valobj_sp; 1339 } 1340 1341 bool 1342 StackFrame::IsInlined () 1343 { 1344 if (m_sc.block == NULL) 1345 GetSymbolContext (eSymbolContextBlock); 1346 if (m_sc.block) 1347 return m_sc.block->GetContainingInlinedBlock() != NULL; 1348 return false; 1349 } 1350 1351 lldb::LanguageType 1352 StackFrame::GetLanguage () 1353 { 1354 CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit; 1355 if (cu) 1356 return cu->GetLanguage(); 1357 return lldb::eLanguageTypeUnknown; 1358 } 1359 1360 TargetSP 1361 StackFrame::CalculateTarget () 1362 { 1363 TargetSP target_sp; 1364 ThreadSP thread_sp(GetThread()); 1365 if (thread_sp) 1366 { 1367 ProcessSP process_sp (thread_sp->CalculateProcess()); 1368 if (process_sp) 1369 target_sp = process_sp->CalculateTarget(); 1370 } 1371 return target_sp; 1372 } 1373 1374 ProcessSP 1375 StackFrame::CalculateProcess () 1376 { 1377 ProcessSP process_sp; 1378 ThreadSP thread_sp(GetThread()); 1379 if (thread_sp) 1380 process_sp = thread_sp->CalculateProcess(); 1381 return process_sp; 1382 } 1383 1384 ThreadSP 1385 StackFrame::CalculateThread () 1386 { 1387 return GetThread(); 1388 } 1389 1390 StackFrameSP 1391 StackFrame::CalculateStackFrame () 1392 { 1393 return shared_from_this(); 1394 } 1395 1396 1397 void 1398 StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx) 1399 { 1400 exe_ctx.SetContext (shared_from_this()); 1401 } 1402 1403 void 1404 StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker) 1405 { 1406 if (strm == NULL) 1407 return; 1408 1409 GetSymbolContext(eSymbolContextEverything); 1410 ExecutionContext exe_ctx (shared_from_this()); 1411 StreamString s; 1412 1413 if (frame_marker) 1414 s.PutCString(frame_marker); 1415 1416 const FormatEntity::Entry *frame_format = NULL; 1417 Target *target = exe_ctx.GetTargetPtr(); 1418 if (target) 1419 frame_format = target->GetDebugger().GetFrameFormat(); 1420 if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, NULL, NULL, false, false)) 1421 { 1422 strm->Write(s.GetData(), s.GetSize()); 1423 } 1424 else 1425 { 1426 Dump (strm, true, false); 1427 strm->EOL(); 1428 } 1429 } 1430 1431 void 1432 StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) 1433 { 1434 if (strm == NULL) 1435 return; 1436 1437 if (show_frame_index) 1438 strm->Printf("frame #%u: ", m_frame_index); 1439 ExecutionContext exe_ctx (shared_from_this()); 1440 Target *target = exe_ctx.GetTargetPtr(); 1441 strm->Printf("0x%0*" PRIx64 " ", 1442 target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16, 1443 GetFrameCodeAddress().GetLoadAddress(target)); 1444 GetSymbolContext(eSymbolContextEverything); 1445 const bool show_module = true; 1446 const bool show_inline = true; 1447 const bool show_function_arguments = true; 1448 const bool show_function_name = true; 1449 m_sc.DumpStopContext (strm, 1450 exe_ctx.GetBestExecutionContextScope(), 1451 GetFrameCodeAddress(), 1452 show_fullpaths, 1453 show_module, 1454 show_inline, 1455 show_function_arguments, 1456 show_function_name); 1457 } 1458 1459 void 1460 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) 1461 { 1462 Mutex::Locker locker(m_mutex); 1463 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing 1464 m_variable_list_sp = prev_frame.m_variable_list_sp; 1465 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); 1466 if (!m_disassembly.GetString().empty()) 1467 m_disassembly.GetString().swap (m_disassembly.GetString()); 1468 } 1469 1470 1471 void 1472 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) 1473 { 1474 Mutex::Locker locker(m_mutex); 1475 assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing 1476 m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value 1477 assert (GetThread() == curr_frame.GetThread()); 1478 m_frame_index = curr_frame.m_frame_index; 1479 m_concrete_frame_index = curr_frame.m_concrete_frame_index; 1480 m_reg_context_sp = curr_frame.m_reg_context_sp; 1481 m_frame_code_addr = curr_frame.m_frame_code_addr; 1482 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()); 1483 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()); 1484 assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); 1485 assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); 1486 m_sc = curr_frame.m_sc; 1487 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); 1488 m_flags.Set (m_sc.GetResolvedMask()); 1489 m_frame_base.Clear(); 1490 m_frame_base_error.Clear(); 1491 } 1492 1493 1494 bool 1495 StackFrame::HasCachedData () const 1496 { 1497 if (m_variable_list_sp.get()) 1498 return true; 1499 if (m_variable_list_value_objects.GetSize() > 0) 1500 return true; 1501 if (!m_disassembly.GetString().empty()) 1502 return true; 1503 return false; 1504 } 1505 1506 bool 1507 StackFrame::GetStatus (Stream& strm, 1508 bool show_frame_info, 1509 bool show_source, 1510 const char *frame_marker) 1511 { 1512 1513 if (show_frame_info) 1514 { 1515 strm.Indent(); 1516 DumpUsingSettingsFormat (&strm, frame_marker); 1517 } 1518 1519 if (show_source) 1520 { 1521 ExecutionContext exe_ctx (shared_from_this()); 1522 bool have_source = false, have_debuginfo = false; 1523 Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever; 1524 Target *target = exe_ctx.GetTargetPtr(); 1525 if (target) 1526 { 1527 Debugger &debugger = target->GetDebugger(); 1528 const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true); 1529 const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false); 1530 disasm_display = debugger.GetStopDisassemblyDisplay (); 1531 1532 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry); 1533 if (m_sc.comp_unit && m_sc.line_entry.IsValid()) 1534 { 1535 have_debuginfo = true; 1536 if (source_lines_before > 0 || source_lines_after > 0) 1537 { 1538 size_t num_lines = target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file, 1539 m_sc.line_entry.line, 1540 source_lines_before, 1541 source_lines_after, 1542 "->", 1543 &strm); 1544 if (num_lines != 0) 1545 have_source = true; 1546 // TODO: Give here a one time warning if source file is missing. 1547 } 1548 } 1549 switch (disasm_display) 1550 { 1551 case Debugger::eStopDisassemblyTypeNever: 1552 break; 1553 1554 case Debugger::eStopDisassemblyTypeNoDebugInfo: 1555 if (have_debuginfo) 1556 break; 1557 // Fall through to next case 1558 1559 case Debugger::eStopDisassemblyTypeNoSource: 1560 if (have_source) 1561 break; 1562 // Fall through to next case 1563 1564 case Debugger::eStopDisassemblyTypeAlways: 1565 if (target) 1566 { 1567 const uint32_t disasm_lines = debugger.GetDisassemblyLineCount(); 1568 if (disasm_lines > 0) 1569 { 1570 const ArchSpec &target_arch = target->GetArchitecture(); 1571 AddressRange pc_range; 1572 pc_range.GetBaseAddress() = GetFrameCodeAddress(); 1573 pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize()); 1574 const char *plugin_name = NULL; 1575 const char *flavor = NULL; 1576 Disassembler::Disassemble (target->GetDebugger(), 1577 target_arch, 1578 plugin_name, 1579 flavor, 1580 exe_ctx, 1581 pc_range, 1582 disasm_lines, 1583 0, 1584 Disassembler::eOptionMarkPCAddress, 1585 strm); 1586 } 1587 } 1588 break; 1589 } 1590 } 1591 } 1592 return true; 1593 } 1594 1595