1 //===-- SBValue.cpp -------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/API/SBValue.h" 10 #include "lldb/Utility/Instrumentation.h" 11 12 #include "lldb/API/SBDeclaration.h" 13 #include "lldb/API/SBStream.h" 14 #include "lldb/API/SBTypeFilter.h" 15 #include "lldb/API/SBTypeFormat.h" 16 #include "lldb/API/SBTypeSummary.h" 17 #include "lldb/API/SBTypeSynthetic.h" 18 19 #include "lldb/Breakpoint/Watchpoint.h" 20 #include "lldb/Core/Declaration.h" 21 #include "lldb/Core/Module.h" 22 #include "lldb/Core/Section.h" 23 #include "lldb/Core/Value.h" 24 #include "lldb/Core/ValueObject.h" 25 #include "lldb/Core/ValueObjectConstResult.h" 26 #include "lldb/DataFormatters/DataVisualization.h" 27 #include "lldb/Symbol/Block.h" 28 #include "lldb/Symbol/ObjectFile.h" 29 #include "lldb/Symbol/Type.h" 30 #include "lldb/Symbol/Variable.h" 31 #include "lldb/Symbol/VariableList.h" 32 #include "lldb/Target/ExecutionContext.h" 33 #include "lldb/Target/Process.h" 34 #include "lldb/Target/StackFrame.h" 35 #include "lldb/Target/Target.h" 36 #include "lldb/Target/Thread.h" 37 #include "lldb/Utility/DataExtractor.h" 38 #include "lldb/Utility/Scalar.h" 39 #include "lldb/Utility/Stream.h" 40 41 #include "lldb/API/SBDebugger.h" 42 #include "lldb/API/SBExpressionOptions.h" 43 #include "lldb/API/SBFrame.h" 44 #include "lldb/API/SBProcess.h" 45 #include "lldb/API/SBTarget.h" 46 #include "lldb/API/SBThread.h" 47 48 #include <memory> 49 50 using namespace lldb; 51 using namespace lldb_private; 52 53 class ValueImpl { 54 public: 55 ValueImpl() = default; 56 57 ValueImpl(lldb::ValueObjectSP in_valobj_sp, 58 lldb::DynamicValueType use_dynamic, bool use_synthetic, 59 const char *name = nullptr) 60 : m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic), 61 m_name(name) { 62 if (in_valobj_sp) { 63 if ((m_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable( 64 lldb::eNoDynamicValues, false))) { 65 if (!m_name.IsEmpty()) 66 m_valobj_sp->SetName(m_name); 67 } 68 } 69 } 70 71 ValueImpl(const ValueImpl &rhs) = default; 72 73 ValueImpl &operator=(const ValueImpl &rhs) { 74 if (this != &rhs) { 75 m_valobj_sp = rhs.m_valobj_sp; 76 m_use_dynamic = rhs.m_use_dynamic; 77 m_use_synthetic = rhs.m_use_synthetic; 78 m_name = rhs.m_name; 79 } 80 return *this; 81 } 82 83 bool IsValid() { 84 if (m_valobj_sp.get() == nullptr) 85 return false; 86 else { 87 // FIXME: This check is necessary but not sufficient. We for sure don't 88 // want to touch SBValues whose owning 89 // targets have gone away. This check is a little weak in that it 90 // enforces that restriction when you call IsValid, but since IsValid 91 // doesn't lock the target, you have no guarantee that the SBValue won't 92 // go invalid after you call this... Also, an SBValue could depend on 93 // data from one of the modules in the target, and those could go away 94 // independently of the target, for instance if a module is unloaded. 95 // But right now, neither SBValues nor ValueObjects know which modules 96 // they depend on. So I have no good way to make that check without 97 // tracking that in all the ValueObject subclasses. 98 TargetSP target_sp = m_valobj_sp->GetTargetSP(); 99 return target_sp && target_sp->IsValid(); 100 } 101 } 102 103 lldb::ValueObjectSP GetRootSP() { return m_valobj_sp; } 104 105 lldb::ValueObjectSP GetSP(Process::StopLocker &stop_locker, 106 std::unique_lock<std::recursive_mutex> &lock, 107 Status &error) { 108 if (!m_valobj_sp) { 109 error.SetErrorString("invalid value object"); 110 return m_valobj_sp; 111 } 112 113 lldb::ValueObjectSP value_sp = m_valobj_sp; 114 115 Target *target = value_sp->GetTargetSP().get(); 116 // If this ValueObject holds an error, then it is valuable for that. 117 if (value_sp->GetError().Fail()) 118 return value_sp; 119 120 if (!target) 121 return ValueObjectSP(); 122 123 lock = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex()); 124 125 ProcessSP process_sp(value_sp->GetProcessSP()); 126 if (process_sp && !stop_locker.TryLock(&process_sp->GetRunLock())) { 127 // We don't allow people to play around with ValueObject if the process 128 // is running. If you want to look at values, pause the process, then 129 // look. 130 error.SetErrorString("process must be stopped."); 131 return ValueObjectSP(); 132 } 133 134 if (m_use_dynamic != eNoDynamicValues) { 135 ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(m_use_dynamic); 136 if (dynamic_sp) 137 value_sp = dynamic_sp; 138 } 139 140 if (m_use_synthetic) { 141 ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue(); 142 if (synthetic_sp) 143 value_sp = synthetic_sp; 144 } 145 146 if (!value_sp) 147 error.SetErrorString("invalid value object"); 148 if (!m_name.IsEmpty()) 149 value_sp->SetName(m_name); 150 151 return value_sp; 152 } 153 154 void SetUseDynamic(lldb::DynamicValueType use_dynamic) { 155 m_use_dynamic = use_dynamic; 156 } 157 158 void SetUseSynthetic(bool use_synthetic) { m_use_synthetic = use_synthetic; } 159 160 lldb::DynamicValueType GetUseDynamic() { return m_use_dynamic; } 161 162 bool GetUseSynthetic() { return m_use_synthetic; } 163 164 // All the derived values that we would make from the m_valobj_sp will share 165 // the ExecutionContext with m_valobj_sp, so we don't need to do the 166 // calculations in GetSP to return the Target, Process, Thread or Frame. It 167 // is convenient to provide simple accessors for these, which I do here. 168 TargetSP GetTargetSP() { 169 if (m_valobj_sp) 170 return m_valobj_sp->GetTargetSP(); 171 else 172 return TargetSP(); 173 } 174 175 ProcessSP GetProcessSP() { 176 if (m_valobj_sp) 177 return m_valobj_sp->GetProcessSP(); 178 else 179 return ProcessSP(); 180 } 181 182 ThreadSP GetThreadSP() { 183 if (m_valobj_sp) 184 return m_valobj_sp->GetThreadSP(); 185 else 186 return ThreadSP(); 187 } 188 189 StackFrameSP GetFrameSP() { 190 if (m_valobj_sp) 191 return m_valobj_sp->GetFrameSP(); 192 else 193 return StackFrameSP(); 194 } 195 196 private: 197 lldb::ValueObjectSP m_valobj_sp; 198 lldb::DynamicValueType m_use_dynamic; 199 bool m_use_synthetic; 200 ConstString m_name; 201 }; 202 203 class ValueLocker { 204 public: 205 ValueLocker() = default; 206 207 ValueObjectSP GetLockedSP(ValueImpl &in_value) { 208 return in_value.GetSP(m_stop_locker, m_lock, m_lock_error); 209 } 210 211 Status &GetError() { return m_lock_error; } 212 213 private: 214 Process::StopLocker m_stop_locker; 215 std::unique_lock<std::recursive_mutex> m_lock; 216 Status m_lock_error; 217 }; 218 219 SBValue::SBValue() { LLDB_INSTRUMENT_VA(this); } 220 221 SBValue::SBValue(const lldb::ValueObjectSP &value_sp) { 222 LLDB_INSTRUMENT_VA(this, value_sp); 223 224 SetSP(value_sp); 225 } 226 227 SBValue::SBValue(const SBValue &rhs) { 228 LLDB_INSTRUMENT_VA(this, rhs); 229 230 SetSP(rhs.m_opaque_sp); 231 } 232 233 SBValue &SBValue::operator=(const SBValue &rhs) { 234 LLDB_INSTRUMENT_VA(this, rhs); 235 236 if (this != &rhs) { 237 SetSP(rhs.m_opaque_sp); 238 } 239 return *this; 240 } 241 242 SBValue::~SBValue() = default; 243 244 bool SBValue::IsValid() { 245 LLDB_INSTRUMENT_VA(this); 246 return this->operator bool(); 247 } 248 SBValue::operator bool() const { 249 LLDB_INSTRUMENT_VA(this); 250 251 // If this function ever changes to anything that does more than just check 252 // if the opaque shared pointer is non NULL, then we need to update all "if 253 // (m_opaque_sp)" code in this file. 254 return m_opaque_sp.get() != nullptr && m_opaque_sp->IsValid() && 255 m_opaque_sp->GetRootSP().get() != nullptr; 256 } 257 258 void SBValue::Clear() { 259 LLDB_INSTRUMENT_VA(this); 260 261 m_opaque_sp.reset(); 262 } 263 264 SBError SBValue::GetError() { 265 LLDB_INSTRUMENT_VA(this); 266 267 SBError sb_error; 268 269 ValueLocker locker; 270 lldb::ValueObjectSP value_sp(GetSP(locker)); 271 if (value_sp) 272 sb_error.SetError(value_sp->GetError()); 273 else 274 sb_error.SetErrorStringWithFormat("error: %s", 275 locker.GetError().AsCString()); 276 277 return sb_error; 278 } 279 280 user_id_t SBValue::GetID() { 281 LLDB_INSTRUMENT_VA(this); 282 283 ValueLocker locker; 284 lldb::ValueObjectSP value_sp(GetSP(locker)); 285 if (value_sp) 286 return value_sp->GetID(); 287 return LLDB_INVALID_UID; 288 } 289 290 const char *SBValue::GetName() { 291 LLDB_INSTRUMENT_VA(this); 292 293 ValueLocker locker; 294 lldb::ValueObjectSP value_sp(GetSP(locker)); 295 if (!value_sp) 296 return nullptr; 297 298 return value_sp->GetName().GetCString(); 299 } 300 301 const char *SBValue::GetTypeName() { 302 LLDB_INSTRUMENT_VA(this); 303 304 ValueLocker locker; 305 lldb::ValueObjectSP value_sp(GetSP(locker)); 306 if (!value_sp) 307 return nullptr; 308 309 return value_sp->GetQualifiedTypeName().GetCString(); 310 } 311 312 const char *SBValue::GetDisplayTypeName() { 313 LLDB_INSTRUMENT_VA(this); 314 315 ValueLocker locker; 316 lldb::ValueObjectSP value_sp(GetSP(locker)); 317 if (!value_sp) 318 return nullptr; 319 320 return value_sp->GetDisplayTypeName().GetCString(); 321 } 322 323 size_t SBValue::GetByteSize() { 324 LLDB_INSTRUMENT_VA(this); 325 326 size_t result = 0; 327 328 ValueLocker locker; 329 lldb::ValueObjectSP value_sp(GetSP(locker)); 330 if (value_sp) { 331 result = value_sp->GetByteSize().value_or(0); 332 } 333 334 return result; 335 } 336 337 bool SBValue::IsInScope() { 338 LLDB_INSTRUMENT_VA(this); 339 340 bool result = false; 341 342 ValueLocker locker; 343 lldb::ValueObjectSP value_sp(GetSP(locker)); 344 if (value_sp) { 345 result = value_sp->IsInScope(); 346 } 347 348 return result; 349 } 350 351 const char *SBValue::GetValue() { 352 LLDB_INSTRUMENT_VA(this); 353 354 ValueLocker locker; 355 lldb::ValueObjectSP value_sp(GetSP(locker)); 356 if (!value_sp) 357 return nullptr; 358 return ConstString(value_sp->GetValueAsCString()).GetCString(); 359 } 360 361 ValueType SBValue::GetValueType() { 362 LLDB_INSTRUMENT_VA(this); 363 364 ValueType result = eValueTypeInvalid; 365 ValueLocker locker; 366 lldb::ValueObjectSP value_sp(GetSP(locker)); 367 if (value_sp) 368 result = value_sp->GetValueType(); 369 370 return result; 371 } 372 373 const char *SBValue::GetObjectDescription() { 374 LLDB_INSTRUMENT_VA(this); 375 376 ValueLocker locker; 377 lldb::ValueObjectSP value_sp(GetSP(locker)); 378 if (!value_sp) 379 return nullptr; 380 381 return ConstString(value_sp->GetObjectDescription()).GetCString(); 382 } 383 384 SBType SBValue::GetType() { 385 LLDB_INSTRUMENT_VA(this); 386 387 SBType sb_type; 388 ValueLocker locker; 389 lldb::ValueObjectSP value_sp(GetSP(locker)); 390 TypeImplSP type_sp; 391 if (value_sp) { 392 type_sp = std::make_shared<TypeImpl>(value_sp->GetTypeImpl()); 393 sb_type.SetSP(type_sp); 394 } 395 396 return sb_type; 397 } 398 399 bool SBValue::GetValueDidChange() { 400 LLDB_INSTRUMENT_VA(this); 401 402 bool result = false; 403 ValueLocker locker; 404 lldb::ValueObjectSP value_sp(GetSP(locker)); 405 if (value_sp) { 406 if (value_sp->UpdateValueIfNeeded(false)) 407 result = value_sp->GetValueDidChange(); 408 } 409 410 return result; 411 } 412 413 const char *SBValue::GetSummary() { 414 LLDB_INSTRUMENT_VA(this); 415 416 ValueLocker locker; 417 lldb::ValueObjectSP value_sp(GetSP(locker)); 418 if (!value_sp) 419 return nullptr; 420 421 return ConstString(value_sp->GetSummaryAsCString()).GetCString(); 422 } 423 424 const char *SBValue::GetSummary(lldb::SBStream &stream, 425 lldb::SBTypeSummaryOptions &options) { 426 LLDB_INSTRUMENT_VA(this, stream, options); 427 428 ValueLocker locker; 429 lldb::ValueObjectSP value_sp(GetSP(locker)); 430 if (value_sp) { 431 std::string buffer; 432 if (value_sp->GetSummaryAsCString(buffer, options.ref()) && !buffer.empty()) 433 stream.Printf("%s", buffer.c_str()); 434 } 435 return ConstString(stream.GetData()).GetCString(); 436 } 437 438 const char *SBValue::GetLocation() { 439 LLDB_INSTRUMENT_VA(this); 440 441 ValueLocker locker; 442 lldb::ValueObjectSP value_sp(GetSP(locker)); 443 if (!value_sp) 444 return nullptr; 445 446 return ConstString(value_sp->GetLocationAsCString()).GetCString(); 447 } 448 449 // Deprecated - use the one that takes an lldb::SBError 450 bool SBValue::SetValueFromCString(const char *value_str) { 451 LLDB_INSTRUMENT_VA(this, value_str); 452 453 lldb::SBError dummy; 454 return SetValueFromCString(value_str, dummy); 455 } 456 457 bool SBValue::SetValueFromCString(const char *value_str, lldb::SBError &error) { 458 LLDB_INSTRUMENT_VA(this, value_str, error); 459 460 bool success = false; 461 ValueLocker locker; 462 lldb::ValueObjectSP value_sp(GetSP(locker)); 463 if (value_sp) { 464 success = value_sp->SetValueFromCString(value_str, error.ref()); 465 } else 466 error.SetErrorStringWithFormat("Could not get value: %s", 467 locker.GetError().AsCString()); 468 469 return success; 470 } 471 472 lldb::SBTypeFormat SBValue::GetTypeFormat() { 473 LLDB_INSTRUMENT_VA(this); 474 475 lldb::SBTypeFormat format; 476 ValueLocker locker; 477 lldb::ValueObjectSP value_sp(GetSP(locker)); 478 if (value_sp) { 479 if (value_sp->UpdateValueIfNeeded(true)) { 480 lldb::TypeFormatImplSP format_sp = value_sp->GetValueFormat(); 481 if (format_sp) 482 format.SetSP(format_sp); 483 } 484 } 485 return format; 486 } 487 488 lldb::SBTypeSummary SBValue::GetTypeSummary() { 489 LLDB_INSTRUMENT_VA(this); 490 491 lldb::SBTypeSummary summary; 492 ValueLocker locker; 493 lldb::ValueObjectSP value_sp(GetSP(locker)); 494 if (value_sp) { 495 if (value_sp->UpdateValueIfNeeded(true)) { 496 lldb::TypeSummaryImplSP summary_sp = value_sp->GetSummaryFormat(); 497 if (summary_sp) 498 summary.SetSP(summary_sp); 499 } 500 } 501 return summary; 502 } 503 504 lldb::SBTypeFilter SBValue::GetTypeFilter() { 505 LLDB_INSTRUMENT_VA(this); 506 507 lldb::SBTypeFilter filter; 508 ValueLocker locker; 509 lldb::ValueObjectSP value_sp(GetSP(locker)); 510 if (value_sp) { 511 if (value_sp->UpdateValueIfNeeded(true)) { 512 lldb::SyntheticChildrenSP synthetic_sp = value_sp->GetSyntheticChildren(); 513 514 if (synthetic_sp && !synthetic_sp->IsScripted()) { 515 TypeFilterImplSP filter_sp = 516 std::static_pointer_cast<TypeFilterImpl>(synthetic_sp); 517 filter.SetSP(filter_sp); 518 } 519 } 520 } 521 return filter; 522 } 523 524 lldb::SBTypeSynthetic SBValue::GetTypeSynthetic() { 525 LLDB_INSTRUMENT_VA(this); 526 527 lldb::SBTypeSynthetic synthetic; 528 ValueLocker locker; 529 lldb::ValueObjectSP value_sp(GetSP(locker)); 530 if (value_sp) { 531 if (value_sp->UpdateValueIfNeeded(true)) { 532 lldb::SyntheticChildrenSP children_sp = value_sp->GetSyntheticChildren(); 533 534 if (children_sp && children_sp->IsScripted()) { 535 ScriptedSyntheticChildrenSP synth_sp = 536 std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp); 537 synthetic.SetSP(synth_sp); 538 } 539 } 540 } 541 return synthetic; 542 } 543 544 lldb::SBValue SBValue::CreateChildAtOffset(const char *name, uint32_t offset, 545 SBType type) { 546 LLDB_INSTRUMENT_VA(this, name, offset, type); 547 548 lldb::SBValue sb_value; 549 ValueLocker locker; 550 lldb::ValueObjectSP value_sp(GetSP(locker)); 551 lldb::ValueObjectSP new_value_sp; 552 if (value_sp) { 553 TypeImplSP type_sp(type.GetSP()); 554 if (type.IsValid()) { 555 sb_value.SetSP(value_sp->GetSyntheticChildAtOffset( 556 offset, type_sp->GetCompilerType(false), true), 557 GetPreferDynamicValue(), GetPreferSyntheticValue(), name); 558 } 559 } 560 return sb_value; 561 } 562 563 lldb::SBValue SBValue::Cast(SBType type) { 564 LLDB_INSTRUMENT_VA(this, type); 565 566 lldb::SBValue sb_value; 567 ValueLocker locker; 568 lldb::ValueObjectSP value_sp(GetSP(locker)); 569 TypeImplSP type_sp(type.GetSP()); 570 if (value_sp && type_sp) 571 sb_value.SetSP(value_sp->Cast(type_sp->GetCompilerType(false)), 572 GetPreferDynamicValue(), GetPreferSyntheticValue()); 573 return sb_value; 574 } 575 576 lldb::SBValue SBValue::CreateValueFromExpression(const char *name, 577 const char *expression) { 578 LLDB_INSTRUMENT_VA(this, name, expression); 579 580 SBExpressionOptions options; 581 options.ref().SetKeepInMemory(true); 582 return CreateValueFromExpression(name, expression, options); 583 } 584 585 lldb::SBValue SBValue::CreateValueFromExpression(const char *name, 586 const char *expression, 587 SBExpressionOptions &options) { 588 LLDB_INSTRUMENT_VA(this, name, expression, options); 589 590 lldb::SBValue sb_value; 591 ValueLocker locker; 592 lldb::ValueObjectSP value_sp(GetSP(locker)); 593 lldb::ValueObjectSP new_value_sp; 594 if (value_sp) { 595 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef()); 596 new_value_sp = ValueObject::CreateValueObjectFromExpression( 597 name, expression, exe_ctx, options.ref()); 598 if (new_value_sp) 599 new_value_sp->SetName(ConstString(name)); 600 } 601 sb_value.SetSP(new_value_sp); 602 return sb_value; 603 } 604 605 lldb::SBValue SBValue::CreateValueFromAddress(const char *name, 606 lldb::addr_t address, 607 SBType sb_type) { 608 LLDB_INSTRUMENT_VA(this, name, address, sb_type); 609 610 lldb::SBValue sb_value; 611 ValueLocker locker; 612 lldb::ValueObjectSP value_sp(GetSP(locker)); 613 lldb::ValueObjectSP new_value_sp; 614 lldb::TypeImplSP type_impl_sp(sb_type.GetSP()); 615 if (value_sp && type_impl_sp) { 616 CompilerType ast_type(type_impl_sp->GetCompilerType(true)); 617 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef()); 618 new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address, 619 exe_ctx, ast_type); 620 } 621 sb_value.SetSP(new_value_sp); 622 return sb_value; 623 } 624 625 lldb::SBValue SBValue::CreateValueFromData(const char *name, SBData data, 626 SBType sb_type) { 627 LLDB_INSTRUMENT_VA(this, name, data, sb_type); 628 629 lldb::SBValue sb_value; 630 lldb::ValueObjectSP new_value_sp; 631 ValueLocker locker; 632 lldb::ValueObjectSP value_sp(GetSP(locker)); 633 lldb::TypeImplSP type_impl_sp(sb_type.GetSP()); 634 if (value_sp && type_impl_sp) { 635 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef()); 636 new_value_sp = ValueObject::CreateValueObjectFromData( 637 name, **data, exe_ctx, type_impl_sp->GetCompilerType(true)); 638 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad); 639 } 640 sb_value.SetSP(new_value_sp); 641 return sb_value; 642 } 643 644 SBValue SBValue::GetChildAtIndex(uint32_t idx) { 645 LLDB_INSTRUMENT_VA(this, idx); 646 647 const bool can_create_synthetic = false; 648 lldb::DynamicValueType use_dynamic = eNoDynamicValues; 649 TargetSP target_sp; 650 if (m_opaque_sp) 651 target_sp = m_opaque_sp->GetTargetSP(); 652 653 if (target_sp) 654 use_dynamic = target_sp->GetPreferDynamicValue(); 655 656 return GetChildAtIndex(idx, use_dynamic, can_create_synthetic); 657 } 658 659 SBValue SBValue::GetChildAtIndex(uint32_t idx, 660 lldb::DynamicValueType use_dynamic, 661 bool can_create_synthetic) { 662 LLDB_INSTRUMENT_VA(this, idx, use_dynamic, can_create_synthetic); 663 664 lldb::ValueObjectSP child_sp; 665 666 ValueLocker locker; 667 lldb::ValueObjectSP value_sp(GetSP(locker)); 668 if (value_sp) { 669 const bool can_create = true; 670 child_sp = value_sp->GetChildAtIndex(idx); 671 if (can_create_synthetic && !child_sp) { 672 child_sp = value_sp->GetSyntheticArrayMember(idx, can_create); 673 } 674 } 675 676 SBValue sb_value; 677 sb_value.SetSP(child_sp, use_dynamic, GetPreferSyntheticValue()); 678 679 return sb_value; 680 } 681 682 uint32_t SBValue::GetIndexOfChildWithName(const char *name) { 683 LLDB_INSTRUMENT_VA(this, name); 684 685 uint32_t idx = UINT32_MAX; 686 ValueLocker locker; 687 lldb::ValueObjectSP value_sp(GetSP(locker)); 688 if (value_sp) { 689 idx = value_sp->GetIndexOfChildWithName(name); 690 } 691 return idx; 692 } 693 694 SBValue SBValue::GetChildMemberWithName(const char *name) { 695 LLDB_INSTRUMENT_VA(this, name); 696 697 lldb::DynamicValueType use_dynamic_value = eNoDynamicValues; 698 TargetSP target_sp; 699 if (m_opaque_sp) 700 target_sp = m_opaque_sp->GetTargetSP(); 701 702 if (target_sp) 703 use_dynamic_value = target_sp->GetPreferDynamicValue(); 704 return GetChildMemberWithName(name, use_dynamic_value); 705 } 706 707 SBValue 708 SBValue::GetChildMemberWithName(const char *name, 709 lldb::DynamicValueType use_dynamic_value) { 710 LLDB_INSTRUMENT_VA(this, name, use_dynamic_value); 711 712 lldb::ValueObjectSP child_sp; 713 714 ValueLocker locker; 715 lldb::ValueObjectSP value_sp(GetSP(locker)); 716 if (value_sp) { 717 child_sp = value_sp->GetChildMemberWithName(name); 718 } 719 720 SBValue sb_value; 721 sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue()); 722 723 return sb_value; 724 } 725 726 lldb::SBValue SBValue::GetDynamicValue(lldb::DynamicValueType use_dynamic) { 727 LLDB_INSTRUMENT_VA(this, use_dynamic); 728 729 SBValue value_sb; 730 if (IsValid()) { 731 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), use_dynamic, 732 m_opaque_sp->GetUseSynthetic())); 733 value_sb.SetSP(proxy_sp); 734 } 735 return value_sb; 736 } 737 738 lldb::SBValue SBValue::GetStaticValue() { 739 LLDB_INSTRUMENT_VA(this); 740 741 SBValue value_sb; 742 if (IsValid()) { 743 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), 744 eNoDynamicValues, 745 m_opaque_sp->GetUseSynthetic())); 746 value_sb.SetSP(proxy_sp); 747 } 748 return value_sb; 749 } 750 751 lldb::SBValue SBValue::GetNonSyntheticValue() { 752 LLDB_INSTRUMENT_VA(this); 753 754 SBValue value_sb; 755 if (IsValid()) { 756 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), 757 m_opaque_sp->GetUseDynamic(), false)); 758 value_sb.SetSP(proxy_sp); 759 } 760 return value_sb; 761 } 762 763 lldb::DynamicValueType SBValue::GetPreferDynamicValue() { 764 LLDB_INSTRUMENT_VA(this); 765 766 if (!IsValid()) 767 return eNoDynamicValues; 768 return m_opaque_sp->GetUseDynamic(); 769 } 770 771 void SBValue::SetPreferDynamicValue(lldb::DynamicValueType use_dynamic) { 772 LLDB_INSTRUMENT_VA(this, use_dynamic); 773 774 if (IsValid()) 775 return m_opaque_sp->SetUseDynamic(use_dynamic); 776 } 777 778 bool SBValue::GetPreferSyntheticValue() { 779 LLDB_INSTRUMENT_VA(this); 780 781 if (!IsValid()) 782 return false; 783 return m_opaque_sp->GetUseSynthetic(); 784 } 785 786 void SBValue::SetPreferSyntheticValue(bool use_synthetic) { 787 LLDB_INSTRUMENT_VA(this, use_synthetic); 788 789 if (IsValid()) 790 return m_opaque_sp->SetUseSynthetic(use_synthetic); 791 } 792 793 bool SBValue::IsDynamic() { 794 LLDB_INSTRUMENT_VA(this); 795 796 ValueLocker locker; 797 lldb::ValueObjectSP value_sp(GetSP(locker)); 798 if (value_sp) 799 return value_sp->IsDynamic(); 800 return false; 801 } 802 803 bool SBValue::IsSynthetic() { 804 LLDB_INSTRUMENT_VA(this); 805 806 ValueLocker locker; 807 lldb::ValueObjectSP value_sp(GetSP(locker)); 808 if (value_sp) 809 return value_sp->IsSynthetic(); 810 return false; 811 } 812 813 bool SBValue::IsSyntheticChildrenGenerated() { 814 LLDB_INSTRUMENT_VA(this); 815 816 ValueLocker locker; 817 lldb::ValueObjectSP value_sp(GetSP(locker)); 818 if (value_sp) 819 return value_sp->IsSyntheticChildrenGenerated(); 820 return false; 821 } 822 823 void SBValue::SetSyntheticChildrenGenerated(bool is) { 824 LLDB_INSTRUMENT_VA(this, is); 825 826 ValueLocker locker; 827 lldb::ValueObjectSP value_sp(GetSP(locker)); 828 if (value_sp) 829 return value_sp->SetSyntheticChildrenGenerated(is); 830 } 831 832 lldb::SBValue SBValue::GetValueForExpressionPath(const char *expr_path) { 833 LLDB_INSTRUMENT_VA(this, expr_path); 834 835 lldb::ValueObjectSP child_sp; 836 ValueLocker locker; 837 lldb::ValueObjectSP value_sp(GetSP(locker)); 838 if (value_sp) { 839 // using default values for all the fancy options, just do it if you can 840 child_sp = value_sp->GetValueForExpressionPath(expr_path); 841 } 842 843 SBValue sb_value; 844 sb_value.SetSP(child_sp, GetPreferDynamicValue(), GetPreferSyntheticValue()); 845 846 return sb_value; 847 } 848 849 int64_t SBValue::GetValueAsSigned(SBError &error, int64_t fail_value) { 850 LLDB_INSTRUMENT_VA(this, error, fail_value); 851 852 error.Clear(); 853 ValueLocker locker; 854 lldb::ValueObjectSP value_sp(GetSP(locker)); 855 if (value_sp) { 856 bool success = true; 857 uint64_t ret_val = fail_value; 858 ret_val = value_sp->GetValueAsSigned(fail_value, &success); 859 if (!success) 860 error.SetErrorString("could not resolve value"); 861 return ret_val; 862 } else 863 error.SetErrorStringWithFormat("could not get SBValue: %s", 864 locker.GetError().AsCString()); 865 866 return fail_value; 867 } 868 869 uint64_t SBValue::GetValueAsUnsigned(SBError &error, uint64_t fail_value) { 870 LLDB_INSTRUMENT_VA(this, error, fail_value); 871 872 error.Clear(); 873 ValueLocker locker; 874 lldb::ValueObjectSP value_sp(GetSP(locker)); 875 if (value_sp) { 876 bool success = true; 877 uint64_t ret_val = fail_value; 878 ret_val = value_sp->GetValueAsUnsigned(fail_value, &success); 879 if (!success) 880 error.SetErrorString("could not resolve value"); 881 return ret_val; 882 } else 883 error.SetErrorStringWithFormat("could not get SBValue: %s", 884 locker.GetError().AsCString()); 885 886 return fail_value; 887 } 888 889 int64_t SBValue::GetValueAsSigned(int64_t fail_value) { 890 LLDB_INSTRUMENT_VA(this, fail_value); 891 892 ValueLocker locker; 893 lldb::ValueObjectSP value_sp(GetSP(locker)); 894 if (value_sp) { 895 return value_sp->GetValueAsSigned(fail_value); 896 } 897 return fail_value; 898 } 899 900 uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) { 901 LLDB_INSTRUMENT_VA(this, fail_value); 902 903 ValueLocker locker; 904 lldb::ValueObjectSP value_sp(GetSP(locker)); 905 if (value_sp) { 906 return value_sp->GetValueAsUnsigned(fail_value); 907 } 908 return fail_value; 909 } 910 911 bool SBValue::MightHaveChildren() { 912 LLDB_INSTRUMENT_VA(this); 913 914 bool has_children = false; 915 ValueLocker locker; 916 lldb::ValueObjectSP value_sp(GetSP(locker)); 917 if (value_sp) 918 has_children = value_sp->MightHaveChildren(); 919 920 return has_children; 921 } 922 923 bool SBValue::IsRuntimeSupportValue() { 924 LLDB_INSTRUMENT_VA(this); 925 926 bool is_support = false; 927 ValueLocker locker; 928 lldb::ValueObjectSP value_sp(GetSP(locker)); 929 if (value_sp) 930 is_support = value_sp->IsRuntimeSupportValue(); 931 932 return is_support; 933 } 934 935 uint32_t SBValue::GetNumChildren() { 936 LLDB_INSTRUMENT_VA(this); 937 938 return GetNumChildren(UINT32_MAX); 939 } 940 941 uint32_t SBValue::GetNumChildren(uint32_t max) { 942 LLDB_INSTRUMENT_VA(this, max); 943 944 uint32_t num_children = 0; 945 946 ValueLocker locker; 947 lldb::ValueObjectSP value_sp(GetSP(locker)); 948 if (value_sp) 949 num_children = value_sp->GetNumChildren(max); 950 951 return num_children; 952 } 953 954 SBValue SBValue::Dereference() { 955 LLDB_INSTRUMENT_VA(this); 956 957 SBValue sb_value; 958 ValueLocker locker; 959 lldb::ValueObjectSP value_sp(GetSP(locker)); 960 if (value_sp) { 961 Status error; 962 sb_value = value_sp->Dereference(error); 963 } 964 965 return sb_value; 966 } 967 968 // Deprecated - please use GetType().IsPointerType() instead. 969 bool SBValue::TypeIsPointerType() { 970 LLDB_INSTRUMENT_VA(this); 971 972 return GetType().IsPointerType(); 973 } 974 975 void *SBValue::GetOpaqueType() { 976 LLDB_INSTRUMENT_VA(this); 977 978 ValueLocker locker; 979 lldb::ValueObjectSP value_sp(GetSP(locker)); 980 if (value_sp) 981 return value_sp->GetCompilerType().GetOpaqueQualType(); 982 return nullptr; 983 } 984 985 lldb::SBTarget SBValue::GetTarget() { 986 LLDB_INSTRUMENT_VA(this); 987 988 SBTarget sb_target; 989 TargetSP target_sp; 990 if (m_opaque_sp) { 991 target_sp = m_opaque_sp->GetTargetSP(); 992 sb_target.SetSP(target_sp); 993 } 994 995 return sb_target; 996 } 997 998 lldb::SBProcess SBValue::GetProcess() { 999 LLDB_INSTRUMENT_VA(this); 1000 1001 SBProcess sb_process; 1002 ProcessSP process_sp; 1003 if (m_opaque_sp) { 1004 process_sp = m_opaque_sp->GetProcessSP(); 1005 sb_process.SetSP(process_sp); 1006 } 1007 1008 return sb_process; 1009 } 1010 1011 lldb::SBThread SBValue::GetThread() { 1012 LLDB_INSTRUMENT_VA(this); 1013 1014 SBThread sb_thread; 1015 ThreadSP thread_sp; 1016 if (m_opaque_sp) { 1017 thread_sp = m_opaque_sp->GetThreadSP(); 1018 sb_thread.SetThread(thread_sp); 1019 } 1020 1021 return sb_thread; 1022 } 1023 1024 lldb::SBFrame SBValue::GetFrame() { 1025 LLDB_INSTRUMENT_VA(this); 1026 1027 SBFrame sb_frame; 1028 StackFrameSP frame_sp; 1029 if (m_opaque_sp) { 1030 frame_sp = m_opaque_sp->GetFrameSP(); 1031 sb_frame.SetFrameSP(frame_sp); 1032 } 1033 1034 return sb_frame; 1035 } 1036 1037 lldb::ValueObjectSP SBValue::GetSP(ValueLocker &locker) const { 1038 // IsValid means that the SBValue has a value in it. But that's not the 1039 // only time that ValueObjects are useful. We also want to return the value 1040 // if there's an error state in it. 1041 if (!m_opaque_sp || (!m_opaque_sp->IsValid() 1042 && (m_opaque_sp->GetRootSP() 1043 && !m_opaque_sp->GetRootSP()->GetError().Fail()))) { 1044 locker.GetError().SetErrorString("No value"); 1045 return ValueObjectSP(); 1046 } 1047 return locker.GetLockedSP(*m_opaque_sp.get()); 1048 } 1049 1050 lldb::ValueObjectSP SBValue::GetSP() const { 1051 LLDB_INSTRUMENT_VA(this); 1052 1053 ValueLocker locker; 1054 return GetSP(locker); 1055 } 1056 1057 void SBValue::SetSP(ValueImplSP impl_sp) { m_opaque_sp = impl_sp; } 1058 1059 void SBValue::SetSP(const lldb::ValueObjectSP &sp) { 1060 if (sp) { 1061 lldb::TargetSP target_sp(sp->GetTargetSP()); 1062 if (target_sp) { 1063 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); 1064 bool use_synthetic = 1065 target_sp->TargetProperties::GetEnableSyntheticValue(); 1066 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic)); 1067 } else 1068 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, true)); 1069 } else 1070 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, false)); 1071 } 1072 1073 void SBValue::SetSP(const lldb::ValueObjectSP &sp, 1074 lldb::DynamicValueType use_dynamic) { 1075 if (sp) { 1076 lldb::TargetSP target_sp(sp->GetTargetSP()); 1077 if (target_sp) { 1078 bool use_synthetic = 1079 target_sp->TargetProperties::GetEnableSyntheticValue(); 1080 SetSP(sp, use_dynamic, use_synthetic); 1081 } else 1082 SetSP(sp, use_dynamic, true); 1083 } else 1084 SetSP(sp, use_dynamic, false); 1085 } 1086 1087 void SBValue::SetSP(const lldb::ValueObjectSP &sp, bool use_synthetic) { 1088 if (sp) { 1089 lldb::TargetSP target_sp(sp->GetTargetSP()); 1090 if (target_sp) { 1091 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); 1092 SetSP(sp, use_dynamic, use_synthetic); 1093 } else 1094 SetSP(sp, eNoDynamicValues, use_synthetic); 1095 } else 1096 SetSP(sp, eNoDynamicValues, use_synthetic); 1097 } 1098 1099 void SBValue::SetSP(const lldb::ValueObjectSP &sp, 1100 lldb::DynamicValueType use_dynamic, bool use_synthetic) { 1101 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic)); 1102 } 1103 1104 void SBValue::SetSP(const lldb::ValueObjectSP &sp, 1105 lldb::DynamicValueType use_dynamic, bool use_synthetic, 1106 const char *name) { 1107 m_opaque_sp = 1108 ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic, name)); 1109 } 1110 1111 bool SBValue::GetExpressionPath(SBStream &description) { 1112 LLDB_INSTRUMENT_VA(this, description); 1113 1114 ValueLocker locker; 1115 lldb::ValueObjectSP value_sp(GetSP(locker)); 1116 if (value_sp) { 1117 value_sp->GetExpressionPath(description.ref()); 1118 return true; 1119 } 1120 return false; 1121 } 1122 1123 bool SBValue::GetExpressionPath(SBStream &description, 1124 bool qualify_cxx_base_classes) { 1125 LLDB_INSTRUMENT_VA(this, description, qualify_cxx_base_classes); 1126 1127 ValueLocker locker; 1128 lldb::ValueObjectSP value_sp(GetSP(locker)); 1129 if (value_sp) { 1130 value_sp->GetExpressionPath(description.ref()); 1131 return true; 1132 } 1133 return false; 1134 } 1135 1136 lldb::SBValue SBValue::EvaluateExpression(const char *expr) const { 1137 LLDB_INSTRUMENT_VA(this, expr); 1138 1139 ValueLocker locker; 1140 lldb::ValueObjectSP value_sp(GetSP(locker)); 1141 if (!value_sp) 1142 return SBValue(); 1143 1144 lldb::TargetSP target_sp = value_sp->GetTargetSP(); 1145 if (!target_sp) 1146 return SBValue(); 1147 1148 lldb::SBExpressionOptions options; 1149 options.SetFetchDynamicValue(target_sp->GetPreferDynamicValue()); 1150 options.SetUnwindOnError(true); 1151 options.SetIgnoreBreakpoints(true); 1152 1153 return EvaluateExpression(expr, options, nullptr); 1154 } 1155 1156 lldb::SBValue 1157 SBValue::EvaluateExpression(const char *expr, 1158 const SBExpressionOptions &options) const { 1159 LLDB_INSTRUMENT_VA(this, expr, options); 1160 1161 return EvaluateExpression(expr, options, nullptr); 1162 } 1163 1164 lldb::SBValue SBValue::EvaluateExpression(const char *expr, 1165 const SBExpressionOptions &options, 1166 const char *name) const { 1167 LLDB_INSTRUMENT_VA(this, expr, options, name); 1168 1169 if (!expr || expr[0] == '\0') { 1170 return SBValue(); 1171 } 1172 1173 1174 ValueLocker locker; 1175 lldb::ValueObjectSP value_sp(GetSP(locker)); 1176 if (!value_sp) { 1177 return SBValue(); 1178 } 1179 1180 lldb::TargetSP target_sp = value_sp->GetTargetSP(); 1181 if (!target_sp) { 1182 return SBValue(); 1183 } 1184 1185 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); 1186 ExecutionContext exe_ctx(target_sp.get()); 1187 1188 StackFrame *frame = exe_ctx.GetFramePtr(); 1189 if (!frame) { 1190 return SBValue(); 1191 } 1192 1193 ValueObjectSP res_val_sp; 1194 target_sp->EvaluateExpression(expr, frame, res_val_sp, options.ref(), nullptr, 1195 value_sp.get()); 1196 1197 if (name) 1198 res_val_sp->SetName(ConstString(name)); 1199 1200 SBValue result; 1201 result.SetSP(res_val_sp, options.GetFetchDynamicValue()); 1202 return result; 1203 } 1204 1205 bool SBValue::GetDescription(SBStream &description) { 1206 LLDB_INSTRUMENT_VA(this, description); 1207 1208 Stream &strm = description.ref(); 1209 1210 ValueLocker locker; 1211 lldb::ValueObjectSP value_sp(GetSP(locker)); 1212 if (value_sp) 1213 value_sp->Dump(strm); 1214 else 1215 strm.PutCString("No value"); 1216 1217 return true; 1218 } 1219 1220 lldb::Format SBValue::GetFormat() { 1221 LLDB_INSTRUMENT_VA(this); 1222 1223 ValueLocker locker; 1224 lldb::ValueObjectSP value_sp(GetSP(locker)); 1225 if (value_sp) 1226 return value_sp->GetFormat(); 1227 return eFormatDefault; 1228 } 1229 1230 void SBValue::SetFormat(lldb::Format format) { 1231 LLDB_INSTRUMENT_VA(this, format); 1232 1233 ValueLocker locker; 1234 lldb::ValueObjectSP value_sp(GetSP(locker)); 1235 if (value_sp) 1236 value_sp->SetFormat(format); 1237 } 1238 1239 lldb::SBValue SBValue::AddressOf() { 1240 LLDB_INSTRUMENT_VA(this); 1241 1242 SBValue sb_value; 1243 ValueLocker locker; 1244 lldb::ValueObjectSP value_sp(GetSP(locker)); 1245 if (value_sp) { 1246 Status error; 1247 sb_value.SetSP(value_sp->AddressOf(error), GetPreferDynamicValue(), 1248 GetPreferSyntheticValue()); 1249 } 1250 1251 return sb_value; 1252 } 1253 1254 lldb::addr_t SBValue::GetLoadAddress() { 1255 LLDB_INSTRUMENT_VA(this); 1256 1257 lldb::addr_t value = LLDB_INVALID_ADDRESS; 1258 ValueLocker locker; 1259 lldb::ValueObjectSP value_sp(GetSP(locker)); 1260 if (value_sp) { 1261 TargetSP target_sp(value_sp->GetTargetSP()); 1262 if (target_sp) { 1263 const bool scalar_is_load_address = true; 1264 AddressType addr_type; 1265 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type); 1266 if (addr_type == eAddressTypeFile) { 1267 ModuleSP module_sp(value_sp->GetModule()); 1268 if (!module_sp) 1269 value = LLDB_INVALID_ADDRESS; 1270 else { 1271 Address addr; 1272 module_sp->ResolveFileAddress(value, addr); 1273 value = addr.GetLoadAddress(target_sp.get()); 1274 } 1275 } else if (addr_type == eAddressTypeHost || 1276 addr_type == eAddressTypeInvalid) 1277 value = LLDB_INVALID_ADDRESS; 1278 } 1279 } 1280 1281 return value; 1282 } 1283 1284 lldb::SBAddress SBValue::GetAddress() { 1285 LLDB_INSTRUMENT_VA(this); 1286 1287 Address addr; 1288 ValueLocker locker; 1289 lldb::ValueObjectSP value_sp(GetSP(locker)); 1290 if (value_sp) { 1291 TargetSP target_sp(value_sp->GetTargetSP()); 1292 if (target_sp) { 1293 lldb::addr_t value = LLDB_INVALID_ADDRESS; 1294 const bool scalar_is_load_address = true; 1295 AddressType addr_type; 1296 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type); 1297 if (addr_type == eAddressTypeFile) { 1298 ModuleSP module_sp(value_sp->GetModule()); 1299 if (module_sp) 1300 module_sp->ResolveFileAddress(value, addr); 1301 } else if (addr_type == eAddressTypeLoad) { 1302 // no need to check the return value on this.. if it can actually do 1303 // the resolve addr will be in the form (section,offset), otherwise it 1304 // will simply be returned as (NULL, value) 1305 addr.SetLoadAddress(value, target_sp.get()); 1306 } 1307 } 1308 } 1309 1310 return SBAddress(addr); 1311 } 1312 1313 lldb::SBData SBValue::GetPointeeData(uint32_t item_idx, uint32_t item_count) { 1314 LLDB_INSTRUMENT_VA(this, item_idx, item_count); 1315 1316 lldb::SBData sb_data; 1317 ValueLocker locker; 1318 lldb::ValueObjectSP value_sp(GetSP(locker)); 1319 if (value_sp) { 1320 TargetSP target_sp(value_sp->GetTargetSP()); 1321 if (target_sp) { 1322 DataExtractorSP data_sp(new DataExtractor()); 1323 value_sp->GetPointeeData(*data_sp, item_idx, item_count); 1324 if (data_sp->GetByteSize() > 0) 1325 *sb_data = data_sp; 1326 } 1327 } 1328 1329 return sb_data; 1330 } 1331 1332 lldb::SBData SBValue::GetData() { 1333 LLDB_INSTRUMENT_VA(this); 1334 1335 lldb::SBData sb_data; 1336 ValueLocker locker; 1337 lldb::ValueObjectSP value_sp(GetSP(locker)); 1338 if (value_sp) { 1339 DataExtractorSP data_sp(new DataExtractor()); 1340 Status error; 1341 value_sp->GetData(*data_sp, error); 1342 if (error.Success()) 1343 *sb_data = data_sp; 1344 } 1345 1346 return sb_data; 1347 } 1348 1349 bool SBValue::SetData(lldb::SBData &data, SBError &error) { 1350 LLDB_INSTRUMENT_VA(this, data, error); 1351 1352 ValueLocker locker; 1353 lldb::ValueObjectSP value_sp(GetSP(locker)); 1354 bool ret = true; 1355 1356 if (value_sp) { 1357 DataExtractor *data_extractor = data.get(); 1358 1359 if (!data_extractor) { 1360 error.SetErrorString("No data to set"); 1361 ret = false; 1362 } else { 1363 Status set_error; 1364 1365 value_sp->SetData(*data_extractor, set_error); 1366 1367 if (!set_error.Success()) { 1368 error.SetErrorStringWithFormat("Couldn't set data: %s", 1369 set_error.AsCString()); 1370 ret = false; 1371 } 1372 } 1373 } else { 1374 error.SetErrorStringWithFormat( 1375 "Couldn't set data: could not get SBValue: %s", 1376 locker.GetError().AsCString()); 1377 ret = false; 1378 } 1379 1380 return ret; 1381 } 1382 1383 lldb::SBValue SBValue::Clone(const char *new_name) { 1384 LLDB_INSTRUMENT_VA(this, new_name); 1385 1386 ValueLocker locker; 1387 lldb::ValueObjectSP value_sp(GetSP(locker)); 1388 1389 if (value_sp) 1390 return lldb::SBValue(value_sp->Clone(ConstString(new_name))); 1391 else 1392 return lldb::SBValue(); 1393 } 1394 1395 lldb::SBDeclaration SBValue::GetDeclaration() { 1396 LLDB_INSTRUMENT_VA(this); 1397 1398 ValueLocker locker; 1399 lldb::ValueObjectSP value_sp(GetSP(locker)); 1400 SBDeclaration decl_sb; 1401 if (value_sp) { 1402 Declaration decl; 1403 if (value_sp->GetDeclaration(decl)) 1404 decl_sb.SetDeclaration(decl); 1405 } 1406 return decl_sb; 1407 } 1408 1409 lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, bool write, 1410 SBError &error) { 1411 LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error); 1412 1413 SBWatchpoint sb_watchpoint; 1414 1415 // If the SBValue is not valid, there's no point in even trying to watch it. 1416 ValueLocker locker; 1417 lldb::ValueObjectSP value_sp(GetSP(locker)); 1418 TargetSP target_sp(GetTarget().GetSP()); 1419 if (value_sp && target_sp) { 1420 // Read and Write cannot both be false. 1421 if (!read && !write) 1422 return sb_watchpoint; 1423 1424 // If the value is not in scope, don't try and watch and invalid value 1425 if (!IsInScope()) 1426 return sb_watchpoint; 1427 1428 addr_t addr = GetLoadAddress(); 1429 if (addr == LLDB_INVALID_ADDRESS) 1430 return sb_watchpoint; 1431 size_t byte_size = GetByteSize(); 1432 if (byte_size == 0) 1433 return sb_watchpoint; 1434 1435 uint32_t watch_type = 0; 1436 if (read) { 1437 watch_type |= LLDB_WATCH_TYPE_READ; 1438 // read + write, the most likely intention 1439 // is to catch all writes to this, not just 1440 // value modifications. 1441 if (write) 1442 watch_type |= LLDB_WATCH_TYPE_WRITE; 1443 } else { 1444 if (write) 1445 watch_type |= LLDB_WATCH_TYPE_MODIFY; 1446 } 1447 1448 Status rc; 1449 CompilerType type(value_sp->GetCompilerType()); 1450 WatchpointSP watchpoint_sp = 1451 target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc); 1452 error.SetError(rc); 1453 1454 if (watchpoint_sp) { 1455 sb_watchpoint.SetSP(watchpoint_sp); 1456 Declaration decl; 1457 if (value_sp->GetDeclaration(decl)) { 1458 if (decl.GetFile()) { 1459 StreamString ss; 1460 // True to show fullpath for declaration file. 1461 decl.DumpStopContext(&ss, true); 1462 watchpoint_sp->SetDeclInfo(std::string(ss.GetString())); 1463 } 1464 } 1465 } 1466 } else if (target_sp) { 1467 error.SetErrorStringWithFormat("could not get SBValue: %s", 1468 locker.GetError().AsCString()); 1469 } else { 1470 error.SetErrorString("could not set watchpoint, a target is required"); 1471 } 1472 1473 return sb_watchpoint; 1474 } 1475 1476 // FIXME: Remove this method impl (as well as the decl in .h) once it is no 1477 // longer needed. 1478 // Backward compatibility fix in the interim. 1479 lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, 1480 bool write) { 1481 LLDB_INSTRUMENT_VA(this, resolve_location, read, write); 1482 1483 SBError error; 1484 return Watch(resolve_location, read, write, error); 1485 } 1486 1487 lldb::SBWatchpoint SBValue::WatchPointee(bool resolve_location, bool read, 1488 bool write, SBError &error) { 1489 LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error); 1490 1491 SBWatchpoint sb_watchpoint; 1492 if (IsInScope() && GetType().IsPointerType()) 1493 sb_watchpoint = Dereference().Watch(resolve_location, read, write, error); 1494 return sb_watchpoint; 1495 } 1496 1497 lldb::SBValue SBValue::Persist() { 1498 LLDB_INSTRUMENT_VA(this); 1499 1500 ValueLocker locker; 1501 lldb::ValueObjectSP value_sp(GetSP(locker)); 1502 SBValue persisted_sb; 1503 if (value_sp) { 1504 persisted_sb.SetSP(value_sp->Persist()); 1505 } 1506 return persisted_sb; 1507 } 1508 1509 lldb::SBValue SBValue::GetVTable() { 1510 SBValue vtable_sb; 1511 ValueLocker locker; 1512 lldb::ValueObjectSP value_sp(GetSP(locker)); 1513 if (!value_sp) 1514 return vtable_sb; 1515 1516 vtable_sb.SetSP(value_sp->GetVTable()); 1517 return vtable_sb; 1518 } 1519