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