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(); 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 resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 456 } 457 458 // Update our internal flags so we remember what we have tried to locate so 459 // we don't have to keep trying when more calls to this function are made. 460 // We might have dug up more information that was requested (for example 461 // if we were asked to only get the block, we will have gotten the 462 // compile unit, and function) so set any additional bits that we resolved 463 m_flags.Set (resolve_scope | resolved); 464 } 465 466 // Return the symbol context with everything that was possible to resolve 467 // resolved. 468 return m_sc; 469 } 470 471 472 VariableList * 473 StackFrame::GetVariableList (bool get_file_globals) 474 { 475 if (m_flags.IsClear(RESOLVED_VARIABLES)) 476 { 477 m_flags.Set(RESOLVED_VARIABLES); 478 479 Block *frame_block = GetFrameBlock(); 480 481 if (frame_block) 482 { 483 const bool get_child_variables = true; 484 const bool can_create = true; 485 const bool stop_if_child_block_is_inlined_function = true; 486 m_variable_list_sp.reset(new VariableList()); 487 frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, m_variable_list_sp.get()); 488 } 489 } 490 491 if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && 492 get_file_globals) 493 { 494 m_flags.Set(RESOLVED_GLOBAL_VARIABLES); 495 496 if (m_flags.IsClear (eSymbolContextCompUnit)) 497 GetSymbolContext (eSymbolContextCompUnit); 498 499 if (m_sc.comp_unit) 500 { 501 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 502 if (m_variable_list_sp) 503 m_variable_list_sp->AddVariables (global_variable_list_sp.get()); 504 else 505 m_variable_list_sp = global_variable_list_sp; 506 } 507 } 508 509 return m_variable_list_sp.get(); 510 } 511 512 VariableListSP 513 StackFrame::GetInScopeVariableList (bool get_file_globals) 514 { 515 VariableListSP var_list_sp(new VariableList); 516 GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock); 517 518 if (m_sc.block) 519 { 520 const bool can_create = true; 521 const bool get_parent_variables = true; 522 const bool stop_if_block_is_inlined_function = true; 523 m_sc.block->AppendVariables (can_create, 524 get_parent_variables, 525 stop_if_block_is_inlined_function, 526 var_list_sp.get()); 527 } 528 529 if (m_sc.comp_unit) 530 { 531 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 532 if (global_variable_list_sp) 533 var_list_sp->AddVariables (global_variable_list_sp.get()); 534 } 535 536 return var_list_sp; 537 } 538 539 540 ValueObjectSP 541 StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, 542 DynamicValueType use_dynamic, 543 uint32_t options, 544 VariableSP &var_sp, 545 Error &error) 546 { 547 548 if (var_expr_cstr && var_expr_cstr[0]) 549 { 550 const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0; 551 const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0; 552 const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0; 553 //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0; 554 error.Clear(); 555 bool deref = false; 556 bool address_of = false; 557 ValueObjectSP valobj_sp; 558 const bool get_file_globals = true; 559 // When looking up a variable for an expression, we need only consider the 560 // variables that are in scope. 561 VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals)); 562 VariableList *variable_list = var_list_sp.get(); 563 564 if (variable_list) 565 { 566 // If first character is a '*', then show pointer contents 567 const char *var_expr = var_expr_cstr; 568 if (var_expr[0] == '*') 569 { 570 deref = true; 571 var_expr++; // Skip the '*' 572 } 573 else if (var_expr[0] == '&') 574 { 575 address_of = true; 576 var_expr++; // Skip the '&' 577 } 578 579 std::string var_path (var_expr); 580 size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}"); 581 StreamString var_expr_path_strm; 582 583 ConstString name_const_string; 584 if (separator_idx == std::string::npos) 585 name_const_string.SetCString (var_path.c_str()); 586 else 587 name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); 588 589 var_sp = variable_list->FindVariable(name_const_string); 590 591 bool synthetically_added_instance_object = false; 592 593 if (var_sp) 594 { 595 var_path.erase (0, name_const_string.GetLength ()); 596 } 597 else if (options & eExpressionPathOptionsAllowDirectIVarAccess) 598 { 599 // Check for direct ivars access which helps us with implicit 600 // access to ivars with the "this->" or "self->" 601 GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock); 602 lldb::LanguageType method_language = eLanguageTypeUnknown; 603 bool is_instance_method = false; 604 ConstString method_object_name; 605 if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name)) 606 { 607 if (is_instance_method && method_object_name) 608 { 609 var_sp = variable_list->FindVariable(method_object_name); 610 if (var_sp) 611 { 612 separator_idx = 0; 613 var_path.insert(0, "->"); 614 synthetically_added_instance_object = true; 615 } 616 } 617 } 618 } 619 620 if (var_sp) 621 { 622 valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic); 623 if (!valobj_sp) 624 return valobj_sp; 625 626 // We are dumping at least one child 627 while (separator_idx != std::string::npos) 628 { 629 // Calculate the next separator index ahead of time 630 ValueObjectSP child_valobj_sp; 631 const char separator_type = var_path[0]; 632 switch (separator_type) 633 { 634 635 case '-': 636 if (var_path.size() >= 2 && var_path[1] != '>') 637 return ValueObjectSP(); 638 639 if (no_fragile_ivar) 640 { 641 // Make sure we aren't trying to deref an objective 642 // C ivar if this is not allowed 643 const uint32_t pointer_type_flags = ClangASTContext::GetTypeInfo (valobj_sp->GetClangType(), NULL, NULL); 644 if ((pointer_type_flags & ClangASTContext::eTypeIsObjC) && 645 (pointer_type_flags & ClangASTContext::eTypeIsPointer)) 646 { 647 // This was an objective C object pointer and 648 // it was requested we skip any fragile ivars 649 // so return nothing here 650 return ValueObjectSP(); 651 } 652 } 653 var_path.erase (0, 1); // Remove the '-' 654 // Fall through 655 case '.': 656 { 657 const bool expr_is_ptr = var_path[0] == '>'; 658 659 var_path.erase (0, 1); // Remove the '.' or '>' 660 separator_idx = var_path.find_first_of(".-["); 661 ConstString child_name; 662 if (separator_idx == std::string::npos) 663 child_name.SetCString (var_path.c_str()); 664 else 665 child_name.SetCStringWithLength(var_path.c_str(), separator_idx); 666 667 if (check_ptr_vs_member) 668 { 669 // We either have a pointer type and need to verify 670 // valobj_sp is a pointer, or we have a member of a 671 // class/union/struct being accessed with the . syntax 672 // and need to verify we don't have a pointer. 673 const bool actual_is_ptr = valobj_sp->IsPointerType (); 674 675 if (actual_is_ptr != expr_is_ptr) 676 { 677 // Incorrect use of "." with a pointer, or "->" with 678 // a class/union/struct instance or reference. 679 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 680 if (actual_is_ptr) 681 error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?", 682 var_expr_path_strm.GetString().c_str(), 683 child_name.GetCString(), 684 var_expr_path_strm.GetString().c_str(), 685 var_path.c_str()); 686 else 687 error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?", 688 var_expr_path_strm.GetString().c_str(), 689 child_name.GetCString(), 690 var_expr_path_strm.GetString().c_str(), 691 var_path.c_str()); 692 return ValueObjectSP(); 693 } 694 } 695 child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); 696 if (!child_valobj_sp) 697 { 698 if (no_synth_child == false) 699 { 700 child_valobj_sp = valobj_sp->GetSyntheticValue(); 701 if (child_valobj_sp) 702 child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true); 703 } 704 705 if (no_synth_child || !child_valobj_sp) 706 { 707 // No child member with name "child_name" 708 if (synthetically_added_instance_object) 709 { 710 // We added a "this->" or "self->" to the beginning of the expression 711 // and this is the first pointer ivar access, so just return the normal 712 // error 713 error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame", 714 name_const_string.GetCString()); 715 } 716 else 717 { 718 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 719 if (child_name) 720 { 721 error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"", 722 child_name.GetCString(), 723 valobj_sp->GetTypeName().AsCString("<invalid type>"), 724 var_expr_path_strm.GetString().c_str()); 725 } 726 else 727 { 728 error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"", 729 var_expr_path_strm.GetString().c_str(), 730 var_expr_cstr); 731 } 732 } 733 return ValueObjectSP(); 734 } 735 } 736 synthetically_added_instance_object = false; 737 // Remove the child name from the path 738 var_path.erase(0, child_name.GetLength()); 739 if (use_dynamic != eNoDynamicValues) 740 { 741 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 742 if (dynamic_value_sp) 743 child_valobj_sp = dynamic_value_sp; 744 } 745 } 746 break; 747 748 case '[': 749 // Array member access, or treating pointer as an array 750 if (var_path.size() > 2) // Need at least two brackets and a number 751 { 752 char *end = NULL; 753 long child_index = ::strtol (&var_path[1], &end, 0); 754 if (end && *end == ']' 755 && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go 756 { 757 if (ClangASTContext::IsPointerToScalarType(valobj_sp->GetClangType()) && deref) 758 { 759 // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr 760 // and extract bit low out of it. reading array item low 761 // would be done by saying ptr[low], without a deref * sign 762 Error error; 763 ValueObjectSP temp(valobj_sp->Dereference(error)); 764 if (error.Fail()) 765 { 766 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 767 error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 768 valobj_sp->GetTypeName().AsCString("<invalid type>"), 769 var_expr_path_strm.GetString().c_str()); 770 return ValueObjectSP(); 771 } 772 valobj_sp = temp; 773 deref = false; 774 } 775 else if (ClangASTContext::IsArrayOfScalarType(valobj_sp->GetClangType()) && deref) 776 { 777 // what we have is *arr[low]. the most similar C++ syntax is to get arr[0] 778 // (an operation that is equivalent to deref-ing arr) 779 // and extract bit low out of it. reading array item low 780 // would be done by saying arr[low], without a deref * sign 781 Error error; 782 ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 783 if (error.Fail()) 784 { 785 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 786 error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 787 valobj_sp->GetTypeName().AsCString("<invalid type>"), 788 var_expr_path_strm.GetString().c_str()); 789 return ValueObjectSP(); 790 } 791 valobj_sp = temp; 792 deref = false; 793 } 794 795 bool is_incomplete_array = false; 796 if (valobj_sp->IsPointerType ()) 797 { 798 bool is_objc_pointer = true; 799 800 if (ClangASTType::GetMinimumLanguage(valobj_sp->GetClangAST(), valobj_sp->GetClangType()) != eLanguageTypeObjC) 801 is_objc_pointer = false; 802 else if (!ClangASTContext::IsPointerType(valobj_sp->GetClangType())) 803 is_objc_pointer = false; 804 805 if (no_synth_child && is_objc_pointer) 806 { 807 error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted", 808 valobj_sp->GetTypeName().AsCString("<invalid type>"), 809 var_expr_path_strm.GetString().c_str()); 810 811 return ValueObjectSP(); 812 } 813 else if (is_objc_pointer) 814 { 815 // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children 816 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 817 if (synthetic.get() == NULL /* no synthetic */ 818 || synthetic == valobj_sp) /* synthetic is the same as the original object */ 819 { 820 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 821 error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 822 valobj_sp->GetTypeName().AsCString("<invalid type>"), 823 var_expr_path_strm.GetString().c_str()); 824 } 825 else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 826 { 827 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 828 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 829 child_index, 830 valobj_sp->GetTypeName().AsCString("<invalid type>"), 831 var_expr_path_strm.GetString().c_str()); 832 } 833 else 834 { 835 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 836 if (!child_valobj_sp) 837 { 838 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 839 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 840 child_index, 841 valobj_sp->GetTypeName().AsCString("<invalid type>"), 842 var_expr_path_strm.GetString().c_str()); 843 } 844 } 845 } 846 else 847 { 848 child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true); 849 if (!child_valobj_sp) 850 { 851 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 852 error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"", 853 child_index, 854 valobj_sp->GetTypeName().AsCString("<invalid type>"), 855 var_expr_path_strm.GetString().c_str()); 856 } 857 } 858 } 859 else if (ClangASTContext::IsArrayType (valobj_sp->GetClangType(), NULL, NULL, &is_incomplete_array)) 860 { 861 // Pass false to dynamic_value here so we can tell the difference between 862 // no dynamic value and no member of this type... 863 child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); 864 if (!child_valobj_sp && (is_incomplete_array || no_synth_child == false)) 865 child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true); 866 867 if (!child_valobj_sp) 868 { 869 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 870 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 871 child_index, 872 valobj_sp->GetTypeName().AsCString("<invalid type>"), 873 var_expr_path_strm.GetString().c_str()); 874 } 875 } 876 else if (ClangASTContext::IsScalarType(valobj_sp->GetClangType())) 877 { 878 // this is a bitfield asking to display just one bit 879 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true); 880 if (!child_valobj_sp) 881 { 882 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 883 error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 884 child_index, child_index, 885 valobj_sp->GetTypeName().AsCString("<invalid type>"), 886 var_expr_path_strm.GetString().c_str()); 887 } 888 } 889 else 890 { 891 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 892 if (no_synth_child /* synthetic is forbidden */ || 893 synthetic.get() == NULL /* no synthetic */ 894 || synthetic == valobj_sp) /* synthetic is the same as the original object */ 895 { 896 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 897 error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 898 valobj_sp->GetTypeName().AsCString("<invalid type>"), 899 var_expr_path_strm.GetString().c_str()); 900 } 901 else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 902 { 903 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 904 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 905 child_index, 906 valobj_sp->GetTypeName().AsCString("<invalid type>"), 907 var_expr_path_strm.GetString().c_str()); 908 } 909 else 910 { 911 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 912 if (!child_valobj_sp) 913 { 914 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 915 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 916 child_index, 917 valobj_sp->GetTypeName().AsCString("<invalid type>"), 918 var_expr_path_strm.GetString().c_str()); 919 } 920 } 921 } 922 923 if (!child_valobj_sp) 924 { 925 // Invalid array index... 926 return ValueObjectSP(); 927 } 928 929 // Erase the array member specification '[%i]' where 930 // %i is the array index 931 var_path.erase(0, (end - var_path.c_str()) + 1); 932 separator_idx = var_path.find_first_of(".-["); 933 if (use_dynamic != eNoDynamicValues) 934 { 935 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 936 if (dynamic_value_sp) 937 child_valobj_sp = dynamic_value_sp; 938 } 939 // Break out early from the switch since we were 940 // able to find the child member 941 break; 942 } 943 else if (end && *end == '-') 944 { 945 // this is most probably a BitField, let's take a look 946 char *real_end = NULL; 947 long final_index = ::strtol (end+1, &real_end, 0); 948 bool expand_bitfield = true; 949 if (real_end && *real_end == ']') 950 { 951 // if the format given is [high-low], swap range 952 if (child_index > final_index) 953 { 954 long temp = child_index; 955 child_index = final_index; 956 final_index = temp; 957 } 958 959 if (ClangASTContext::IsPointerToScalarType(valobj_sp->GetClangType()) && deref) 960 { 961 // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr 962 // and extract bits low thru high out of it. reading array items low thru high 963 // would be done by saying ptr[low-high], without a deref * sign 964 Error error; 965 ValueObjectSP temp(valobj_sp->Dereference(error)); 966 if (error.Fail()) 967 { 968 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 969 error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 970 valobj_sp->GetTypeName().AsCString("<invalid type>"), 971 var_expr_path_strm.GetString().c_str()); 972 return ValueObjectSP(); 973 } 974 valobj_sp = temp; 975 deref = false; 976 } 977 else if (ClangASTContext::IsArrayOfScalarType(valobj_sp->GetClangType()) && deref) 978 { 979 // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0] 980 // (an operation that is equivalent to deref-ing arr) 981 // and extract bits low thru high out of it. reading array items low thru high 982 // would be done by saying arr[low-high], without a deref * sign 983 Error error; 984 ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 985 if (error.Fail()) 986 { 987 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 988 error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 989 valobj_sp->GetTypeName().AsCString("<invalid type>"), 990 var_expr_path_strm.GetString().c_str()); 991 return ValueObjectSP(); 992 } 993 valobj_sp = temp; 994 deref = false; 995 } 996 /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType()) 997 { 998 child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true); 999 expand_bitfield = false; 1000 if (!child_valobj_sp) 1001 { 1002 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1003 error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"", 1004 child_index, final_index, 1005 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1006 var_expr_path_strm.GetString().c_str()); 1007 } 1008 }*/ 1009 1010 if (expand_bitfield) 1011 { 1012 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true); 1013 if (!child_valobj_sp) 1014 { 1015 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1016 error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 1017 child_index, final_index, 1018 valobj_sp->GetTypeName().AsCString("<invalid type>"), 1019 var_expr_path_strm.GetString().c_str()); 1020 } 1021 } 1022 } 1023 1024 if (!child_valobj_sp) 1025 { 1026 // Invalid bitfield range... 1027 return ValueObjectSP(); 1028 } 1029 1030 // Erase the bitfield member specification '[%i-%i]' where 1031 // %i is the index 1032 var_path.erase(0, (real_end - var_path.c_str()) + 1); 1033 separator_idx = var_path.find_first_of(".-["); 1034 if (use_dynamic != eNoDynamicValues) 1035 { 1036 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 1037 if (dynamic_value_sp) 1038 child_valobj_sp = dynamic_value_sp; 1039 } 1040 // Break out early from the switch since we were 1041 // able to find the child member 1042 break; 1043 1044 } 1045 } 1046 else 1047 { 1048 error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"", 1049 var_expr_path_strm.GetString().c_str(), 1050 var_path.c_str()); 1051 } 1052 return ValueObjectSP(); 1053 1054 default: 1055 // Failure... 1056 { 1057 valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1058 error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"", 1059 separator_type, 1060 var_expr_path_strm.GetString().c_str(), 1061 var_path.c_str()); 1062 1063 return ValueObjectSP(); 1064 } 1065 } 1066 1067 if (child_valobj_sp) 1068 valobj_sp = child_valobj_sp; 1069 1070 if (var_path.empty()) 1071 break; 1072 1073 } 1074 if (valobj_sp) 1075 { 1076 if (deref) 1077 { 1078 ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error)); 1079 valobj_sp = deref_valobj_sp; 1080 } 1081 else if (address_of) 1082 { 1083 ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error)); 1084 valobj_sp = address_of_valobj_sp; 1085 } 1086 } 1087 return valobj_sp; 1088 } 1089 else 1090 { 1091 error.SetErrorStringWithFormat("no variable named '%s' found in this frame", 1092 name_const_string.GetCString()); 1093 } 1094 } 1095 } 1096 else 1097 { 1098 error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr); 1099 } 1100 return ValueObjectSP(); 1101 } 1102 1103 bool 1104 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 1105 { 1106 if (m_flags.IsClear(GOT_FRAME_BASE)) 1107 { 1108 if (m_sc.function) 1109 { 1110 m_frame_base.Clear(); 1111 m_frame_base_error.Clear(); 1112 1113 m_flags.Set(GOT_FRAME_BASE); 1114 ExecutionContext exe_ctx (shared_from_this()); 1115 Value expr_value; 1116 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; 1117 if (m_sc.function->GetFrameBaseExpression().IsLocationList()) 1118 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr()); 1119 1120 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false) 1121 { 1122 // We should really have an error if evaluate returns, but in case 1123 // we don't, lets set the error to something at least. 1124 if (m_frame_base_error.Success()) 1125 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 1126 } 1127 else 1128 { 1129 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL); 1130 } 1131 } 1132 else 1133 { 1134 m_frame_base_error.SetErrorString ("No function in symbol context."); 1135 } 1136 } 1137 1138 if (m_frame_base_error.Success()) 1139 frame_base = m_frame_base; 1140 1141 if (error_ptr) 1142 *error_ptr = m_frame_base_error; 1143 return m_frame_base_error.Success(); 1144 } 1145 1146 RegisterContextSP 1147 StackFrame::GetRegisterContext () 1148 { 1149 if (!m_reg_context_sp) 1150 { 1151 ThreadSP thread_sp (GetThread()); 1152 if (thread_sp) 1153 m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this); 1154 } 1155 return m_reg_context_sp; 1156 } 1157 1158 bool 1159 StackFrame::HasDebugInformation () 1160 { 1161 GetSymbolContext (eSymbolContextLineEntry); 1162 return m_sc.line_entry.IsValid(); 1163 } 1164 1165 1166 ValueObjectSP 1167 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 1168 { 1169 ValueObjectSP valobj_sp; 1170 VariableList *var_list = GetVariableList (true); 1171 if (var_list) 1172 { 1173 // Make sure the variable is a frame variable 1174 const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get()); 1175 const uint32_t num_variables = var_list->GetSize(); 1176 if (var_idx < num_variables) 1177 { 1178 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); 1179 if (valobj_sp.get() == NULL) 1180 { 1181 if (m_variable_list_value_objects.GetSize() < num_variables) 1182 m_variable_list_value_objects.Resize(num_variables); 1183 valobj_sp = ValueObjectVariable::Create (this, variable_sp); 1184 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp); 1185 } 1186 } 1187 } 1188 if (use_dynamic != eNoDynamicValues && valobj_sp) 1189 { 1190 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic); 1191 if (dynamic_sp) 1192 return dynamic_sp; 1193 } 1194 return valobj_sp; 1195 } 1196 1197 ValueObjectSP 1198 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 1199 { 1200 // Check to make sure we aren't already tracking this variable? 1201 ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic)); 1202 if (!valobj_sp) 1203 { 1204 // We aren't already tracking this global 1205 VariableList *var_list = GetVariableList (true); 1206 // If this frame has no variables, create a new list 1207 if (var_list == NULL) 1208 m_variable_list_sp.reset (new VariableList()); 1209 1210 // Add the global/static variable to this frame 1211 m_variable_list_sp->AddVariable (variable_sp); 1212 1213 // Now make a value object for it so we can track its changes 1214 valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic); 1215 } 1216 return valobj_sp; 1217 } 1218 1219 bool 1220 StackFrame::IsInlined () 1221 { 1222 if (m_sc.block == NULL) 1223 GetSymbolContext (eSymbolContextBlock); 1224 if (m_sc.block) 1225 return m_sc.block->GetContainingInlinedBlock() != NULL; 1226 return false; 1227 } 1228 1229 TargetSP 1230 StackFrame::CalculateTarget () 1231 { 1232 TargetSP target_sp; 1233 ThreadSP thread_sp(GetThread()); 1234 if (thread_sp) 1235 { 1236 ProcessSP process_sp (thread_sp->CalculateProcess()); 1237 if (process_sp) 1238 target_sp = process_sp->CalculateTarget(); 1239 } 1240 return target_sp; 1241 } 1242 1243 ProcessSP 1244 StackFrame::CalculateProcess () 1245 { 1246 ProcessSP process_sp; 1247 ThreadSP thread_sp(GetThread()); 1248 if (thread_sp) 1249 process_sp = thread_sp->CalculateProcess(); 1250 return process_sp; 1251 } 1252 1253 ThreadSP 1254 StackFrame::CalculateThread () 1255 { 1256 return GetThread(); 1257 } 1258 1259 StackFrameSP 1260 StackFrame::CalculateStackFrame () 1261 { 1262 return shared_from_this(); 1263 } 1264 1265 1266 void 1267 StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx) 1268 { 1269 exe_ctx.SetContext (shared_from_this()); 1270 } 1271 1272 void 1273 StackFrame::DumpUsingSettingsFormat (Stream *strm) 1274 { 1275 if (strm == NULL) 1276 return; 1277 1278 GetSymbolContext(eSymbolContextEverything); 1279 ExecutionContext exe_ctx (shared_from_this()); 1280 const char *end = NULL; 1281 StreamString s; 1282 const char *frame_format = NULL; 1283 Target *target = exe_ctx.GetTargetPtr(); 1284 if (target) 1285 frame_format = target->GetDebugger().GetFrameFormat(); 1286 if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s, &end)) 1287 { 1288 strm->Write(s.GetData(), s.GetSize()); 1289 } 1290 else 1291 { 1292 Dump (strm, true, false); 1293 strm->EOL(); 1294 } 1295 } 1296 1297 void 1298 StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) 1299 { 1300 if (strm == NULL) 1301 return; 1302 1303 if (show_frame_index) 1304 strm->Printf("frame #%u: ", m_frame_index); 1305 ExecutionContext exe_ctx (shared_from_this()); 1306 Target *target = exe_ctx.GetTargetPtr(); 1307 strm->Printf("0x%0*" PRIx64 " ", 1308 target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16, 1309 GetFrameCodeAddress().GetLoadAddress(target)); 1310 GetSymbolContext(eSymbolContextEverything); 1311 const bool show_module = true; 1312 const bool show_inline = true; 1313 m_sc.DumpStopContext (strm, 1314 exe_ctx.GetBestExecutionContextScope(), 1315 GetFrameCodeAddress(), 1316 show_fullpaths, 1317 show_module, 1318 show_inline); 1319 } 1320 1321 void 1322 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) 1323 { 1324 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing 1325 m_variable_list_sp = prev_frame.m_variable_list_sp; 1326 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); 1327 if (!m_disassembly.GetString().empty()) 1328 m_disassembly.GetString().swap (m_disassembly.GetString()); 1329 } 1330 1331 1332 void 1333 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) 1334 { 1335 assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing 1336 m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value 1337 assert (GetThread() == curr_frame.GetThread()); 1338 m_frame_index = curr_frame.m_frame_index; 1339 m_concrete_frame_index = curr_frame.m_concrete_frame_index; 1340 m_reg_context_sp = curr_frame.m_reg_context_sp; 1341 m_frame_code_addr = curr_frame.m_frame_code_addr; 1342 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()); 1343 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()); 1344 assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); 1345 assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); 1346 m_sc = curr_frame.m_sc; 1347 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); 1348 m_flags.Set (m_sc.GetResolvedMask()); 1349 m_frame_base.Clear(); 1350 m_frame_base_error.Clear(); 1351 } 1352 1353 1354 bool 1355 StackFrame::HasCachedData () const 1356 { 1357 if (m_variable_list_sp.get()) 1358 return true; 1359 if (m_variable_list_value_objects.GetSize() > 0) 1360 return true; 1361 if (!m_disassembly.GetString().empty()) 1362 return true; 1363 return false; 1364 } 1365 1366 bool 1367 StackFrame::GetStatus (Stream& strm, 1368 bool show_frame_info, 1369 bool show_source) 1370 { 1371 1372 if (show_frame_info) 1373 { 1374 strm.Indent(); 1375 DumpUsingSettingsFormat (&strm); 1376 } 1377 1378 if (show_source) 1379 { 1380 ExecutionContext exe_ctx (shared_from_this()); 1381 bool have_source = false; 1382 Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever; 1383 Target *target = exe_ctx.GetTargetPtr(); 1384 if (target) 1385 { 1386 Debugger &debugger = target->GetDebugger(); 1387 const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true); 1388 const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false); 1389 disasm_display = debugger.GetStopDisassemblyDisplay (); 1390 1391 if (source_lines_before > 0 || source_lines_after > 0) 1392 { 1393 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry); 1394 1395 if (m_sc.comp_unit && m_sc.line_entry.IsValid()) 1396 { 1397 if (target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file, 1398 m_sc.line_entry.line, 1399 source_lines_before, 1400 source_lines_after, 1401 "->", 1402 &strm)) 1403 { 1404 have_source = true; 1405 } 1406 } 1407 } 1408 switch (disasm_display) 1409 { 1410 case Debugger::eStopDisassemblyTypeNever: 1411 break; 1412 1413 case Debugger::eStopDisassemblyTypeNoSource: 1414 if (have_source) 1415 break; 1416 // Fall through to next case 1417 case Debugger::eStopDisassemblyTypeAlways: 1418 if (target) 1419 { 1420 const uint32_t disasm_lines = debugger.GetDisassemblyLineCount(); 1421 if (disasm_lines > 0) 1422 { 1423 const ArchSpec &target_arch = target->GetArchitecture(); 1424 AddressRange pc_range; 1425 pc_range.GetBaseAddress() = GetFrameCodeAddress(); 1426 pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize()); 1427 Disassembler::Disassemble (target->GetDebugger(), 1428 target_arch, 1429 NULL, 1430 exe_ctx, 1431 pc_range, 1432 disasm_lines, 1433 0, 1434 Disassembler::eOptionMarkPCAddress, 1435 strm); 1436 } 1437 } 1438 break; 1439 } 1440 } 1441 } 1442 return true; 1443 } 1444 1445