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/Core/ValueObjectMemory.h" 24 #include "lldb/Symbol/CompileUnit.h" 25 #include "lldb/Symbol/Function.h" 26 #include "lldb/Symbol/Symbol.h" 27 #include "lldb/Symbol/SymbolContextScope.h" 28 #include "lldb/Symbol/Type.h" 29 #include "lldb/Symbol/VariableList.h" 30 #include "lldb/Target/ABI.h" 31 #include "lldb/Target/ExecutionContext.h" 32 #include "lldb/Target/Process.h" 33 #include "lldb/Target/RegisterContext.h" 34 #include "lldb/Target/Target.h" 35 #include "lldb/Target/Thread.h" 36 37 using namespace lldb; 38 using namespace lldb_private; 39 40 // The first bits in the flags are reserved for the SymbolContext::Scope bits 41 // so we know if we have tried to look up information in our internal symbol 42 // context (m_sc) already. 43 #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) 44 #define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1) 45 #define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1) 46 #define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) 47 #define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1) 48 49 StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, addr_t cfa, 50 bool cfa_is_valid, addr_t pc, uint32_t stop_id, bool stop_id_is_valid, bool is_history_frame, 51 const SymbolContext *sc_ptr) 52 : m_thread_wp(thread_sp), 53 m_frame_index(frame_idx), 54 m_concrete_frame_index(unwind_frame_index), 55 m_reg_context_sp(), 56 m_id(pc, cfa, nullptr), 57 m_frame_code_addr(pc), 58 m_sc(), 59 m_flags(), 60 m_frame_base(), 61 m_frame_base_error(), 62 m_cfa_is_valid(cfa_is_valid), 63 m_stop_id(stop_id), 64 m_stop_id_is_valid(stop_id_is_valid), 65 m_is_history_frame(is_history_frame), 66 m_variable_list_sp(), 67 m_variable_list_value_objects(), 68 m_disassembly(), 69 m_mutex() 70 { 71 // If we don't have a CFA value, use the frame index for our StackID so that recursive 72 // functions properly aren't confused with one another on a history stack. 73 if (m_is_history_frame && !m_cfa_is_valid) 74 { 75 m_id.SetCFA(m_frame_index); 76 } 77 78 if (sc_ptr != nullptr) 79 { 80 m_sc = *sc_ptr; 81 m_flags.Set(m_sc.GetResolvedMask()); 82 } 83 } 84 85 StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, 86 const RegisterContextSP ®_context_sp, addr_t cfa, addr_t pc, const SymbolContext *sc_ptr) 87 : m_thread_wp(thread_sp), 88 m_frame_index(frame_idx), 89 m_concrete_frame_index(unwind_frame_index), 90 m_reg_context_sp(reg_context_sp), 91 m_id(pc, cfa, nullptr), 92 m_frame_code_addr(pc), 93 m_sc(), 94 m_flags(), 95 m_frame_base(), 96 m_frame_base_error(), 97 m_cfa_is_valid(true), 98 m_stop_id(0), 99 m_stop_id_is_valid(false), 100 m_is_history_frame(false), 101 m_variable_list_sp(), 102 m_variable_list_value_objects(), 103 m_disassembly(), 104 m_mutex() 105 { 106 if (sc_ptr != nullptr) 107 { 108 m_sc = *sc_ptr; 109 m_flags.Set(m_sc.GetResolvedMask()); 110 } 111 112 if (reg_context_sp && !m_sc.target_sp) 113 { 114 m_sc.target_sp = reg_context_sp->CalculateTarget(); 115 if (m_sc.target_sp) 116 m_flags.Set(eSymbolContextTarget); 117 } 118 } 119 120 StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, 121 const RegisterContextSP ®_context_sp, addr_t cfa, const Address &pc_addr, 122 const SymbolContext *sc_ptr) 123 : m_thread_wp(thread_sp), 124 m_frame_index(frame_idx), 125 m_concrete_frame_index(unwind_frame_index), 126 m_reg_context_sp(reg_context_sp), 127 m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa, nullptr), 128 m_frame_code_addr(pc_addr), 129 m_sc(), 130 m_flags(), 131 m_frame_base(), 132 m_frame_base_error(), 133 m_cfa_is_valid(true), 134 m_stop_id(0), 135 m_stop_id_is_valid(false), 136 m_is_history_frame(false), 137 m_variable_list_sp(), 138 m_variable_list_value_objects(), 139 m_disassembly(), 140 m_mutex() 141 { 142 if (sc_ptr != nullptr) 143 { 144 m_sc = *sc_ptr; 145 m_flags.Set(m_sc.GetResolvedMask()); 146 } 147 148 if (!m_sc.target_sp && reg_context_sp) 149 { 150 m_sc.target_sp = reg_context_sp->CalculateTarget(); 151 if (m_sc.target_sp) 152 m_flags.Set(eSymbolContextTarget); 153 } 154 155 ModuleSP pc_module_sp(pc_addr.GetModule()); 156 if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) 157 { 158 if (pc_module_sp) 159 { 160 m_sc.module_sp = pc_module_sp; 161 m_flags.Set(eSymbolContextModule); 162 } 163 else 164 { 165 m_sc.module_sp.reset(); 166 } 167 } 168 } 169 170 StackFrame::~StackFrame() = default; 171 172 StackID& 173 StackFrame::GetStackID() 174 { 175 std::lock_guard<std::recursive_mutex> guard(m_mutex); 176 // Make sure we have resolved the StackID object's symbol context scope if 177 // we already haven't looked it up. 178 179 if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE)) 180 { 181 if (m_id.GetSymbolContextScope ()) 182 { 183 // We already have a symbol context scope, we just don't have our 184 // flag bit set. 185 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 186 } 187 else 188 { 189 // Calculate the frame block and use this for the stack ID symbol 190 // context scope if we have one. 191 SymbolContextScope *scope = GetFrameBlock (); 192 if (scope == nullptr) 193 { 194 // We don't have a block, so use the symbol 195 if (m_flags.IsClear (eSymbolContextSymbol)) 196 GetSymbolContext (eSymbolContextSymbol); 197 198 // It is ok if m_sc.symbol is nullptr here 199 scope = m_sc.symbol; 200 } 201 // Set the symbol context scope (the accessor will set the 202 // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags). 203 SetSymbolContextScope (scope); 204 } 205 } 206 return m_id; 207 } 208 209 uint32_t 210 StackFrame::GetFrameIndex () const 211 { 212 ThreadSP thread_sp = GetThread(); 213 if (thread_sp) 214 return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index); 215 else 216 return m_frame_index; 217 } 218 219 void 220 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) 221 { 222 std::lock_guard<std::recursive_mutex> guard(m_mutex); 223 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 224 m_id.SetSymbolContextScope (symbol_scope); 225 } 226 227 const Address& 228 StackFrame::GetFrameCodeAddress() 229 { 230 std::lock_guard<std::recursive_mutex> guard(m_mutex); 231 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) 232 { 233 m_flags.Set (RESOLVED_FRAME_CODE_ADDR); 234 235 // Resolve the PC into a temporary address because if ResolveLoadAddress 236 // fails to resolve the address, it will clear the address object... 237 ThreadSP thread_sp (GetThread()); 238 if (thread_sp) 239 { 240 TargetSP target_sp (thread_sp->CalculateTarget()); 241 if (target_sp) 242 { 243 if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), target_sp.get(), eAddressClassCode)) 244 { 245 ModuleSP module_sp (m_frame_code_addr.GetModule()); 246 if (module_sp) 247 { 248 m_sc.module_sp = module_sp; 249 m_flags.Set(eSymbolContextModule); 250 } 251 } 252 } 253 } 254 } 255 return m_frame_code_addr; 256 } 257 258 bool 259 StackFrame::ChangePC (addr_t pc) 260 { 261 std::lock_guard<std::recursive_mutex> guard(m_mutex); 262 // We can't change the pc value of a history stack frame - it is immutable. 263 if (m_is_history_frame) 264 return false; 265 m_frame_code_addr.SetRawAddress(pc); 266 m_sc.Clear(false); 267 m_flags.Reset(0); 268 ThreadSP thread_sp (GetThread()); 269 if (thread_sp) 270 thread_sp->ClearStackFrames (); 271 return true; 272 } 273 274 const char * 275 StackFrame::Disassemble () 276 { 277 std::lock_guard<std::recursive_mutex> guard(m_mutex); 278 if (m_disassembly.GetSize() == 0) 279 { 280 ExecutionContext exe_ctx (shared_from_this()); 281 Target *target = exe_ctx.GetTargetPtr(); 282 if (target) 283 { 284 const char *plugin_name = nullptr; 285 const char *flavor = nullptr; 286 Disassembler::Disassemble (target->GetDebugger(), 287 target->GetArchitecture(), 288 plugin_name, 289 flavor, 290 exe_ctx, 291 0, 292 0, 293 0, 294 m_disassembly); 295 } 296 if (m_disassembly.GetSize() == 0) 297 return nullptr; 298 } 299 return m_disassembly.GetData(); 300 } 301 302 Block * 303 StackFrame::GetFrameBlock () 304 { 305 if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock)) 306 GetSymbolContext (eSymbolContextBlock); 307 308 if (m_sc.block) 309 { 310 Block *inline_block = m_sc.block->GetContainingInlinedBlock(); 311 if (inline_block) 312 { 313 // Use the block with the inlined function info 314 // as the frame block we want this frame to have only the variables 315 // for the inlined function and its non-inlined block child blocks. 316 return inline_block; 317 } 318 else 319 { 320 // This block is not contained within any inlined function blocks 321 // with so we want to use the top most function block. 322 return &m_sc.function->GetBlock (false); 323 } 324 } 325 return nullptr; 326 } 327 328 //---------------------------------------------------------------------- 329 // Get the symbol context if we already haven't done so by resolving the 330 // PC address as much as possible. This way when we pass around a 331 // StackFrame object, everyone will have as much information as 332 // possible and no one will ever have to look things up manually. 333 //---------------------------------------------------------------------- 334 const SymbolContext& 335 StackFrame::GetSymbolContext (uint32_t resolve_scope) 336 { 337 std::lock_guard<std::recursive_mutex> guard(m_mutex); 338 // Copy our internal symbol context into "sc". 339 if ((m_flags.Get() & resolve_scope) != resolve_scope) 340 { 341 uint32_t resolved = 0; 342 343 // If the target was requested add that: 344 if (!m_sc.target_sp) 345 { 346 m_sc.target_sp = CalculateTarget(); 347 if (m_sc.target_sp) 348 resolved |= eSymbolContextTarget; 349 } 350 351 // Resolve our PC to section offset if we haven't already done so 352 // and if we don't have a module. The resolved address section will 353 // contain the module to which it belongs 354 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) 355 GetFrameCodeAddress(); 356 357 // If this is not frame zero, then we need to subtract 1 from the PC 358 // value when doing address lookups since the PC will be on the 359 // instruction following the function call instruction... 360 361 Address lookup_addr(GetFrameCodeAddress()); 362 if (m_frame_index > 0 && lookup_addr.IsValid()) 363 { 364 addr_t offset = lookup_addr.GetOffset(); 365 if (offset > 0) 366 { 367 lookup_addr.SetOffset(offset - 1); 368 369 } 370 else 371 { 372 // lookup_addr is the start of a section. We need 373 // do the math on the actual load address and re-compute 374 // the section. We're working with a 'noreturn' function 375 // at the end of a section. 376 ThreadSP thread_sp (GetThread()); 377 if (thread_sp) 378 { 379 TargetSP target_sp (thread_sp->CalculateTarget()); 380 if (target_sp) 381 { 382 addr_t addr_minus_one = lookup_addr.GetLoadAddress(target_sp.get()) - 1; 383 lookup_addr.SetLoadAddress (addr_minus_one, target_sp.get()); 384 } 385 else 386 { 387 lookup_addr.SetOffset(offset - 1); 388 } 389 } 390 } 391 } 392 393 if (m_sc.module_sp) 394 { 395 // We have something in our stack frame symbol context, lets check 396 // if we haven't already tried to lookup one of those things. If we 397 // haven't then we will do the query. 398 399 uint32_t actual_resolve_scope = 0; 400 401 if (resolve_scope & eSymbolContextCompUnit) 402 { 403 if (m_flags.IsClear (eSymbolContextCompUnit)) 404 { 405 if (m_sc.comp_unit) 406 resolved |= eSymbolContextCompUnit; 407 else 408 actual_resolve_scope |= eSymbolContextCompUnit; 409 } 410 } 411 412 if (resolve_scope & eSymbolContextFunction) 413 { 414 if (m_flags.IsClear (eSymbolContextFunction)) 415 { 416 if (m_sc.function) 417 resolved |= eSymbolContextFunction; 418 else 419 actual_resolve_scope |= eSymbolContextFunction; 420 } 421 } 422 423 if (resolve_scope & eSymbolContextBlock) 424 { 425 if (m_flags.IsClear (eSymbolContextBlock)) 426 { 427 if (m_sc.block) 428 resolved |= eSymbolContextBlock; 429 else 430 actual_resolve_scope |= eSymbolContextBlock; 431 } 432 } 433 434 if (resolve_scope & eSymbolContextSymbol) 435 { 436 if (m_flags.IsClear (eSymbolContextSymbol)) 437 { 438 if (m_sc.symbol) 439 resolved |= eSymbolContextSymbol; 440 else 441 actual_resolve_scope |= eSymbolContextSymbol; 442 } 443 } 444 445 if (resolve_scope & eSymbolContextLineEntry) 446 { 447 if (m_flags.IsClear (eSymbolContextLineEntry)) 448 { 449 if (m_sc.line_entry.IsValid()) 450 resolved |= eSymbolContextLineEntry; 451 else 452 actual_resolve_scope |= eSymbolContextLineEntry; 453 } 454 } 455 456 if (actual_resolve_scope) 457 { 458 // We might be resolving less information than what is already 459 // in our current symbol context so resolve into a temporary 460 // symbol context "sc" so we don't clear out data we have 461 // already found in "m_sc" 462 SymbolContext sc; 463 // Set flags that indicate what we have tried to resolve 464 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); 465 // Only replace what we didn't already have as we may have 466 // information for an inlined function scope that won't match 467 // what a standard lookup by address would match 468 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == nullptr) 469 m_sc.comp_unit = sc.comp_unit; 470 if ((resolved & eSymbolContextFunction) && m_sc.function == nullptr) 471 m_sc.function = sc.function; 472 if ((resolved & eSymbolContextBlock) && m_sc.block == nullptr) 473 m_sc.block = sc.block; 474 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == nullptr) 475 m_sc.symbol = sc.symbol; 476 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) 477 { 478 m_sc.line_entry = sc.line_entry; 479 m_sc.line_entry.ApplyFileMappings(m_sc.target_sp); 480 } 481 } 482 } 483 else 484 { 485 // If we don't have a module, then we can't have the compile unit, 486 // function, block, line entry or symbol, so we can safely call 487 // ResolveSymbolContextForAddress with our symbol context member m_sc. 488 if (m_sc.target_sp) 489 { 490 resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 491 } 492 } 493 494 // Update our internal flags so we remember what we have tried to locate so 495 // we don't have to keep trying when more calls to this function are made. 496 // We might have dug up more information that was requested (for example 497 // if we were asked to only get the block, we will have gotten the 498 // compile unit, and function) so set any additional bits that we resolved 499 m_flags.Set (resolve_scope | resolved); 500 } 501 502 // Return the symbol context with everything that was possible to resolve 503 // resolved. 504 return m_sc; 505 } 506 507 VariableList * 508 StackFrame::GetVariableList (bool get_file_globals) 509 { 510 std::lock_guard<std::recursive_mutex> guard(m_mutex); 511 if (m_flags.IsClear(RESOLVED_VARIABLES)) 512 { 513 m_flags.Set(RESOLVED_VARIABLES); 514 515 Block *frame_block = GetFrameBlock(); 516 517 if (frame_block) 518 { 519 const bool get_child_variables = true; 520 const bool can_create = true; 521 const bool stop_if_child_block_is_inlined_function = true; 522 m_variable_list_sp.reset(new VariableList()); 523 frame_block->AppendBlockVariables(can_create, 524 get_child_variables, 525 stop_if_child_block_is_inlined_function, 526 [this](Variable* v) { return true; }, 527 m_variable_list_sp.get()); 528 } 529 } 530 531 if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && 532 get_file_globals) 533 { 534 m_flags.Set(RESOLVED_GLOBAL_VARIABLES); 535 536 if (m_flags.IsClear (eSymbolContextCompUnit)) 537 GetSymbolContext (eSymbolContextCompUnit); 538 539 if (m_sc.comp_unit) 540 { 541 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 542 if (m_variable_list_sp) 543 m_variable_list_sp->AddVariables (global_variable_list_sp.get()); 544 else 545 m_variable_list_sp = global_variable_list_sp; 546 } 547 } 548 549 return m_variable_list_sp.get(); 550 } 551 552 VariableListSP 553 StackFrame::GetInScopeVariableList (bool get_file_globals, bool must_have_valid_location) 554 { 555 std::lock_guard<std::recursive_mutex> guard(m_mutex); 556 // We can't fetch variable information for a history stack frame. 557 if (m_is_history_frame) 558 return VariableListSP(); 559 560 VariableListSP var_list_sp(new VariableList); 561 GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock); 562 563 if (m_sc.block) 564 { 565 const bool can_create = true; 566 const bool get_parent_variables = true; 567 const bool stop_if_block_is_inlined_function = true; 568 m_sc.block->AppendVariables (can_create, 569 get_parent_variables, 570 stop_if_block_is_inlined_function, 571 [this, must_have_valid_location](Variable* v) 572 { 573 return v->IsInScope(this) && (!must_have_valid_location || v->LocationIsValidForFrame(this)); 574 }, 575 var_list_sp.get()); 576 } 577 578 if (m_sc.comp_unit && get_file_globals) 579 { 580 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 581 if (global_variable_list_sp) 582 var_list_sp->AddVariables (global_variable_list_sp.get()); 583 } 584 585 return var_list_sp; 586 } 587 588 ValueObjectSP 589 StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, 590 DynamicValueType use_dynamic, 591 uint32_t options, 592 VariableSP &var_sp, 593 Error &error) 594 { 595 // We can't fetch variable information for a history stack frame. 596 if (m_is_history_frame) 597 return ValueObjectSP(); 598 599 if (var_expr_cstr && var_expr_cstr[0]) 600 { 601 const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0; 602 const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0; 603 const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0; 604 //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0; 605 error.Clear(); 606 bool deref = false; 607 bool address_of = false; 608 ValueObjectSP valobj_sp; 609 const bool get_file_globals = true; 610 // When looking up a variable for an expression, we need only consider the 611 // variables that are in scope. 612 VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals)); 613 VariableList *variable_list = var_list_sp.get(); 614 615 if (variable_list) 616 { 617 // If first character is a '*', then show pointer contents 618 const char *var_expr = var_expr_cstr; 619 if (var_expr[0] == '*') 620 { 621 deref = true; 622 var_expr++; // Skip the '*' 623 } 624 else if (var_expr[0] == '&') 625 { 626 address_of = true; 627 var_expr++; // Skip the '&' 628 } 629 630 std::string var_path (var_expr); 631 size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}"); 632 StreamString var_expr_path_strm; 633 634 ConstString name_const_string; 635 if (separator_idx == std::string::npos) 636 name_const_string.SetCString (var_path.c_str()); 637 else 638 name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); 639 640 var_sp = variable_list->FindVariable(name_const_string, false); 641 642 bool synthetically_added_instance_object = false; 643 644 if (var_sp) 645 { 646 var_path.erase (0, name_const_string.GetLength ()); 647 } 648 649 if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) 650 { 651 // Check for direct ivars access which helps us with implicit 652 // access to ivars with the "this->" or "self->" 653 GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock); 654 lldb::LanguageType method_language = eLanguageTypeUnknown; 655 bool is_instance_method = false; 656 ConstString method_object_name; 657 if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name)) 658 { 659 if (is_instance_method && method_object_name) 660 { 661 var_sp = variable_list->FindVariable(method_object_name); 662 if (var_sp) 663 { 664 separator_idx = 0; 665 var_path.insert(0, "->"); 666 synthetically_added_instance_object = true; 667 } 668 } 669 } 670 } 671 672 if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) 673 { 674 // Check if any anonymous unions are there which contain a variable with the name we need 675 for (size_t i = 0; 676 i < variable_list->GetSize(); 677 i++) 678 { 679 if (VariableSP variable_sp = variable_list->GetVariableAtIndex(i)) 680 { 681 if (variable_sp->GetName().IsEmpty()) 682 { 683 if (Type *var_type = variable_sp->GetType()) 684 { 685 if (var_type->GetForwardCompilerType().IsAnonymousType()) 686 { 687 valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic); 688 if (!valobj_sp) 689 return valobj_sp; 690 valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string, true); 691 if (valobj_sp) 692 break; 693 } 694 } 695 } 696 } 697 } 698 } 699 700 if (var_sp && !valobj_sp) 701 { 702 valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic); 703 if (!valobj_sp) 704 return valobj_sp; 705 } 706 if (valobj_sp) 707 { 708 // We are dumping at least one child 709 while (separator_idx != std::string::npos) 710 { 711 // Calculate the next separator index ahead of time 712 ValueObjectSP child_valobj_sp; 713 const char separator_type = var_path[0]; 714 switch (separator_type) 715 { 716 case '-': 717 if (var_path.size() >= 2 && var_path[1] != '>') 718 return ValueObjectSP(); 719 720 if (no_fragile_ivar) 721 { 722 // Make sure we aren't trying to deref an objective 723 // C ivar if this is not allowed 724 const uint32_t pointer_type_flags = valobj_sp->GetCompilerType().GetTypeInfo(nullptr); 725 if ((pointer_type_flags & eTypeIsObjC) && 726 (pointer_type_flags & eTypeIsPointer)) 727 { 728 // This was an objective C object pointer and 729 // it was requested we skip any fragile ivars 730 // so return nothing here 731 return ValueObjectSP(); 732 } 733 } 734 var_path.erase (0, 1); // Remove the '-' 735 LLVM_FALLTHROUGH; 736 case '.': 737 { 738 const bool expr_is_ptr = var_path[0] == '>'; 739 740 var_path.erase (0, 1); // Remove the '.' or '>' 741 separator_idx = var_path.find_first_of(".-["); 742 ConstString child_name; 743 if (separator_idx == std::string::npos) 744 child_name.SetCString (var_path.c_str()); 745 else 746 child_name.SetCStringWithLength(var_path.c_str(), separator_idx); 747 748 if (check_ptr_vs_member) 749 { 750 // We either have a pointer type and need to verify 751 // valobj_sp is a pointer, or we have a member of a 752 // class/union/struct being accessed with the . syntax 753 // and need to verify we don't have a pointer. 754 const bool actual_is_ptr = valobj_sp->IsPointerType (); 755 756 if (actual_is_ptr != expr_is_ptr) 757 { 758 // Incorrect use of "." with a pointer, or "->" with 759 // a class/union/struct instance or reference. 760 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 761 if (actual_is_ptr) 762 error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?", 763 var_expr_path_strm.GetString().c_str(), 764 child_name.GetCString(), 765 var_expr_path_strm.GetString().c_str(), 766 var_path.c_str()); 767 else 768 error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?", 769 var_expr_path_strm.GetString().c_str(), 770 child_name.GetCString(), 771 var_expr_path_strm.GetString().c_str(), 772 var_path.c_str()); 773 return ValueObjectSP(); 774 } 775 } 776 child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); 777 if (!child_valobj_sp) 778 { 779 if (!no_synth_child) 780 { 781 child_valobj_sp = valobj_sp->GetSyntheticValue(); 782 if (child_valobj_sp) 783 child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true); 784 } 785 786 if (no_synth_child || !child_valobj_sp) 787 { 788 // No child member with name "child_name" 789 if (synthetically_added_instance_object) 790 { 791 // We added a "this->" or "self->" to the beginning of the expression 792 // and this is the first pointer ivar access, so just return the normal 793 // error 794 error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame", 795 name_const_string.GetCString()); 796 } 797 else 798 { 799 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 800 if (child_name) 801 { 802 error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"", 803 child_name.GetCString(), 804 valobj_sp->GetTypeName().AsCString("<invalid type>"), 805 var_expr_path_strm.GetString().c_str()); 806 } 807 else 808 { 809 error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"", 810 var_expr_path_strm.GetString().c_str(), 811 var_expr_cstr); 812 } 813 } 814 return ValueObjectSP(); 815 } 816 } 817 synthetically_added_instance_object = false; 818 // Remove the child name from the path 819 var_path.erase(0, child_name.GetLength()); 820 if (use_dynamic != eNoDynamicValues) 821 { 822 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 823 if (dynamic_value_sp) 824 child_valobj_sp = dynamic_value_sp; 825 } 826 } 827 break; 828 829 case '[': 830 // Array member access, or treating pointer as an array 831 if (var_path.size() > 2) // Need at least two brackets and a number 832 { 833 char *end = nullptr; 834 long child_index = ::strtol (&var_path[1], &end, 0); 835 if (end && *end == ']' 836 && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go 837 { 838 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) 839 { 840 // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr 841 // and extract bit low out of it. reading array item low 842 // would be done by saying ptr[low], without a deref * sign 843 Error error; 844 ValueObjectSP temp(valobj_sp->Dereference(error)); 845 if (error.Fail()) 846 { 847 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 848 error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 849 valobj_sp->GetTypeName().AsCString("<invalid type>"), 850 var_expr_path_strm.GetString().c_str()); 851 return ValueObjectSP(); 852 } 853 valobj_sp = temp; 854 deref = false; 855 } 856 else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) 857 { 858 // what we have is *arr[low]. the most similar C++ syntax is to get arr[0] 859 // (an operation that is equivalent to deref-ing arr) 860 // and extract bit low out of it. reading array item low 861 // would be done by saying arr[low], without a deref * sign 862 Error error; 863 ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 864 if (error.Fail()) 865 { 866 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 867 error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 868 valobj_sp->GetTypeName().AsCString("<invalid type>"), 869 var_expr_path_strm.GetString().c_str()); 870 return ValueObjectSP(); 871 } 872 valobj_sp = temp; 873 deref = false; 874 } 875 876 bool is_incomplete_array = false; 877 if (valobj_sp->IsPointerType ()) 878 { 879 bool is_objc_pointer = true; 880 881 if (valobj_sp->GetCompilerType().GetMinimumLanguage() != eLanguageTypeObjC) 882 is_objc_pointer = false; 883 else if (!valobj_sp->GetCompilerType().IsPointerType()) 884 is_objc_pointer = false; 885 886 if (no_synth_child && is_objc_pointer) 887 { 888 error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted", 889 valobj_sp->GetTypeName().AsCString("<invalid type>"), 890 var_expr_path_strm.GetString().c_str()); 891 892 return ValueObjectSP(); 893 } 894 else if (is_objc_pointer) 895 { 896 // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children 897 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 898 if (!synthetic /* no synthetic */ 899 || synthetic == valobj_sp) /* synthetic is the same as the original object */ 900 { 901 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 902 error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 903 valobj_sp->GetTypeName().AsCString("<invalid type>"), 904 var_expr_path_strm.GetString().c_str()); 905 } 906 else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 907 { 908 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 909 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 910 child_index, 911 valobj_sp->GetTypeName().AsCString("<invalid type>"), 912 var_expr_path_strm.GetString().c_str()); 913 } 914 else 915 { 916 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 917 if (!child_valobj_sp) 918 { 919 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 920 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 921 child_index, 922 valobj_sp->GetTypeName().AsCString("<invalid type>"), 923 var_expr_path_strm.GetString().c_str()); 924 } 925 } 926 } 927 else 928 { 929 child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true); 930 if (!child_valobj_sp) 931 { 932 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 933 error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"", 934 child_index, 935 valobj_sp->GetTypeName().AsCString("<invalid type>"), 936 var_expr_path_strm.GetString().c_str()); 937 } 938 } 939 } 940 else if (valobj_sp->GetCompilerType().IsArrayType(nullptr, nullptr, &is_incomplete_array)) 941 { 942 // Pass false to dynamic_value here so we can tell the difference between 943 // no dynamic value and no member of this type... 944 child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); 945 if (!child_valobj_sp && (is_incomplete_array || !no_synth_child)) 946 child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true); 947 948 if (!child_valobj_sp) 949 { 950 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 951 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 952 child_index, 953 valobj_sp->GetTypeName().AsCString("<invalid type>"), 954 var_expr_path_strm.GetString().c_str()); 955 } 956 } 957 else if (valobj_sp->GetCompilerType().IsScalarType()) 958 { 959 // this is a bitfield asking to display just one bit 960 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true); 961 if (!child_valobj_sp) 962 { 963 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 964 error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 965 child_index, child_index, 966 valobj_sp->GetTypeName().AsCString("<invalid type>"), 967 var_expr_path_strm.GetString().c_str()); 968 } 969 } 970 else 971 { 972 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 973 if (no_synth_child /* synthetic is forbidden */ || 974 !synthetic /* no synthetic */ 975 || synthetic == valobj_sp) /* synthetic is the same as the original object */ 976 { 977 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 978 error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 979 valobj_sp->GetTypeName().AsCString("<invalid type>"), 980 var_expr_path_strm.GetString().c_str()); 981 } 982 else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 983 { 984 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 985 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 986 child_index, 987 valobj_sp->GetTypeName().AsCString("<invalid type>"), 988 var_expr_path_strm.GetString().c_str()); 989 } 990 else 991 { 992 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 993 if (!child_valobj_sp) 994 { 995 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 996 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 997 child_index, 998 valobj_sp->GetTypeName().AsCString("<invalid type>"), 999 var_expr_path_strm.GetString().c_str()); 1000 } 1001 } 1002 } 1003 1004 if (!child_valobj_sp) 1005 { 1006 // Invalid array index... 1007 return ValueObjectSP(); 1008 } 1009 1010 // Erase the array member specification '[%i]' where 1011 // %i is the array index 1012 var_path.erase(0, (end - var_path.c_str()) + 1); 1013 separator_idx = var_path.find_first_of(".-["); 1014 if (use_dynamic != eNoDynamicValues) 1015 { 1016 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 1017 if (dynamic_value_sp) 1018 child_valobj_sp = dynamic_value_sp; 1019 } 1020 // Break out early from the switch since we were 1021 // able to find the child member 1022 break; 1023 } 1024 else if (end && *end == '-') 1025 { 1026 // this is most probably a BitField, let's take a look 1027 char *real_end = nullptr; 1028 long final_index = ::strtol (end+1, &real_end, 0); 1029 bool expand_bitfield = true; 1030 if (real_end && *real_end == ']') 1031 { 1032 // if the format given is [high-low], swap range 1033 if (child_index > final_index) 1034 { 1035 long temp = child_index; 1036 child_index = final_index; 1037 final_index = temp; 1038 } 1039 1040 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) 1041 { 1042 // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr 1043 // and extract bits low thru high out of it. reading array items low thru high 1044 // would be done by saying ptr[low-high], without a deref * sign 1045 Error error; 1046 ValueObjectSP temp(valobj_sp->Dereference(error)); 1047 if (error.Fail()) 1048 { 1049 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1050 error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 1051 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1052 var_expr_path_strm.GetString().c_str()); 1053 return ValueObjectSP(); 1054 } 1055 valobj_sp = temp; 1056 deref = false; 1057 } 1058 else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) 1059 { 1060 // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0] 1061 // (an operation that is equivalent to deref-ing arr) 1062 // and extract bits low thru high out of it. reading array items low thru high 1063 // would be done by saying arr[low-high], without a deref * sign 1064 Error error; 1065 ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 1066 if (error.Fail()) 1067 { 1068 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1069 error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 1070 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1071 var_expr_path_strm.GetString().c_str()); 1072 return ValueObjectSP(); 1073 } 1074 valobj_sp = temp; 1075 deref = false; 1076 } 1077 /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType()) 1078 { 1079 child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true); 1080 expand_bitfield = false; 1081 if (!child_valobj_sp) 1082 { 1083 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1084 error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"", 1085 child_index, final_index, 1086 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1087 var_expr_path_strm.GetString().c_str()); 1088 } 1089 }*/ 1090 1091 if (expand_bitfield) 1092 { 1093 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true); 1094 if (!child_valobj_sp) 1095 { 1096 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1097 error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 1098 child_index, final_index, 1099 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1100 var_expr_path_strm.GetString().c_str()); 1101 } 1102 } 1103 } 1104 1105 if (!child_valobj_sp) 1106 { 1107 // Invalid bitfield range... 1108 return ValueObjectSP(); 1109 } 1110 1111 // Erase the bitfield member specification '[%i-%i]' where 1112 // %i is the index 1113 var_path.erase(0, (real_end - var_path.c_str()) + 1); 1114 separator_idx = var_path.find_first_of(".-["); 1115 if (use_dynamic != eNoDynamicValues) 1116 { 1117 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 1118 if (dynamic_value_sp) 1119 child_valobj_sp = dynamic_value_sp; 1120 } 1121 // Break out early from the switch since we were 1122 // able to find the child member 1123 break; 1124 1125 } 1126 } 1127 else 1128 { 1129 error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"", 1130 var_expr_path_strm.GetString().c_str(), 1131 var_path.c_str()); 1132 } 1133 return ValueObjectSP(); 1134 1135 default: 1136 // Failure... 1137 { 1138 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1139 error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"", 1140 separator_type, 1141 var_expr_path_strm.GetString().c_str(), 1142 var_path.c_str()); 1143 1144 return ValueObjectSP(); 1145 } 1146 } 1147 1148 if (child_valobj_sp) 1149 valobj_sp = child_valobj_sp; 1150 1151 if (var_path.empty()) 1152 break; 1153 } 1154 if (valobj_sp) 1155 { 1156 if (deref) 1157 { 1158 ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error)); 1159 valobj_sp = deref_valobj_sp; 1160 } 1161 else if (address_of) 1162 { 1163 ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error)); 1164 valobj_sp = address_of_valobj_sp; 1165 } 1166 } 1167 return valobj_sp; 1168 } 1169 else 1170 { 1171 error.SetErrorStringWithFormat("no variable named '%s' found in this frame", 1172 name_const_string.GetCString()); 1173 } 1174 } 1175 } 1176 else 1177 { 1178 error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr); 1179 } 1180 return ValueObjectSP(); 1181 } 1182 1183 bool 1184 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 1185 { 1186 std::lock_guard<std::recursive_mutex> guard(m_mutex); 1187 if (!m_cfa_is_valid) 1188 { 1189 m_frame_base_error.SetErrorString("No frame base available for this historical stack frame."); 1190 return false; 1191 } 1192 1193 if (m_flags.IsClear(GOT_FRAME_BASE)) 1194 { 1195 if (m_sc.function) 1196 { 1197 m_frame_base.Clear(); 1198 m_frame_base_error.Clear(); 1199 1200 m_flags.Set(GOT_FRAME_BASE); 1201 ExecutionContext exe_ctx (shared_from_this()); 1202 Value expr_value; 1203 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; 1204 if (m_sc.function->GetFrameBaseExpression().IsLocationList()) 1205 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr()); 1206 1207 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, 1208 nullptr, 1209 nullptr, 1210 nullptr, 1211 loclist_base_addr, 1212 nullptr, 1213 nullptr, 1214 expr_value, 1215 &m_frame_base_error) == false) 1216 { 1217 // We should really have an error if evaluate returns, but in case 1218 // we don't, lets set the error to something at least. 1219 if (m_frame_base_error.Success()) 1220 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 1221 } 1222 else 1223 { 1224 m_frame_base = expr_value.ResolveValue(&exe_ctx); 1225 } 1226 } 1227 else 1228 { 1229 m_frame_base_error.SetErrorString ("No function in symbol context."); 1230 } 1231 } 1232 1233 if (m_frame_base_error.Success()) 1234 frame_base = m_frame_base; 1235 1236 if (error_ptr) 1237 *error_ptr = m_frame_base_error; 1238 return m_frame_base_error.Success(); 1239 } 1240 1241 DWARFExpression * 1242 StackFrame::GetFrameBaseExpression(Error *error_ptr) 1243 { 1244 if (!m_sc.function) 1245 { 1246 if (error_ptr) 1247 { 1248 error_ptr->SetErrorString ("No function in symbol context."); 1249 } 1250 return nullptr; 1251 } 1252 1253 return &m_sc.function->GetFrameBaseExpression(); 1254 } 1255 1256 RegisterContextSP 1257 StackFrame::GetRegisterContext () 1258 { 1259 std::lock_guard<std::recursive_mutex> guard(m_mutex); 1260 if (!m_reg_context_sp) 1261 { 1262 ThreadSP thread_sp (GetThread()); 1263 if (thread_sp) 1264 m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this); 1265 } 1266 return m_reg_context_sp; 1267 } 1268 1269 bool 1270 StackFrame::HasDebugInformation () 1271 { 1272 GetSymbolContext (eSymbolContextLineEntry); 1273 return m_sc.line_entry.IsValid(); 1274 } 1275 1276 ValueObjectSP 1277 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 1278 { 1279 std::lock_guard<std::recursive_mutex> guard(m_mutex); 1280 ValueObjectSP valobj_sp; 1281 if (m_is_history_frame) 1282 { 1283 return valobj_sp; 1284 } 1285 VariableList *var_list = GetVariableList (true); 1286 if (var_list) 1287 { 1288 // Make sure the variable is a frame variable 1289 const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get()); 1290 const uint32_t num_variables = var_list->GetSize(); 1291 if (var_idx < num_variables) 1292 { 1293 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); 1294 if (!valobj_sp) 1295 { 1296 if (m_variable_list_value_objects.GetSize() < num_variables) 1297 m_variable_list_value_objects.Resize(num_variables); 1298 valobj_sp = ValueObjectVariable::Create (this, variable_sp); 1299 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp); 1300 } 1301 } 1302 } 1303 if (use_dynamic != eNoDynamicValues && valobj_sp) 1304 { 1305 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic); 1306 if (dynamic_sp) 1307 return dynamic_sp; 1308 } 1309 return valobj_sp; 1310 } 1311 1312 ValueObjectSP 1313 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 1314 { 1315 std::lock_guard<std::recursive_mutex> guard(m_mutex); 1316 if (m_is_history_frame) 1317 return ValueObjectSP(); 1318 1319 // Check to make sure we aren't already tracking this variable? 1320 ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic)); 1321 if (!valobj_sp) 1322 { 1323 // We aren't already tracking this global 1324 VariableList *var_list = GetVariableList (true); 1325 // If this frame has no variables, create a new list 1326 if (var_list == nullptr) 1327 m_variable_list_sp.reset (new VariableList()); 1328 1329 // Add the global/static variable to this frame 1330 m_variable_list_sp->AddVariable (variable_sp); 1331 1332 // Now make a value object for it so we can track its changes 1333 valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic); 1334 } 1335 return valobj_sp; 1336 } 1337 1338 bool 1339 StackFrame::IsInlined () 1340 { 1341 if (m_sc.block == nullptr) 1342 GetSymbolContext (eSymbolContextBlock); 1343 if (m_sc.block) 1344 return m_sc.block->GetContainingInlinedBlock() != nullptr; 1345 return false; 1346 } 1347 1348 lldb::LanguageType 1349 StackFrame::GetLanguage () 1350 { 1351 CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit; 1352 if (cu) 1353 return cu->GetLanguage(); 1354 return lldb::eLanguageTypeUnknown; 1355 } 1356 1357 lldb::LanguageType 1358 StackFrame::GuessLanguage () 1359 { 1360 LanguageType lang_type = GetLanguage(); 1361 1362 if (lang_type == eLanguageTypeUnknown) 1363 { 1364 Function *f = GetSymbolContext(eSymbolContextFunction).function; 1365 if (f) 1366 { 1367 lang_type = f->GetMangled().GuessLanguage(); 1368 } 1369 } 1370 1371 return lang_type; 1372 } 1373 1374 namespace 1375 { 1376 std::pair<const Instruction::Operand *, int64_t> 1377 GetBaseExplainingValue(const Instruction::Operand &operand, 1378 RegisterContext ®ister_context, 1379 lldb::addr_t value) 1380 { 1381 switch(operand.m_type) 1382 { 1383 case Instruction::Operand::Type::Dereference: 1384 case Instruction::Operand::Type::Immediate: 1385 case Instruction::Operand::Type::Invalid: 1386 case Instruction::Operand::Type::Product: 1387 // These are not currently interesting 1388 return std::make_pair(nullptr, 0); 1389 case Instruction::Operand::Type::Sum: 1390 { 1391 const Instruction::Operand *immediate_child = nullptr; 1392 const Instruction::Operand *variable_child = nullptr; 1393 if (operand.m_children[0].m_type == Instruction::Operand::Type::Immediate) 1394 { 1395 immediate_child = &operand.m_children[0]; 1396 variable_child = &operand.m_children[1]; 1397 } 1398 else if (operand.m_children[1].m_type == Instruction::Operand::Type::Immediate) 1399 { 1400 immediate_child = &operand.m_children[1]; 1401 variable_child = &operand.m_children[0]; 1402 } 1403 if (!immediate_child) 1404 { 1405 return std::make_pair(nullptr, 0); 1406 } 1407 lldb::addr_t adjusted_value = value; 1408 if (immediate_child->m_negative) 1409 { 1410 adjusted_value += immediate_child->m_immediate; 1411 } 1412 else 1413 { 1414 adjusted_value -= immediate_child->m_immediate; 1415 } 1416 std::pair<const Instruction::Operand *, int64_t> base_and_offset = GetBaseExplainingValue(*variable_child, register_context, adjusted_value); 1417 if (!base_and_offset.first) 1418 { 1419 return std::make_pair(nullptr, 0); 1420 } 1421 if (immediate_child->m_negative) 1422 { 1423 base_and_offset.second -= immediate_child->m_immediate; 1424 } 1425 else 1426 { 1427 base_and_offset.second += immediate_child->m_immediate; 1428 } 1429 return base_and_offset; 1430 } 1431 case Instruction::Operand::Type::Register: 1432 { 1433 const RegisterInfo *info = register_context.GetRegisterInfoByName(operand.m_register.AsCString()); 1434 if (!info) 1435 { 1436 return std::make_pair(nullptr, 0); 1437 } 1438 RegisterValue reg_value; 1439 if (!register_context.ReadRegister(info, reg_value)) 1440 { 1441 return std::make_pair(nullptr, 0); 1442 } 1443 if (reg_value.GetAsUInt64() == value) 1444 { 1445 return std::make_pair(&operand, 0); 1446 } 1447 else 1448 { 1449 return std::make_pair(nullptr, 0); 1450 } 1451 } 1452 } 1453 } 1454 1455 std::pair<const Instruction::Operand *, int64_t> 1456 GetBaseExplainingDereference(const Instruction::Operand &operand, 1457 RegisterContext ®ister_context, 1458 lldb::addr_t addr) 1459 { 1460 if (operand.m_type == Instruction::Operand::Type::Dereference) 1461 { 1462 return GetBaseExplainingValue(operand.m_children[0], 1463 register_context, 1464 addr); 1465 } 1466 return std::make_pair(nullptr, 0); 1467 } 1468 }; 1469 1470 lldb::ValueObjectSP 1471 StackFrame::GuessValueForAddress(lldb::addr_t addr) 1472 { 1473 TargetSP target_sp = CalculateTarget(); 1474 1475 const ArchSpec &target_arch = target_sp->GetArchitecture(); 1476 1477 AddressRange pc_range; 1478 pc_range.GetBaseAddress() = GetFrameCodeAddress(); 1479 pc_range.SetByteSize(target_arch.GetMaximumOpcodeByteSize()); 1480 1481 ExecutionContext exe_ctx (shared_from_this()); 1482 1483 const char *plugin_name = nullptr; 1484 const char *flavor = nullptr; 1485 const bool prefer_file_cache = false; 1486 1487 DisassemblerSP disassembler_sp = Disassembler::DisassembleRange (target_arch, 1488 plugin_name, 1489 flavor, 1490 exe_ctx, 1491 pc_range, 1492 prefer_file_cache); 1493 1494 if (!disassembler_sp->GetInstructionList().GetSize()) 1495 { 1496 return ValueObjectSP(); 1497 } 1498 1499 InstructionSP instruction_sp = disassembler_sp->GetInstructionList().GetInstructionAtIndex(0); 1500 1501 llvm::SmallVector<Instruction::Operand, 3> operands; 1502 1503 if (!instruction_sp->ParseOperands(operands)) 1504 { 1505 return ValueObjectSP(); 1506 } 1507 1508 RegisterContextSP register_context_sp = GetRegisterContext(); 1509 1510 if (!register_context_sp) 1511 { 1512 return ValueObjectSP(); 1513 } 1514 1515 for (const Instruction::Operand &operand : operands) 1516 { 1517 std::pair<const Instruction::Operand *, int64_t> 1518 base_and_offset = GetBaseExplainingDereference(operand, *register_context_sp, addr); 1519 1520 if (!base_and_offset.first) 1521 { 1522 continue; 1523 } 1524 1525 switch (base_and_offset.first->m_type) 1526 { 1527 case Instruction::Operand::Type::Immediate: 1528 { 1529 lldb_private::Address addr; 1530 if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate + base_and_offset.second, addr)) 1531 { 1532 TypeSystem *c_type_system = target_sp->GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC); 1533 if (!c_type_system) 1534 { 1535 return ValueObjectSP(); 1536 } 1537 else 1538 { 1539 CompilerType void_ptr_type = c_type_system->GetBasicTypeFromAST(lldb::BasicType::eBasicTypeChar).GetPointerType(); 1540 return ValueObjectMemory::Create(this, "", addr, void_ptr_type); 1541 } 1542 } 1543 else 1544 { 1545 return ValueObjectSP(); 1546 } 1547 break; 1548 } 1549 case Instruction::Operand::Type::Register: 1550 { 1551 return GuessValueForRegisterAndOffset(base_and_offset.first->m_register, base_and_offset.second); 1552 } 1553 default: 1554 return ValueObjectSP(); 1555 } 1556 1557 } 1558 1559 return ValueObjectSP(); 1560 } 1561 1562 namespace 1563 { 1564 ValueObjectSP 1565 GetValueForOffset(StackFrame &frame, ValueObjectSP &parent, int64_t offset) 1566 { 1567 if (offset < 0 || offset >= parent->GetByteSize()) 1568 { 1569 return ValueObjectSP(); 1570 } 1571 1572 if (parent->IsPointerOrReferenceType()) 1573 { 1574 return parent; 1575 } 1576 1577 for (int ci = 0, ce = parent->GetNumChildren(); ci != ce; ++ci) 1578 { 1579 const bool can_create = true; 1580 ValueObjectSP child_sp = parent->GetChildAtIndex(ci, can_create); 1581 1582 if (!child_sp) 1583 { 1584 return ValueObjectSP(); 1585 } 1586 1587 int64_t child_offset = child_sp->GetByteOffset(); 1588 int64_t child_size = child_sp->GetByteSize(); 1589 1590 if (offset >= child_offset && 1591 offset < (child_offset + child_size)) 1592 { 1593 return GetValueForOffset(frame, child_sp, offset - child_offset); 1594 } 1595 } 1596 1597 if (offset == 0) 1598 { 1599 return parent; 1600 } 1601 else 1602 { 1603 return ValueObjectSP(); 1604 } 1605 } 1606 1607 ValueObjectSP 1608 GetValueForDereferincingOffset(StackFrame &frame, ValueObjectSP &base, int64_t offset) 1609 { 1610 // base is a pointer to something 1611 // offset is the thing to add to the pointer 1612 // We return the most sensible ValueObject for the result of *(base+offset) 1613 1614 if (!base->IsPointerOrReferenceType()) 1615 { 1616 return ValueObjectSP(); 1617 } 1618 1619 Error error; 1620 ValueObjectSP pointee = base->Dereference(error); 1621 1622 if (offset >= pointee->GetByteSize()) 1623 { 1624 int64_t index = offset / pointee->GetByteSize(); 1625 offset = offset % pointee->GetByteSize(); 1626 const bool can_create = true; 1627 pointee = base->GetSyntheticArrayMember(index, can_create); 1628 } 1629 1630 if (!pointee || error.Fail()) 1631 { 1632 return ValueObjectSP(); 1633 } 1634 1635 return GetValueForOffset(frame, pointee, offset); 1636 } 1637 1638 //------------------------------------------------------------------ 1639 /// Attempt to reconstruct the ValueObject for the address contained in a 1640 /// given register plus an offset. 1641 /// 1642 /// @params [in] frame 1643 /// The current stack frame. 1644 /// 1645 /// @params [in] reg 1646 /// The register. 1647 /// 1648 /// @params [in] offset 1649 /// The offset from the register. 1650 /// 1651 /// @param [in] disassembler 1652 /// A disassembler containing instructions valid up to the current PC. 1653 /// 1654 /// @param [in] variables 1655 /// The variable list from the current frame, 1656 /// 1657 /// @param [in] pc 1658 /// The program counter for the instruction considered the 'user'. 1659 /// 1660 /// @return 1661 /// A string describing the base for the ExpressionPath. This could be a 1662 /// variable, a register value, an argument, or a function return value. 1663 /// The ValueObject if found. If valid, it has a valid ExpressionPath. 1664 //------------------------------------------------------------------ 1665 lldb::ValueObjectSP 1666 DoGuessValueAt(StackFrame &frame, ConstString reg, int64_t offset, Disassembler &disassembler, VariableList &variables, const Address &pc) 1667 { 1668 // Example of operation for Intel: 1669 // 1670 // +14: movq -0x8(%rbp), %rdi 1671 // +18: movq 0x8(%rdi), %rdi 1672 // +22: addl 0x4(%rdi), %eax 1673 // 1674 // f, a pointer to a struct, is known to be at -0x8(%rbp). 1675 // 1676 // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at +18 that assigns to rdi, and calls itself recursively for that dereference 1677 // DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at +14 that assigns to rdi, and calls itself recursively for that derefernece 1678 // DoGuessValueAt(frame, rbp, -8, dis, vars, 0x14) finds "f" in the variable list. 1679 // Returns a ValueObject for f. (That's what was stored at rbp-8 at +14) 1680 // Returns a ValueObject for *(f+8) or f->b (That's what was stored at rdi+8 at +18) 1681 // Returns a ValueObject for *(f->b+4) or f->b->a (That's what was stored at rdi+4 at +22) 1682 1683 // First, check the variable list to see if anything is at the specified location. 1684 for (size_t vi = 0, ve = variables.GetSize(); vi != ve; ++vi) 1685 { 1686 VariableSP var_sp = variables.GetVariableAtIndex(vi); 1687 DWARFExpression &dwarf_expression = var_sp->LocationExpression(); 1688 1689 const RegisterInfo *expression_reg; 1690 int64_t expression_offset; 1691 ExecutionContext exe_ctx; 1692 1693 if (dwarf_expression.IsDereferenceOfRegister(frame, expression_reg, expression_offset)) 1694 { 1695 if ((reg == ConstString(expression_reg->name) || 1696 reg == ConstString(expression_reg->alt_name)) && 1697 expression_offset == offset) 1698 { 1699 return frame.GetValueObjectForFrameVariable(var_sp, eNoDynamicValues); 1700 } 1701 } 1702 } 1703 1704 bool is_in_return_register = false; 1705 ABISP abi_sp = frame.CalculateProcess()->GetABI(); 1706 RegisterInfo return_register_info; 1707 1708 if (abi_sp) 1709 { 1710 const char *return_register_name; 1711 const RegisterInfo *reg_info = nullptr; 1712 if (abi_sp->GetPointerReturnRegister(return_register_name) && 1713 reg == ConstString(return_register_name) && 1714 (reg_info = frame.GetRegisterContext()->GetRegisterInfoByName(return_register_name))) 1715 { 1716 is_in_return_register = true; 1717 return_register_info = *reg_info; 1718 } 1719 } 1720 1721 const uint32_t current_inst = disassembler.GetInstructionList().GetIndexOfInstructionAtAddress(pc); 1722 if (current_inst == UINT32_MAX) 1723 { 1724 return ValueObjectSP(); 1725 } 1726 1727 ValueObjectSP source_path; 1728 1729 for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) 1730 { 1731 // This is not an exact algorithm, and it sacrifices accuracy for generality. 1732 // Recognizing "mov" and "ld" instructions –– and which are their source and 1733 // destination operands -- is something the disassembler should do for us. 1734 InstructionSP instruction_sp = disassembler.GetInstructionList().GetInstructionAtIndex(ii); 1735 1736 if (is_in_return_register && instruction_sp->IsCall()) 1737 { 1738 llvm::SmallVector<Instruction::Operand, 1> operands; 1739 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) 1740 { 1741 continue; 1742 } 1743 1744 switch (operands[0].m_type) 1745 { 1746 default: 1747 break; 1748 case Instruction::Operand::Type::Immediate: 1749 { 1750 SymbolContext sc; 1751 Address load_address; 1752 if (!frame.CalculateTarget()->ResolveLoadAddress(operands[0].m_immediate, load_address)) 1753 { 1754 break; 1755 } 1756 frame.CalculateTarget()->GetImages().ResolveSymbolContextForAddress(load_address, eSymbolContextFunction, sc); 1757 if (!sc.function) 1758 { 1759 break; 1760 } 1761 CompilerType function_type = sc.function->GetCompilerType(); 1762 if (!function_type.IsFunctionType()) 1763 { 1764 break; 1765 } 1766 CompilerType return_type = function_type.GetFunctionReturnType(); 1767 RegisterValue return_value; 1768 if (!frame.GetRegisterContext()->ReadRegister(&return_register_info, return_value)) 1769 { 1770 break; 1771 } 1772 std::string name_str(sc.function->GetName().AsCString("<unknown function>")); 1773 name_str.append("()"); 1774 Address return_value_address(return_value.GetAsUInt64()); 1775 ValueObjectSP return_value_sp = ValueObjectMemory::Create(&frame, name_str.c_str(), return_value_address, return_type); 1776 return GetValueForDereferincingOffset(frame, return_value_sp, offset); 1777 } 1778 } 1779 1780 continue; 1781 } 1782 1783 llvm::SmallVector<Instruction::Operand, 2> operands; 1784 if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) 1785 { 1786 continue; 1787 } 1788 1789 Instruction::Operand *register_operand = nullptr; 1790 Instruction::Operand *origin_operand = nullptr; 1791 if (operands[0].m_type == Instruction::Operand::Type::Register && 1792 operands[0].m_clobbered == true && 1793 operands[0].m_register == reg) 1794 { 1795 register_operand = &operands[0]; 1796 origin_operand = &operands[1]; 1797 } 1798 else if (operands[1].m_type == Instruction::Operand::Type::Register && 1799 operands[1].m_clobbered == true && 1800 operands[1].m_register == reg) 1801 { 1802 register_operand = &operands[1]; 1803 origin_operand = &operands[0]; 1804 } 1805 else 1806 { 1807 continue; 1808 } 1809 1810 // We have an origin operand. Can we track its value down? 1811 switch (origin_operand->m_type) 1812 { 1813 default: 1814 break; 1815 case Instruction::Operand::Type::Register: 1816 source_path = DoGuessValueAt(frame, origin_operand->m_register, 0, disassembler, variables, instruction_sp->GetAddress()); 1817 break; 1818 case Instruction::Operand::Type::Dereference: 1819 { 1820 const Instruction::Operand &pointer = origin_operand->m_children[0]; 1821 switch (pointer.m_type) 1822 { 1823 default: 1824 break; 1825 case Instruction::Operand::Type::Register: 1826 source_path = DoGuessValueAt(frame, pointer.m_register, 0, disassembler, variables, instruction_sp->GetAddress()); 1827 if (source_path) 1828 { 1829 Error err; 1830 source_path = source_path->Dereference(err); 1831 if (!err.Success()) 1832 { 1833 source_path.reset(); 1834 } 1835 } 1836 break; 1837 case Instruction::Operand::Type::Sum: 1838 { 1839 const Instruction::Operand *origin_register = nullptr; 1840 const Instruction::Operand *origin_offset = nullptr; 1841 if (pointer.m_children.size() != 2) 1842 { 1843 break; 1844 } 1845 if (pointer.m_children[0].m_type == Instruction::Operand::Type::Register && 1846 pointer.m_children[1].m_type == Instruction::Operand::Type::Immediate) 1847 { 1848 origin_register = &pointer.m_children[0]; 1849 origin_offset = &pointer.m_children[1]; 1850 } 1851 else if (pointer.m_children[1].m_type == Instruction::Operand::Type::Register && 1852 pointer.m_children[0].m_type == Instruction::Operand::Type::Immediate) 1853 { 1854 origin_register = &pointer.m_children[1]; 1855 origin_offset = &pointer.m_children[0]; 1856 } 1857 if (!origin_register) 1858 { 1859 break; 1860 } 1861 int64_t signed_origin_offset = origin_offset->m_negative ? -((int64_t)origin_offset->m_immediate) : origin_offset->m_immediate; 1862 source_path = DoGuessValueAt(frame, origin_register->m_register, signed_origin_offset, disassembler, variables, instruction_sp->GetAddress()); 1863 if (!source_path) 1864 { 1865 break; 1866 } 1867 source_path = GetValueForDereferincingOffset(frame, source_path, offset); 1868 break; 1869 } 1870 } 1871 } 1872 } 1873 1874 if (source_path) 1875 { 1876 return source_path; 1877 } 1878 } 1879 1880 return ValueObjectSP(); 1881 } 1882 } 1883 1884 lldb::ValueObjectSP 1885 StackFrame::GuessValueForRegisterAndOffset(ConstString reg, int64_t offset) 1886 { 1887 TargetSP target_sp = CalculateTarget(); 1888 1889 const ArchSpec &target_arch = target_sp->GetArchitecture(); 1890 1891 Block *frame_block = GetFrameBlock(); 1892 1893 if (!frame_block) 1894 { 1895 return ValueObjectSP(); 1896 } 1897 1898 Function *function = frame_block->CalculateSymbolContextFunction(); 1899 if (!function) 1900 { 1901 return ValueObjectSP(); 1902 } 1903 1904 AddressRange pc_range = function->GetAddressRange(); 1905 1906 if (GetFrameCodeAddress().GetFileAddress() < pc_range.GetBaseAddress().GetFileAddress() || 1907 GetFrameCodeAddress().GetFileAddress() - pc_range.GetBaseAddress().GetFileAddress() >= pc_range.GetByteSize()) 1908 { 1909 return ValueObjectSP(); 1910 } 1911 1912 ExecutionContext exe_ctx (shared_from_this()); 1913 1914 const char *plugin_name = nullptr; 1915 const char *flavor = nullptr; 1916 const bool prefer_file_cache = false; 1917 DisassemblerSP disassembler_sp = Disassembler::DisassembleRange (target_arch, 1918 plugin_name, 1919 flavor, 1920 exe_ctx, 1921 pc_range, 1922 prefer_file_cache); 1923 1924 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) 1925 { 1926 return ValueObjectSP(); 1927 } 1928 1929 const bool get_file_globals = false; 1930 VariableList *variables = GetVariableList(get_file_globals); 1931 1932 if (!variables) 1933 { 1934 return ValueObjectSP(); 1935 } 1936 1937 return DoGuessValueAt(*this, reg, offset, *disassembler_sp, *variables, GetFrameCodeAddress()); 1938 } 1939 1940 TargetSP 1941 StackFrame::CalculateTarget () 1942 { 1943 TargetSP target_sp; 1944 ThreadSP thread_sp(GetThread()); 1945 if (thread_sp) 1946 { 1947 ProcessSP process_sp (thread_sp->CalculateProcess()); 1948 if (process_sp) 1949 target_sp = process_sp->CalculateTarget(); 1950 } 1951 return target_sp; 1952 } 1953 1954 ProcessSP 1955 StackFrame::CalculateProcess () 1956 { 1957 ProcessSP process_sp; 1958 ThreadSP thread_sp(GetThread()); 1959 if (thread_sp) 1960 process_sp = thread_sp->CalculateProcess(); 1961 return process_sp; 1962 } 1963 1964 ThreadSP 1965 StackFrame::CalculateThread () 1966 { 1967 return GetThread(); 1968 } 1969 1970 StackFrameSP 1971 StackFrame::CalculateStackFrame () 1972 { 1973 return shared_from_this(); 1974 } 1975 1976 void 1977 StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx) 1978 { 1979 exe_ctx.SetContext (shared_from_this()); 1980 } 1981 1982 void 1983 StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker) 1984 { 1985 if (strm == nullptr) 1986 return; 1987 1988 GetSymbolContext(eSymbolContextEverything); 1989 ExecutionContext exe_ctx (shared_from_this()); 1990 StreamString s; 1991 1992 if (frame_marker) 1993 s.PutCString(frame_marker); 1994 1995 const FormatEntity::Entry *frame_format = nullptr; 1996 Target *target = exe_ctx.GetTargetPtr(); 1997 if (target) 1998 frame_format = target->GetDebugger().GetFrameFormat(); 1999 if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, nullptr, nullptr, false, false)) 2000 { 2001 strm->Write(s.GetData(), s.GetSize()); 2002 } 2003 else 2004 { 2005 Dump (strm, true, false); 2006 strm->EOL(); 2007 } 2008 } 2009 2010 void 2011 StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) 2012 { 2013 if (strm == nullptr) 2014 return; 2015 2016 if (show_frame_index) 2017 strm->Printf("frame #%u: ", m_frame_index); 2018 ExecutionContext exe_ctx (shared_from_this()); 2019 Target *target = exe_ctx.GetTargetPtr(); 2020 strm->Printf("0x%0*" PRIx64 " ", 2021 target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16, 2022 GetFrameCodeAddress().GetLoadAddress(target)); 2023 GetSymbolContext(eSymbolContextEverything); 2024 const bool show_module = true; 2025 const bool show_inline = true; 2026 const bool show_function_arguments = true; 2027 const bool show_function_name = true; 2028 m_sc.DumpStopContext (strm, 2029 exe_ctx.GetBestExecutionContextScope(), 2030 GetFrameCodeAddress(), 2031 show_fullpaths, 2032 show_module, 2033 show_inline, 2034 show_function_arguments, 2035 show_function_name); 2036 } 2037 2038 void 2039 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) 2040 { 2041 std::lock_guard<std::recursive_mutex> guard(m_mutex); 2042 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing 2043 m_variable_list_sp = prev_frame.m_variable_list_sp; 2044 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); 2045 if (!m_disassembly.GetString().empty()) 2046 m_disassembly.GetString().swap (m_disassembly.GetString()); 2047 } 2048 2049 void 2050 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) 2051 { 2052 std::lock_guard<std::recursive_mutex> guard(m_mutex); 2053 assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing 2054 m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value 2055 assert (GetThread() == curr_frame.GetThread()); 2056 m_frame_index = curr_frame.m_frame_index; 2057 m_concrete_frame_index = curr_frame.m_concrete_frame_index; 2058 m_reg_context_sp = curr_frame.m_reg_context_sp; 2059 m_frame_code_addr = curr_frame.m_frame_code_addr; 2060 assert (!m_sc.target_sp || !curr_frame.m_sc.target_sp || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); 2061 assert (!m_sc.module_sp || !curr_frame.m_sc.module_sp || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get()); 2062 assert (m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr || m_sc.comp_unit == curr_frame.m_sc.comp_unit); 2063 assert (m_sc.function == nullptr || curr_frame.m_sc.function == nullptr || m_sc.function == curr_frame.m_sc.function); 2064 m_sc = curr_frame.m_sc; 2065 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); 2066 m_flags.Set (m_sc.GetResolvedMask()); 2067 m_frame_base.Clear(); 2068 m_frame_base_error.Clear(); 2069 } 2070 2071 bool 2072 StackFrame::HasCachedData () const 2073 { 2074 if (m_variable_list_sp) 2075 return true; 2076 if (m_variable_list_value_objects.GetSize() > 0) 2077 return true; 2078 if (!m_disassembly.GetString().empty()) 2079 return true; 2080 return false; 2081 } 2082 2083 bool 2084 StackFrame::GetStatus (Stream& strm, 2085 bool show_frame_info, 2086 bool show_source, 2087 const char *frame_marker) 2088 { 2089 2090 if (show_frame_info) 2091 { 2092 strm.Indent(); 2093 DumpUsingSettingsFormat (&strm, frame_marker); 2094 } 2095 2096 if (show_source) 2097 { 2098 ExecutionContext exe_ctx (shared_from_this()); 2099 bool have_source = false, have_debuginfo = false; 2100 Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever; 2101 Target *target = exe_ctx.GetTargetPtr(); 2102 if (target) 2103 { 2104 Debugger &debugger = target->GetDebugger(); 2105 const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true); 2106 const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false); 2107 disasm_display = debugger.GetStopDisassemblyDisplay (); 2108 2109 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry); 2110 if (m_sc.comp_unit && m_sc.line_entry.IsValid()) 2111 { 2112 have_debuginfo = true; 2113 if (source_lines_before > 0 || source_lines_after > 0) 2114 { 2115 size_t num_lines = target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file, 2116 m_sc.line_entry.line, 2117 source_lines_before, 2118 source_lines_after, 2119 "->", 2120 &strm); 2121 if (num_lines != 0) 2122 have_source = true; 2123 // TODO: Give here a one time warning if source file is missing. 2124 } 2125 } 2126 switch (disasm_display) 2127 { 2128 case Debugger::eStopDisassemblyTypeNever: 2129 break; 2130 2131 case Debugger::eStopDisassemblyTypeNoDebugInfo: 2132 if (have_debuginfo) 2133 break; 2134 LLVM_FALLTHROUGH; 2135 2136 case Debugger::eStopDisassemblyTypeNoSource: 2137 if (have_source) 2138 break; 2139 LLVM_FALLTHROUGH; 2140 2141 case Debugger::eStopDisassemblyTypeAlways: 2142 if (target) 2143 { 2144 const uint32_t disasm_lines = debugger.GetDisassemblyLineCount(); 2145 if (disasm_lines > 0) 2146 { 2147 const ArchSpec &target_arch = target->GetArchitecture(); 2148 AddressRange pc_range; 2149 pc_range.GetBaseAddress() = GetFrameCodeAddress(); 2150 pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize()); 2151 const char *plugin_name = nullptr; 2152 const char *flavor = nullptr; 2153 Disassembler::Disassemble (target->GetDebugger(), 2154 target_arch, 2155 plugin_name, 2156 flavor, 2157 exe_ctx, 2158 pc_range, 2159 disasm_lines, 2160 0, 2161 Disassembler::eOptionMarkPCAddress, 2162 strm); 2163 } 2164 } 2165 break; 2166 } 2167 } 2168 } 2169 return true; 2170 } 2171