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