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