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