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