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