1 //===-- SBFrame.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/API/SBFrame.h" 11 12 #include <string> 13 #include <algorithm> 14 15 #include "lldb/lldb-types.h" 16 17 #include "lldb/Breakpoint/WatchpointLocation.h" 18 #include "lldb/Core/Address.h" 19 #include "lldb/Core/ConstString.h" 20 #include "lldb/Core/Log.h" 21 #include "lldb/Core/Stream.h" 22 #include "lldb/Core/StreamFile.h" 23 #include "lldb/Core/ValueObjectRegister.h" 24 #include "lldb/Core/ValueObjectVariable.h" 25 #include "lldb/Expression/ClangUserExpression.h" 26 #include "lldb/Host/Host.h" 27 #include "lldb/Symbol/Block.h" 28 #include "lldb/Symbol/SymbolContext.h" 29 #include "lldb/Symbol/VariableList.h" 30 #include "lldb/Symbol/Variable.h" 31 #include "lldb/Target/ExecutionContext.h" 32 #include "lldb/Target/Target.h" 33 #include "lldb/Target/Process.h" 34 #include "lldb/Target/RegisterContext.h" 35 #include "lldb/Target/StackFrame.h" 36 #include "lldb/Target/Thread.h" 37 38 #include "lldb/API/SBDebugger.h" 39 #include "lldb/API/SBValue.h" 40 #include "lldb/API/SBAddress.h" 41 #include "lldb/API/SBStream.h" 42 #include "lldb/API/SBSymbolContext.h" 43 #include "lldb/API/SBThread.h" 44 45 using namespace lldb; 46 using namespace lldb_private; 47 48 SBFrame::SBFrame () : 49 m_opaque_sp () 50 { 51 } 52 53 SBFrame::SBFrame (const StackFrameSP &lldb_object_sp) : 54 m_opaque_sp (lldb_object_sp) 55 { 56 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 57 58 if (log) 59 { 60 SBStream sstr; 61 GetDescription (sstr); 62 log->Printf ("SBFrame::SBFrame (sp=%p) => SBFrame(%p): %s", 63 lldb_object_sp.get(), m_opaque_sp.get(), sstr.GetData()); 64 65 } 66 } 67 68 SBFrame::SBFrame(const SBFrame &rhs) : 69 m_opaque_sp (rhs.m_opaque_sp) 70 { 71 } 72 73 const SBFrame & 74 SBFrame::operator = (const SBFrame &rhs) 75 { 76 if (this != &rhs) 77 m_opaque_sp = rhs.m_opaque_sp; 78 return *this; 79 } 80 81 SBFrame::~SBFrame() 82 { 83 } 84 85 86 void 87 SBFrame::SetFrame (const StackFrameSP &lldb_object_sp) 88 { 89 void *old_ptr = m_opaque_sp.get(); 90 m_opaque_sp = lldb_object_sp; 91 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 92 93 if (log) 94 { 95 log->Printf ("SBFrame(%p)::SetFrame(sp=%p) := SBFrame(%p)", 96 old_ptr, lldb_object_sp.get(), m_opaque_sp.get()); 97 } 98 99 } 100 101 102 bool 103 SBFrame::IsValid() const 104 { 105 return (m_opaque_sp.get() != NULL); 106 } 107 108 SBSymbolContext 109 SBFrame::GetSymbolContext (uint32_t resolve_scope) const 110 { 111 112 SBSymbolContext sb_sym_ctx; 113 if (m_opaque_sp) 114 { 115 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 116 sb_sym_ctx.SetSymbolContext(&m_opaque_sp->GetSymbolContext (resolve_scope)); 117 } 118 119 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 120 if (log) 121 log->Printf ("SBFrame(%p)::GetSymbolContext (resolve_scope=0x%8.8x) => SBSymbolContext(%p)", 122 m_opaque_sp.get(), resolve_scope, sb_sym_ctx.get()); 123 124 return sb_sym_ctx; 125 } 126 127 SBModule 128 SBFrame::GetModule () const 129 { 130 SBModule sb_module; 131 if (m_opaque_sp) 132 { 133 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 134 *sb_module = m_opaque_sp->GetSymbolContext (eSymbolContextModule).module_sp; 135 } 136 137 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 138 if (log) 139 log->Printf ("SBFrame(%p)::GetModule () => SBModule(%p)", 140 m_opaque_sp.get(), sb_module.get()); 141 142 return sb_module; 143 } 144 145 SBCompileUnit 146 SBFrame::GetCompileUnit () const 147 { 148 SBCompileUnit sb_comp_unit; 149 if (m_opaque_sp) 150 { 151 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 152 sb_comp_unit.reset (m_opaque_sp->GetSymbolContext (eSymbolContextCompUnit).comp_unit); 153 } 154 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 155 if (log) 156 log->Printf ("SBFrame(%p)::GetModule () => SBCompileUnit(%p)", 157 m_opaque_sp.get(), sb_comp_unit.get()); 158 159 return sb_comp_unit; 160 } 161 162 SBFunction 163 SBFrame::GetFunction () const 164 { 165 SBFunction sb_function; 166 if (m_opaque_sp) 167 { 168 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 169 sb_function.reset(m_opaque_sp->GetSymbolContext (eSymbolContextFunction).function); 170 } 171 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 172 if (log) 173 log->Printf ("SBFrame(%p)::GetFunction () => SBFunction(%p)", 174 m_opaque_sp.get(), sb_function.get()); 175 176 return sb_function; 177 } 178 179 SBSymbol 180 SBFrame::GetSymbol () const 181 { 182 SBSymbol sb_symbol; 183 if (m_opaque_sp) 184 { 185 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 186 sb_symbol.reset(m_opaque_sp->GetSymbolContext (eSymbolContextSymbol).symbol); 187 } 188 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 189 if (log) 190 log->Printf ("SBFrame(%p)::GetSymbol () => SBSymbol(%p)", 191 m_opaque_sp.get(), sb_symbol.get()); 192 return sb_symbol; 193 } 194 195 SBBlock 196 SBFrame::GetBlock () const 197 { 198 SBBlock sb_block; 199 if (m_opaque_sp) 200 { 201 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 202 sb_block.reset (m_opaque_sp->GetSymbolContext (eSymbolContextBlock).block); 203 } 204 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 205 if (log) 206 log->Printf ("SBFrame(%p)::GetBlock () => SBBlock(%p)", 207 m_opaque_sp.get(), sb_block.get()); 208 return sb_block; 209 } 210 211 SBBlock 212 SBFrame::GetFrameBlock () const 213 { 214 SBBlock sb_block; 215 if (m_opaque_sp) 216 { 217 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 218 sb_block.reset(m_opaque_sp->GetFrameBlock ()); 219 } 220 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 221 if (log) 222 log->Printf ("SBFrame(%p)::GetFrameBlock () => SBBlock(%p)", 223 m_opaque_sp.get(), sb_block.get()); 224 return sb_block; 225 } 226 227 SBLineEntry 228 SBFrame::GetLineEntry () const 229 { 230 SBLineEntry sb_line_entry; 231 if (m_opaque_sp) 232 { 233 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 234 sb_line_entry.SetLineEntry (m_opaque_sp->GetSymbolContext (eSymbolContextLineEntry).line_entry); 235 } 236 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 237 if (log) 238 log->Printf ("SBFrame(%p)::GetLineEntry () => SBLineEntry(%p)", 239 m_opaque_sp.get(), sb_line_entry.get()); 240 return sb_line_entry; 241 } 242 243 uint32_t 244 SBFrame::GetFrameID () const 245 { 246 uint32_t frame_idx = m_opaque_sp ? m_opaque_sp->GetFrameIndex () : UINT32_MAX; 247 248 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 249 if (log) 250 log->Printf ("SBFrame(%p)::GetFrameID () => %u", 251 m_opaque_sp.get(), frame_idx); 252 return frame_idx; 253 } 254 255 addr_t 256 SBFrame::GetPC () const 257 { 258 addr_t addr = LLDB_INVALID_ADDRESS; 259 if (m_opaque_sp) 260 { 261 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 262 addr = m_opaque_sp->GetFrameCodeAddress().GetOpcodeLoadAddress (&m_opaque_sp->GetThread().GetProcess().GetTarget()); 263 } 264 265 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 266 if (log) 267 log->Printf ("SBFrame(%p)::GetPC () => 0x%llx", m_opaque_sp.get(), addr); 268 269 return addr; 270 } 271 272 bool 273 SBFrame::SetPC (addr_t new_pc) 274 { 275 bool ret_val = false; 276 if (m_opaque_sp) 277 { 278 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 279 ret_val = m_opaque_sp->GetRegisterContext()->SetPC (new_pc); 280 } 281 282 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 283 if (log) 284 log->Printf ("SBFrame(%p)::SetPC (new_pc=0x%llx) => %i", 285 m_opaque_sp.get(), new_pc, ret_val); 286 287 return ret_val; 288 } 289 290 addr_t 291 SBFrame::GetSP () const 292 { 293 addr_t addr = LLDB_INVALID_ADDRESS; 294 if (m_opaque_sp) 295 { 296 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 297 addr = m_opaque_sp->GetRegisterContext()->GetSP(); 298 } 299 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 300 if (log) 301 log->Printf ("SBFrame(%p)::GetSP () => 0x%llx", m_opaque_sp.get(), addr); 302 303 return addr; 304 } 305 306 307 addr_t 308 SBFrame::GetFP () const 309 { 310 addr_t addr = LLDB_INVALID_ADDRESS; 311 if (m_opaque_sp) 312 { 313 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 314 addr = m_opaque_sp->GetRegisterContext()->GetFP(); 315 } 316 317 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 318 if (log) 319 log->Printf ("SBFrame(%p)::GetFP () => 0x%llx", m_opaque_sp.get(), addr); 320 return addr; 321 } 322 323 324 SBAddress 325 SBFrame::GetPCAddress () const 326 { 327 SBAddress sb_addr; 328 if (m_opaque_sp) 329 { 330 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 331 sb_addr.SetAddress (&m_opaque_sp->GetFrameCodeAddress()); 332 } 333 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 334 if (log) 335 log->Printf ("SBFrame(%p)::GetPCAddress () => SBAddress(%p)", m_opaque_sp.get(), sb_addr.get()); 336 return sb_addr; 337 } 338 339 void 340 SBFrame::Clear() 341 { 342 m_opaque_sp.reset(); 343 } 344 345 SBValue 346 SBFrame::FindVariable (const char *name) 347 { 348 SBValue value; 349 if (m_opaque_sp) 350 { 351 lldb::DynamicValueType use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); 352 value = FindVariable (name, use_dynamic); 353 } 354 return value; 355 } 356 357 SBValue 358 SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) 359 { 360 VariableSP var_sp; 361 SBValue sb_value; 362 363 if (m_opaque_sp && name && name[0]) 364 { 365 VariableList variable_list; 366 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 367 SymbolContext sc (m_opaque_sp->GetSymbolContext (eSymbolContextBlock)); 368 369 if (sc.block) 370 { 371 const bool can_create = true; 372 const bool get_parent_variables = true; 373 const bool stop_if_block_is_inlined_function = true; 374 375 if (sc.block->AppendVariables (can_create, 376 get_parent_variables, 377 stop_if_block_is_inlined_function, 378 &variable_list)) 379 { 380 var_sp = variable_list.FindVariable (ConstString(name)); 381 } 382 } 383 384 if (var_sp) 385 *sb_value = ValueObjectSP (m_opaque_sp->GetValueObjectForFrameVariable(var_sp, use_dynamic)); 386 387 } 388 389 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 390 if (log) 391 log->Printf ("SBFrame(%p)::FindVariable (name=\"%s\") => SBValue(%p)", 392 m_opaque_sp.get(), name, sb_value.get()); 393 394 return sb_value; 395 } 396 397 SBValue 398 SBFrame::FindValue (const char *name, ValueType value_type) 399 { 400 SBValue value; 401 if (m_opaque_sp) 402 { 403 lldb::DynamicValueType use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); 404 value = FindValue (name, value_type, use_dynamic); 405 } 406 return value; 407 } 408 409 /// Find and watch a variable using the frame as the scope. 410 /// You can use LLDB_WATCH_TYPE_READ | LLDB_WATCH_TYPE_WRITE for 'rw' watch. 411 SBValue 412 SBFrame::WatchValue (const char *name, ValueType value_type, uint32_t watch_type) 413 { 414 SBValue sb_value_empty; 415 416 if (!IsValid()) 417 return sb_value_empty; 418 419 // Acquire the API locker, to be released at the end of the method call. 420 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 421 422 switch (value_type) { 423 case eValueTypeVariableGlobal: // global variable 424 case eValueTypeVariableStatic: // static variable 425 case eValueTypeVariableArgument: // function argument variables 426 case eValueTypeVariableLocal: // function local variables 427 break; 428 default: 429 return sb_value_empty; // these are not eligible for watching 430 } 431 432 SBValue sb_value = FindValue(name, value_type); 433 // If the SBValue is not valid, there's no point in even trying to watch it. 434 if (!sb_value.IsValid()) 435 return sb_value; 436 437 addr_t addr = sb_value.GetLoadAddress(); 438 size_t size = sb_value.GetByteSize(); 439 440 WatchpointLocationSP wp_loc_sp = m_opaque_sp->GetThread().GetProcess().GetTarget(). 441 CreateWatchpointLocation(addr, size, watch_type); 442 443 if (wp_loc_sp) { 444 // StackFrame::GetInScopeVariableList(true) to get file globals as well. 445 VariableListSP var_list_sp(m_opaque_sp->GetInScopeVariableList(true)); 446 VariableSP var_sp = var_list_sp->FindVariable(ConstString(name)); 447 if (var_sp && var_sp->GetDeclaration().GetFile()) { 448 StreamString ss; 449 // True to show fullpath for declaration file. 450 var_sp->GetDeclaration().DumpStopContext(&ss, true); 451 wp_loc_sp->SetDeclInfo(ss.GetString()); 452 } 453 } 454 455 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 456 if (log) 457 log->Printf ("SBFrame(%p)::WatchValue (name=\"%s\", value_type=%i, watch_type=%i) => SBValue(%p) & wp_loc(%p)", 458 m_opaque_sp.get(), name, value_type, watch_type, sb_value.get(), wp_loc_sp.get()); 459 460 return wp_loc_sp ? sb_value : sb_value_empty; 461 } 462 463 /// Find and watch the location pointed to by a variable using the frame as 464 /// the scope. 465 /// It returns an SBValue, similar to FindValue() method, if find-and-watch 466 /// operation succeeds. Otherwise, an invalid SBValue is returned. 467 /// You can use LLDB_WATCH_TYPE_READ | LLDB_WATCH_TYPE_WRITE for 'rw' watch. 468 SBValue 469 SBFrame::WatchLocation (const char *name, ValueType value_type, uint32_t watch_type, size_t size) 470 { 471 SBValue sb_value_empty; 472 473 if (!IsValid()) 474 return sb_value_empty; 475 476 // Acquire the API locker, to be released at the end of the method call. 477 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 478 479 switch (value_type) { 480 case eValueTypeVariableGlobal: // global variable 481 case eValueTypeVariableStatic: // static variable 482 case eValueTypeVariableArgument: // function argument variables 483 case eValueTypeVariableLocal: // function local variables 484 break; 485 default: 486 return sb_value_empty; // these are not eligible for watching 487 } 488 489 SBValue sb_pointer = FindValue(name, value_type); 490 // If the sb_pointer is not valid, there's no point in even trying to watch it. 491 if (!sb_pointer.IsValid() || !sb_pointer.GetType().IsPointerType()) 492 return sb_value_empty; 493 494 addr_t addr = sb_pointer.GetValueAsUnsigned(0); 495 if (!addr) 496 return sb_value_empty; 497 498 SBValue sb_value = sb_pointer.CreateValueFromAddress("pointee", addr, sb_pointer.GetType().GetPointeeType()); 499 WatchpointLocationSP wp_loc_sp = m_opaque_sp->GetThread().GetProcess().GetTarget(). 500 CreateWatchpointLocation(addr, size, watch_type); 501 502 if (wp_loc_sp) { 503 // StackFrame::GetInScopeVariableList(true) to get file globals as well. 504 VariableListSP var_list_sp(m_opaque_sp->GetInScopeVariableList(true)); 505 VariableSP var_sp = var_list_sp->FindVariable(ConstString(name)); 506 if (var_sp && var_sp->GetDeclaration().GetFile()) { 507 StreamString ss; 508 // True to show fullpath for declaration file. 509 var_sp->GetDeclaration().DumpStopContext(&ss, true); 510 wp_loc_sp->SetDeclInfo(ss.GetString()); 511 } 512 } 513 514 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 515 if (log) 516 log->Printf ("SBFrame(%p)::WatchLocation (name=\"%s\", value_type=%i, watch_type=%i, size=%lu) => SBValue(%p) & wp_loc(%p)", 517 m_opaque_sp.get(), name, value_type, watch_type, size, sb_value.get(), wp_loc_sp.get()); 518 519 return wp_loc_sp ? sb_value : sb_value_empty; 520 } 521 522 SBValue 523 SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic) 524 { 525 SBValue sb_value; 526 if (m_opaque_sp && name && name[0]) 527 { 528 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 529 530 switch (value_type) 531 { 532 case eValueTypeVariableGlobal: // global variable 533 case eValueTypeVariableStatic: // static variable 534 case eValueTypeVariableArgument: // function argument variables 535 case eValueTypeVariableLocal: // function local variables 536 { 537 VariableList *variable_list = m_opaque_sp->GetVariableList(true); 538 539 SymbolContext sc (m_opaque_sp->GetSymbolContext (eSymbolContextBlock)); 540 541 const bool can_create = true; 542 const bool get_parent_variables = true; 543 const bool stop_if_block_is_inlined_function = true; 544 545 if (sc.block && sc.block->AppendVariables (can_create, 546 get_parent_variables, 547 stop_if_block_is_inlined_function, 548 variable_list)) 549 { 550 ConstString const_name(name); 551 const uint32_t num_variables = variable_list->GetSize(); 552 for (uint32_t i = 0; i < num_variables; ++i) 553 { 554 VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); 555 if (variable_sp && 556 variable_sp->GetScope() == value_type && 557 variable_sp->GetName() == const_name) 558 { 559 *sb_value = ValueObjectSP (m_opaque_sp->GetValueObjectForFrameVariable(variable_sp, 560 use_dynamic)); 561 break; 562 } 563 } 564 } 565 } 566 break; 567 568 case eValueTypeRegister: // stack frame register value 569 { 570 RegisterContextSP reg_ctx (m_opaque_sp->GetRegisterContext()); 571 if (reg_ctx) 572 { 573 const uint32_t num_regs = reg_ctx->GetRegisterCount(); 574 for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) 575 { 576 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); 577 if (reg_info && 578 ((reg_info->name && strcasecmp (reg_info->name, name) == 0) || 579 (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0))) 580 { 581 *sb_value = ValueObjectRegister::Create (m_opaque_sp.get(), reg_ctx, reg_idx); 582 } 583 } 584 } 585 } 586 break; 587 588 case eValueTypeRegisterSet: // A collection of stack frame register values 589 { 590 RegisterContextSP reg_ctx (m_opaque_sp->GetRegisterContext()); 591 if (reg_ctx) 592 { 593 const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); 594 for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) 595 { 596 const RegisterSet *reg_set = reg_ctx->GetRegisterSet (set_idx); 597 if (reg_set && 598 ((reg_set->name && strcasecmp (reg_set->name, name) == 0) || 599 (reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0))) 600 { 601 *sb_value = ValueObjectRegisterSet::Create (m_opaque_sp.get(), reg_ctx, set_idx); 602 } 603 } 604 } 605 } 606 break; 607 608 case eValueTypeConstResult: // constant result variables 609 { 610 ConstString const_name(name); 611 ClangExpressionVariableSP expr_var_sp (m_opaque_sp->GetThread().GetProcess().GetTarget().GetPersistentVariables().GetVariable (const_name)); 612 if (expr_var_sp) 613 *sb_value = expr_var_sp->GetValueObject(); 614 } 615 break; 616 617 default: 618 break; 619 } 620 } 621 622 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 623 if (log) 624 log->Printf ("SBFrame(%p)::FindVariableInScope (name=\"%s\", value_type=%i) => SBValue(%p)", 625 m_opaque_sp.get(), name, value_type, sb_value.get()); 626 627 628 return sb_value; 629 } 630 631 bool 632 SBFrame::operator == (const SBFrame &rhs) const 633 { 634 return m_opaque_sp.get() == rhs.m_opaque_sp.get(); 635 } 636 637 bool 638 SBFrame::operator != (const SBFrame &rhs) const 639 { 640 return m_opaque_sp.get() != rhs.m_opaque_sp.get(); 641 } 642 643 lldb_private::StackFrame * 644 SBFrame::operator->() const 645 { 646 return m_opaque_sp.get(); 647 } 648 649 lldb_private::StackFrame * 650 SBFrame::get() const 651 { 652 return m_opaque_sp.get(); 653 } 654 655 lldb::StackFrameSP & 656 SBFrame::get_sp() 657 { 658 return m_opaque_sp; 659 } 660 661 SBThread 662 SBFrame::GetThread () const 663 { 664 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 665 666 SBThread sb_thread; 667 if (m_opaque_sp) 668 { 669 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 670 sb_thread.SetThread (m_opaque_sp->GetThread().GetSP()); 671 } 672 673 if (log) 674 { 675 SBStream sstr; 676 sb_thread.GetDescription (sstr); 677 log->Printf ("SBFrame(%p)::GetThread () => SBThread(%p): %s", m_opaque_sp.get(), 678 sb_thread.get(), sstr.GetData()); 679 } 680 681 return sb_thread; 682 } 683 684 const char * 685 SBFrame::Disassemble () const 686 { 687 const char *disassembly = NULL; 688 if (m_opaque_sp) 689 { 690 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 691 disassembly = m_opaque_sp->Disassemble(); 692 } 693 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 694 695 if (log) 696 log->Printf ("SBFrame(%p)::Disassemble () => %s", m_opaque_sp.get(), disassembly); 697 698 return disassembly; 699 } 700 701 702 SBValueList 703 SBFrame::GetVariables (bool arguments, 704 bool locals, 705 bool statics, 706 bool in_scope_only) 707 { 708 SBValueList value_list; 709 if (m_opaque_sp) 710 { 711 lldb::DynamicValueType use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); 712 value_list = GetVariables (arguments, locals, statics, in_scope_only, use_dynamic); 713 } 714 return value_list; 715 } 716 717 SBValueList 718 SBFrame::GetVariables (bool arguments, 719 bool locals, 720 bool statics, 721 bool in_scope_only, 722 lldb::DynamicValueType use_dynamic) 723 { 724 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 725 726 if (log) 727 log->Printf ("SBFrame(%p)::GetVariables (arguments=%i, locals=%i, statics=%i, in_scope_only=%i)", 728 m_opaque_sp.get(), 729 arguments, 730 locals, 731 statics, 732 in_scope_only); 733 734 SBValueList value_list; 735 if (m_opaque_sp) 736 { 737 738 size_t i; 739 VariableList *variable_list = NULL; 740 // Scope for locker 741 { 742 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 743 variable_list = m_opaque_sp->GetVariableList(true); 744 } 745 if (variable_list) 746 { 747 const size_t num_variables = variable_list->GetSize(); 748 if (num_variables) 749 { 750 for (i = 0; i < num_variables; ++i) 751 { 752 VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); 753 if (variable_sp) 754 { 755 bool add_variable = false; 756 switch (variable_sp->GetScope()) 757 { 758 case eValueTypeVariableGlobal: 759 case eValueTypeVariableStatic: 760 add_variable = statics; 761 break; 762 763 case eValueTypeVariableArgument: 764 add_variable = arguments; 765 break; 766 767 case eValueTypeVariableLocal: 768 add_variable = locals; 769 break; 770 771 default: 772 break; 773 } 774 if (add_variable) 775 { 776 if (in_scope_only && !variable_sp->IsInScope(m_opaque_sp.get())) 777 continue; 778 779 value_list.Append(m_opaque_sp->GetValueObjectForFrameVariable (variable_sp, use_dynamic)); 780 } 781 } 782 } 783 } 784 } 785 } 786 787 if (log) 788 { 789 log->Printf ("SBFrame(%p)::GetVariables (...) => SBValueList(%p)", m_opaque_sp.get(), 790 value_list.get()); 791 } 792 793 return value_list; 794 } 795 796 SBValueList 797 SBFrame::GetRegisters () 798 { 799 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 800 801 SBValueList value_list; 802 if (m_opaque_sp) 803 { 804 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 805 RegisterContextSP reg_ctx (m_opaque_sp->GetRegisterContext()); 806 if (reg_ctx) 807 { 808 const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); 809 for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) 810 { 811 value_list.Append(ValueObjectRegisterSet::Create (m_opaque_sp.get(), reg_ctx, set_idx)); 812 } 813 } 814 } 815 816 if (log) 817 log->Printf ("SBFrame(%p)::Registers () => SBValueList(%p)", m_opaque_sp.get(), value_list.get()); 818 819 return value_list; 820 } 821 822 bool 823 SBFrame::GetDescription (SBStream &description) 824 { 825 if (m_opaque_sp) 826 { 827 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 828 Stream &s = description.ref(); 829 m_opaque_sp->DumpUsingSettingsFormat (&s); 830 } 831 else 832 description.Printf ("No value"); 833 834 return true; 835 } 836 837 SBValue 838 SBFrame::EvaluateExpression (const char *expr) 839 { 840 SBValue result; 841 if (m_opaque_sp) 842 { 843 lldb::DynamicValueType use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue(); 844 result = EvaluateExpression (expr, use_dynamic); 845 } 846 return result; 847 } 848 849 SBValue 850 SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value) 851 { 852 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 853 854 LogSP expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 855 856 ExecutionResults exe_results; 857 SBValue expr_result; 858 if (log) 859 log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\")...", m_opaque_sp.get(), expr); 860 861 if (m_opaque_sp) 862 { 863 Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); 864 865 866 StreamString frame_description; 867 m_opaque_sp->DumpUsingSettingsFormat (&frame_description); 868 869 Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s", 870 expr, fetch_dynamic_value, frame_description.GetString().c_str()); 871 872 const bool unwind_on_error = true; 873 const bool keep_in_memory = false; 874 875 exe_results = m_opaque_sp->GetThread().GetProcess().GetTarget().EvaluateExpression(expr, 876 m_opaque_sp.get(), 877 eExecutionPolicyOnlyWhenNeeded, 878 unwind_on_error, 879 keep_in_memory, 880 fetch_dynamic_value, 881 *expr_result); 882 } 883 884 if (expr_log) 885 expr_log->Printf("** [SBFrame::EvaluateExpression] Expression result is %s, summary %s **", 886 expr_result.GetValue(), 887 expr_result.GetSummary()); 888 889 if (log) 890 log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)", m_opaque_sp.get(), 891 expr, 892 expr_result.get(), 893 exe_results); 894 895 return expr_result; 896 } 897 898 bool 899 SBFrame::IsInlined() 900 { 901 if (m_opaque_sp) 902 { 903 Block *block = m_opaque_sp->GetSymbolContext(eSymbolContextBlock).block; 904 if (block) 905 return block->GetContainingInlinedBlock () != NULL; 906 } 907 return false; 908 } 909 910 const char * 911 SBFrame::GetFunctionName() 912 { 913 const char *name = NULL; 914 if (m_opaque_sp) 915 { 916 SymbolContext sc (m_opaque_sp->GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol)); 917 if (sc.block) 918 { 919 Block *inlined_block = sc.block->GetContainingInlinedBlock (); 920 if (inlined_block) 921 { 922 const InlineFunctionInfo* inlined_info = inlined_block->GetInlinedFunctionInfo(); 923 name = inlined_info->GetName().AsCString(); 924 } 925 } 926 927 if (name == NULL) 928 { 929 if (sc.function) 930 name = sc.function->GetName().GetCString(); 931 } 932 933 if (name == NULL) 934 { 935 if (sc.symbol) 936 name = sc.symbol->GetName().GetCString(); 937 } 938 } 939 return name; 940 } 941 942