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