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