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