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