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