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