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