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