[lldb] Add support for negative integer to {SB,}StructuredData

This patch refactors the `StructuredData::Integer` class to make it
templated, makes it private and adds 2 public specialization for both
`int64_t` & `uint64_t` with a public type aliases, respectively
`SignedInteger` & `UnsignedInteger`.

It adds new getter for signed and unsigned interger values to the
`StructuredData::Object` base class and changes the implementation of
`StructuredData::Array::GetItemAtIndexAsInteger` and
`StructuredData::Dictionary::GetValueForKeyAsInteger` to support signed
and unsigned integers.

This patch also adds 2 new `Get{Signed,Unsigned}IntegerValue` to the
`SBStructuredData` class and marks `GetIntegerValue` as deprecated.

Finally, this patch audits all the caller of `StructuredData::Integer`
or `StructuredData::GetIntegerValue` to use the proper type as well the
various tests that uses `SBStructuredData.GetIntegerValue`.

rdar://105575764

Differential Revision: https://reviews.llvm.org/D150485

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
This commit is contained in:
Med Ismail Bennani
2023-05-22 13:52:09 -07:00
parent 01c5ec3d62
commit 1370a1cb5b
37 changed files with 365 additions and 185 deletions

View File

@@ -57,7 +57,7 @@ public:
/// Fill keys with the keys in this object and return true if this data
/// structure is a dictionary. Returns false otherwise.
bool GetKeys(lldb::SBStringList &keys) const;
bool GetKeys(lldb::SBStringList &keys) const;
/// Return the value corresponding to a key if this data structure
/// is a dictionary type.
@@ -68,6 +68,12 @@ public:
lldb::SBStructuredData GetItemAtIndex(size_t idx) const;
/// Return the integer value if this data structure is an integer type.
uint64_t GetUnsignedIntegerValue(uint64_t fail_value = 0) const;
/// Return the integer value if this data structure is an integer type.
int64_t GetSignedIntegerValue(int64_t fail_value = 0) const;
LLDB_DEPRECATED("Specify if the value is signed or unsigned",
"uint64_t GetUnsignedIntegerValue(uint64_t fail_value = 0)")
uint64_t GetIntegerValue(uint64_t fail_value = 0) const;
/// Return the floating point value if this data structure is a floating

View File

@@ -129,7 +129,13 @@ public:
}
uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
return (m_data_sp ? m_data_sp->GetIntegerValue(fail_value) : fail_value);
return (m_data_sp ? m_data_sp->GetUnsignedIntegerValue(fail_value)
: fail_value);
}
int64_t GetIntegerValue(int64_t fail_value = 0) const {
return (m_data_sp ? m_data_sp->GetSignedIntegerValue(fail_value)
: fail_value);
}
double GetFloatValue(double fail_value = 0.0) const {

View File

@@ -26,6 +26,7 @@
#include <string>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>
namespace lldb_private {
@@ -48,10 +49,13 @@ namespace lldb_private {
/// that may be present.
class StructuredData {
template <typename N> class Integer;
public:
class Object;
class Array;
class Integer;
using UnsignedInteger = Integer<uint64_t>;
using SignedInteger = Integer<int64_t>;
class Float;
class Boolean;
class String;
@@ -60,13 +64,16 @@ public:
typedef std::shared_ptr<Object> ObjectSP;
typedef std::shared_ptr<Array> ArraySP;
typedef std::shared_ptr<Integer> IntegerSP;
typedef std::shared_ptr<UnsignedInteger> UnsignedIntegerSP;
typedef std::shared_ptr<SignedInteger> SignedIntegerSP;
typedef std::shared_ptr<Float> FloatSP;
typedef std::shared_ptr<Boolean> BooleanSP;
typedef std::shared_ptr<String> StringSP;
typedef std::shared_ptr<Dictionary> DictionarySP;
typedef std::shared_ptr<Generic> GenericSP;
typedef std::variant<UnsignedIntegerSP, SignedIntegerSP> IntegerSP;
class Object : public std::enable_shared_from_this<Object> {
public:
Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid)
@@ -94,14 +101,28 @@ public:
: nullptr);
}
Integer *GetAsInteger() {
return ((m_type == lldb::eStructuredDataTypeInteger)
? static_cast<Integer *>(this)
UnsignedInteger *GetAsUnsignedInteger() {
// NOTE: For backward compatibility, eStructuredDataTypeInteger is
// the same as eStructuredDataTypeUnsignedInteger.
return ((m_type == lldb::eStructuredDataTypeInteger ||
m_type == lldb::eStructuredDataTypeUnsignedInteger)
? static_cast<UnsignedInteger *>(this)
: nullptr);
}
uint64_t GetIntegerValue(uint64_t fail_value = 0) {
Integer *integer = GetAsInteger();
SignedInteger *GetAsSignedInteger() {
return ((m_type == lldb::eStructuredDataTypeSignedInteger)
? static_cast<SignedInteger *>(this)
: nullptr);
}
uint64_t GetUnsignedIntegerValue(uint64_t fail_value = 0) {
UnsignedInteger *integer = GetAsUnsignedInteger();
return ((integer != nullptr) ? integer->GetValue() : fail_value);
}
int64_t GetSignedIntegerValue(int64_t fail_value = 0) {
SignedInteger *integer = GetAsSignedInteger();
return ((integer != nullptr) ? integer->GetValue() : fail_value);
}
@@ -202,9 +223,16 @@ public:
bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const {
ObjectSP value_sp = GetItemAtIndex(idx);
if (value_sp.get()) {
if (auto int_value = value_sp->GetAsInteger()) {
result = static_cast<IntType>(int_value->GetValue());
return true;
if constexpr (std::numeric_limits<IntType>::is_signed) {
if (auto signed_value = value_sp->GetAsSignedInteger()) {
result = static_cast<IntType>(signed_value->GetValue());
return true;
}
} else {
if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
result = static_cast<IntType>(unsigned_value->GetValue());
return true;
}
}
}
return false;
@@ -281,6 +309,26 @@ public:
void AddItem(const ObjectSP &item) { m_items.push_back(item); }
template <typename T> void AddIntegerItem(T value) {
static_assert(std::is_integral<T>::value ||
std::is_floating_point<T>::value,
"value type should be integral");
if constexpr (std::numeric_limits<T>::is_signed)
AddItem(std::make_shared<SignedInteger>(value));
else
AddItem(std::make_shared<UnsignedInteger>(value));
}
void AddFloatItem(double value) { AddItem(std::make_shared<Float>(value)); }
void AddStringItem(llvm::StringRef value) {
AddItem(std::make_shared<String>(std::move(value)));
}
void AddBooleanItem(bool value) {
AddItem(std::make_shared<Boolean>(value));
}
void Serialize(llvm::json::OStream &s) const override;
void GetDescription(lldb_private::Stream &s) const override;
@@ -290,25 +338,36 @@ public:
collection m_items;
};
class Integer : public Object {
public:
Integer(uint64_t i = 0)
: Object(lldb::eStructuredDataTypeInteger), m_value(i) {}
private:
template <typename N> class Integer : public Object {
static_assert(std::is_integral<N>::value, "N must be an integral type");
public:
Integer(N i = 0)
: Object(std::numeric_limits<N>::is_signed
? lldb::eStructuredDataTypeSignedInteger
: lldb::eStructuredDataTypeUnsignedInteger),
m_value(i) {}
~Integer() override = default;
void SetValue(uint64_t value) { m_value = value; }
void SetValue(N value) { m_value = value; }
uint64_t GetValue() { return m_value; }
N GetValue() { return m_value; }
void Serialize(llvm::json::OStream &s) const override;
void Serialize(llvm::json::OStream &s) const override {
s.value(static_cast<N>(m_value));
}
void GetDescription(lldb_private::Stream &s) const override;
void GetDescription(lldb_private::Stream &s) const override {
s.Printf(std::numeric_limits<N>::is_signed ? "%" PRId64 : "%" PRIu64,
static_cast<N>(m_value));
}
protected:
uint64_t m_value;
N m_value;
};
public:
class Float : public Object {
public:
Float(double d = 0.0)
@@ -429,9 +488,16 @@ public:
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
ObjectSP value_sp = GetValueForKey(key);
if (value_sp) {
if (auto int_value = value_sp->GetAsInteger()) {
result = static_cast<IntType>(int_value->GetValue());
return true;
if constexpr (std::numeric_limits<IntType>::is_signed) {
if (auto signed_value = value_sp->GetAsSignedInteger()) {
result = static_cast<IntType>(signed_value->GetValue());
return true;
}
} else {
if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
result = static_cast<IntType>(unsigned_value->GetValue());
return true;
}
}
}
return false;
@@ -522,8 +588,14 @@ public:
m_dict[key_cs] = std::move(value_sp);
}
void AddIntegerItem(llvm::StringRef key, uint64_t value) {
AddItem(key, std::make_shared<Integer>(value));
template <typename T> void AddIntegerItem(llvm::StringRef key, T value) {
static_assert(std::is_integral<T>::value ||
std::is_floating_point<T>::value,
"value type should be integral");
if constexpr (std::numeric_limits<T>::is_signed)
AddItem(key, std::make_shared<SignedInteger>(value));
else
AddItem(key, std::make_shared<UnsignedInteger>(value));
}
void AddFloatItem(llvm::StringRef key, double value) {

View File

@@ -819,7 +819,9 @@ enum StructuredDataType {
eStructuredDataTypeFloat,
eStructuredDataTypeBoolean,
eStructuredDataTypeString,
eStructuredDataTypeDictionary
eStructuredDataTypeDictionary,
eStructuredDataTypeSignedInteger,
eStructuredDataTypeUnsignedInteger = eStructuredDataTypeInteger,
};
FLAGS_ENUM(TypeClass){

View File

@@ -7,11 +7,11 @@
//===----------------------------------------------------------------------===//
#include "lldb/API/SBStructuredData.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Utility/Instrumentation.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStringList.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Target/StructuredDataPlugin.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/Status.h"
@@ -165,6 +165,18 @@ lldb::SBStructuredData SBStructuredData::GetItemAtIndex(size_t idx) const {
uint64_t SBStructuredData::GetIntegerValue(uint64_t fail_value) const {
LLDB_INSTRUMENT_VA(this, fail_value);
return GetUnsignedIntegerValue(fail_value);
}
uint64_t SBStructuredData::GetUnsignedIntegerValue(uint64_t fail_value) const {
LLDB_INSTRUMENT_VA(this, fail_value);
return m_impl_up->GetIntegerValue(fail_value);
}
int64_t SBStructuredData::GetSignedIntegerValue(int64_t fail_value) const {
LLDB_INSTRUMENT_VA(this, fail_value);
return m_impl_up->GetIntegerValue(fail_value);
}

View File

@@ -461,7 +461,7 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
success = true;
}
if (node->GetType() == eStructuredDataTypeInteger) {
strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
strm.Printf("0x%" PRIx64, node->GetUnsignedIntegerValue());
success = true;
}
if (node->GetType() == eStructuredDataTypeFloat) {

View File

@@ -230,7 +230,7 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData(
bool enabled = true;
bool one_shot = false;
bool auto_continue = false;
int32_t ignore_count = 0;
uint32_t ignore_count = 0;
llvm::StringRef condition_ref("");
Flags set_options;

View File

@@ -102,7 +102,7 @@ BreakpointResolverSP BreakpointResolver::CreateFromStructuredData(
return result_sp;
}
lldb::addr_t offset;
lldb::offset_t offset;
success = subclass_options->GetValueForKeyAsInteger(
GetKey(OptionNames::Offset), offset);
if (!success) {

View File

@@ -34,7 +34,7 @@ BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData(
const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict,
Status &error) {
llvm::StringRef module_name;
lldb::addr_t addr_offset;
lldb::offset_t addr_offset;
FileSpec module_filespec;
bool success;

View File

@@ -104,7 +104,7 @@ BreakpointResolver *BreakpointResolverName::CreateFromStructuredData(
}
}
lldb::addr_t offset = 0;
lldb::offset_t offset = 0;
success =
options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Offset), offset);
if (!success) {
@@ -197,8 +197,8 @@ StructuredData::ObjectSP BreakpointResolverName::SerializeToStructuredData() {
for (auto lookup : m_lookups) {
names_sp->AddItem(StructuredData::StringSP(
new StructuredData::String(lookup.GetName().GetStringRef())));
name_masks_sp->AddItem(StructuredData::IntegerSP(
new StructuredData::Integer(lookup.GetNameTypeMask())));
name_masks_sp->AddItem(StructuredData::UnsignedIntegerSP(
new StructuredData::UnsignedInteger(lookup.GetNameTypeMask())));
}
options_dict_sp->AddItem(GetKey(OptionNames::SymbolNameArray), names_sp);
options_dict_sp->AddItem(GetKey(OptionNames::NameMaskArray), name_masks_sp);

View File

@@ -1008,7 +1008,7 @@ static bool FormatThreadExtendedInfoRecurse(
const char *token_format = "0x%4.4" PRIx64;
if (!entry.printf_format.empty())
token_format = entry.printf_format.c_str();
s.Printf(token_format, value->GetAsInteger()->GetValue());
s.Printf(token_format, value->GetUnsignedIntegerValue());
return true;
} else if (value->GetType() == eStructuredDataTypeFloat) {
s.Printf("%f", value->GetAsFloat()->GetValue());

View File

@@ -490,7 +490,7 @@ static StructuredData::ObjectSP CreatePlistValue(XMLNode node) {
} else if (element_name == "integer") {
uint64_t value = 0;
node.GetElementTextAsUnsigned(value, 0, 0);
return StructuredData::ObjectSP(new StructuredData::Integer(value));
return StructuredData::ObjectSP(new StructuredData::UnsignedInteger(value));
} else if ((element_name == "string") || (element_name == "data") ||
(element_name == "date")) {
std::string text;

View File

@@ -102,8 +102,26 @@ Status OptionGroupPythonClassWithDict::SetOptionValue(
if (!m_dict_sp)
m_dict_sp = std::make_shared<StructuredData::Dictionary>();
if (!m_current_key.empty()) {
m_dict_sp->AddStringItem(m_current_key, option_arg);
m_current_key.clear();
if (!option_arg.empty()) {
double d = 0;
std::string opt = option_arg.lower();
if (llvm::to_integer(option_arg, d)) {
if (opt[0] == '-')
m_dict_sp->AddIntegerItem(m_current_key, static_cast<int64_t>(d));
else
m_dict_sp->AddIntegerItem(m_current_key,
static_cast<uint64_t>(d));
} else if (llvm::to_float(option_arg, d)) {
m_dict_sp->AddFloatItem(m_current_key, d);
} else if (opt == "true" || opt == "false") {
m_dict_sp->AddBooleanItem(m_current_key, opt == "true");
} else {
m_dict_sp->AddStringItem(m_current_key, option_arg);
}
}
m_current_key.clear();
}
else
error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.",

View File

@@ -381,7 +381,7 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
}
// clang-format on
image_infos[i].address =
image->GetValueForKey("load_address")->GetAsInteger()->GetValue();
image->GetValueForKey("load_address")->GetUnsignedIntegerValue();
image_infos[i].file_spec.SetFile(
image->GetValueForKey("pathname")->GetAsString()->GetValue(),
FileSpec::Style::native);
@@ -389,13 +389,13 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
StructuredData::Dictionary *mh =
image->GetValueForKey("mach_header")->GetAsDictionary();
image_infos[i].header.magic =
mh->GetValueForKey("magic")->GetAsInteger()->GetValue();
mh->GetValueForKey("magic")->GetUnsignedIntegerValue();
image_infos[i].header.cputype =
mh->GetValueForKey("cputype")->GetAsInteger()->GetValue();
mh->GetValueForKey("cputype")->GetUnsignedIntegerValue();
image_infos[i].header.cpusubtype =
mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue();
mh->GetValueForKey("cpusubtype")->GetUnsignedIntegerValue();
image_infos[i].header.filetype =
mh->GetValueForKey("filetype")->GetAsInteger()->GetValue();
mh->GetValueForKey("filetype")->GetUnsignedIntegerValue();
if (image->HasKey("min_version_os_name")) {
std::string os_name =
@@ -438,19 +438,19 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
if (mh->HasKey("flags"))
image_infos[i].header.flags =
mh->GetValueForKey("flags")->GetAsInteger()->GetValue();
mh->GetValueForKey("flags")->GetUnsignedIntegerValue();
else
image_infos[i].header.flags = 0;
if (mh->HasKey("ncmds"))
image_infos[i].header.ncmds =
mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue();
mh->GetValueForKey("ncmds")->GetUnsignedIntegerValue();
else
image_infos[i].header.ncmds = 0;
if (mh->HasKey("sizeofcmds"))
image_infos[i].header.sizeofcmds =
mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue();
mh->GetValueForKey("sizeofcmds")->GetUnsignedIntegerValue();
else
image_infos[i].header.sizeofcmds = 0;
@@ -463,35 +463,32 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
segments->GetItemAtIndex(j)->GetAsDictionary();
segment.name =
ConstString(seg->GetValueForKey("name")->GetAsString()->GetValue());
segment.vmaddr =
seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue();
segment.vmsize =
seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue();
segment.vmaddr = seg->GetValueForKey("vmaddr")->GetUnsignedIntegerValue();
segment.vmsize = seg->GetValueForKey("vmsize")->GetUnsignedIntegerValue();
segment.fileoff =
seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue();
seg->GetValueForKey("fileoff")->GetUnsignedIntegerValue();
segment.filesize =
seg->GetValueForKey("filesize")->GetAsInteger()->GetValue();
seg->GetValueForKey("filesize")->GetUnsignedIntegerValue();
segment.maxprot =
seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
seg->GetValueForKey("maxprot")->GetUnsignedIntegerValue();
// Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
// currently send them in the reply.
if (seg->HasKey("initprot"))
segment.initprot =
seg->GetValueForKey("initprot")->GetAsInteger()->GetValue();
seg->GetValueForKey("initprot")->GetUnsignedIntegerValue();
else
segment.initprot = 0;
if (seg->HasKey("flags"))
segment.flags =
seg->GetValueForKey("flags")->GetAsInteger()->GetValue();
segment.flags = seg->GetValueForKey("flags")->GetUnsignedIntegerValue();
else
segment.flags = 0;
if (seg->HasKey("nsects"))
segment.nsects =
seg->GetValueForKey("nsects")->GetAsInteger()->GetValue();
seg->GetValueForKey("nsects")->GetUnsignedIntegerValue();
else
segment.nsects = 0;

View File

@@ -570,7 +570,7 @@ bool DynamicLoaderMacOS::GetSharedCacheInformation(
info_dict->HasKey("no_shared_cache") &&
info_dict->HasKey("shared_cache_base_address")) {
base_address = info_dict->GetValueForKey("shared_cache_base_address")
->GetIntegerValue(LLDB_INVALID_ADDRESS);
->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS);
std::string uuid_str = std::string(
info_dict->GetValueForKey("shared_cache_uuid")->GetStringValue());
if (!uuid_str.empty())

View File

@@ -132,7 +132,7 @@ InstrumentationRuntimeMainThreadChecker::RetrieveReportData(
responsible_frame = frame;
lldb::addr_t PC = addr.GetLoadAddress(&target);
trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC)));
trace->AddIntegerItem(PC);
}
auto *d = new StructuredData::Dictionary();
@@ -252,7 +252,7 @@ InstrumentationRuntimeMainThreadChecker::GetBacktracesFromExtendedStopInfo(
std::vector<lldb::addr_t> PCs;
auto trace = info->GetObjectForDotSeparatedPath("trace")->GetAsArray();
trace->ForEach([&PCs](StructuredData::Object *PC) -> bool {
PCs.push_back(PC->GetAsInteger()->GetValue());
PCs.push_back(PC->GetUnsignedIntegerValue());
return true;
});
@@ -261,7 +261,7 @@ InstrumentationRuntimeMainThreadChecker::GetBacktracesFromExtendedStopInfo(
StructuredData::ObjectSP thread_id_obj =
info->GetObjectForDotSeparatedPath("tid");
tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
tid_t tid = thread_id_obj ? thread_id_obj->GetUnsignedIntegerValue() : 0;
// We gather symbolication addresses above, so no need for HistoryThread to
// try to infer the call addresses.

View File

@@ -217,7 +217,7 @@ CreateStackTrace(ValueObjectSP o,
trace_value_object->GetChildAtIndex(j, true)->GetValueAsUnsigned(0);
if (trace_addr == 0)
break;
trace_sp->AddItem(std::make_shared<StructuredData::Integer>(trace_addr));
trace_sp->AddIntegerItem(trace_addr);
}
return trace_sp;
}
@@ -668,13 +668,11 @@ InstrumentationRuntimeTSan::GenerateSummary(StructuredData::ObjectSP report) {
}
addr_t addr = loc->GetAsDictionary()
->GetValueForKey("address")
->GetAsInteger()
->GetValue();
->GetUnsignedIntegerValue();
if (addr == 0)
addr = loc->GetAsDictionary()
->GetValueForKey("start")
->GetAsInteger()
->GetValue();
->GetUnsignedIntegerValue();
if (addr != 0) {
std::string global_name = GetSymbolNameFromAddress(process_sp, addr);
@@ -686,8 +684,7 @@ InstrumentationRuntimeTSan::GenerateSummary(StructuredData::ObjectSP report) {
} else {
int fd = loc->GetAsDictionary()
->GetValueForKey("file_descriptor")
->GetAsInteger()
->GetValue();
->GetSignedIntegerValue();
if (fd != 0) {
summary = summary + " on file descriptor " + Sprintf("%d", fd);
}
@@ -703,8 +700,8 @@ addr_t InstrumentationRuntimeTSan::GetMainRacyAddress(
report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach(
[&result](StructuredData::Object *o) -> bool {
addr_t addr =
o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
addr_t addr = o->GetObjectForDotSeparatedPath("address")
->GetUnsignedIntegerValue();
if (addr < result)
result = addr;
return true;
@@ -733,8 +730,8 @@ std::string InstrumentationRuntimeTSan::GetLocationDescription(
if (type == "global") {
global_addr = loc->GetAsDictionary()
->GetValueForKey("address")
->GetAsInteger()
->GetValue();
->GetUnsignedIntegerValue();
global_name = GetSymbolNameFromAddress(process_sp, global_addr);
if (!global_name.empty()) {
result = Sprintf("'%s' is a global variable (0x%llx)",
@@ -752,12 +749,12 @@ std::string InstrumentationRuntimeTSan::GetLocationDescription(
} else if (type == "heap") {
addr_t addr = loc->GetAsDictionary()
->GetValueForKey("start")
->GetAsInteger()
->GetValue();
long size = loc->GetAsDictionary()
->GetValueForKey("size")
->GetAsInteger()
->GetValue();
->GetUnsignedIntegerValue();
size_t size = loc->GetAsDictionary()
->GetValueForKey("size")
->GetUnsignedIntegerValue();
std::string object_type = std::string(loc->GetAsDictionary()
->GetValueForKey("object_type")
->GetAsString()
@@ -770,22 +767,22 @@ std::string InstrumentationRuntimeTSan::GetLocationDescription(
Sprintf("Location is a %ld-byte heap object at 0x%llx", size, addr);
}
} else if (type == "stack") {
int tid = loc->GetAsDictionary()
->GetValueForKey("thread_id")
->GetAsInteger()
->GetValue();
tid_t tid = loc->GetAsDictionary()
->GetValueForKey("thread_id")
->GetUnsignedIntegerValue();
result = Sprintf("Location is stack of thread %d", tid);
} else if (type == "tls") {
int tid = loc->GetAsDictionary()
->GetValueForKey("thread_id")
->GetAsInteger()
->GetValue();
tid_t tid = loc->GetAsDictionary()
->GetValueForKey("thread_id")
->GetUnsignedIntegerValue();
result = Sprintf("Location is TLS of thread %d", tid);
} else if (type == "fd") {
int fd = loc->GetAsDictionary()
->GetValueForKey("file_descriptor")
->GetAsInteger()
->GetValue();
->GetSignedIntegerValue();
result = Sprintf("Location is file descriptor %d", fd);
}
}
@@ -848,8 +845,8 @@ bool InstrumentationRuntimeTSan::NotifyBreakpointHit(
report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach(
[&all_addresses_are_same,
main_address](StructuredData::Object *o) -> bool {
addr_t addr =
o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
addr_t addr = o->GetObjectForDotSeparatedPath("address")
->GetUnsignedIntegerValue();
if (main_address != addr)
all_addresses_are_same = false;
return true;
@@ -946,14 +943,16 @@ static std::string GenerateThreadName(const std::string &path,
std::string result = "additional information";
if (path == "mops") {
int size = o->GetObjectForDotSeparatedPath("size")->GetIntegerValue();
int thread_id =
o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
size_t size =
o->GetObjectForDotSeparatedPath("size")->GetUnsignedIntegerValue();
tid_t thread_id =
o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue();
bool is_write =
o->GetObjectForDotSeparatedPath("is_write")->GetBooleanValue();
bool is_atomic =
o->GetObjectForDotSeparatedPath("is_atomic")->GetBooleanValue();
addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
addr_t addr =
o->GetObjectForDotSeparatedPath("address")->GetUnsignedIntegerValue();
std::string addr_string = Sprintf(" at 0x%llx", addr);
@@ -970,44 +969,44 @@ static std::string GenerateThreadName(const std::string &path,
->GetStringValue() == "swift-access-race") {
result = Sprintf("modifying access by thread %d", thread_id);
} else {
result = Sprintf("%s%s of size %d%s by thread %d",
result = Sprintf("%s%s of size %zu%s by thread %" PRIu64,
is_atomic ? "atomic " : "", is_write ? "write" : "read",
size, addr_string.c_str(), thread_id);
}
}
if (path == "threads") {
int thread_id =
o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
result = Sprintf("Thread %d created", thread_id);
tid_t thread_id =
o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue();
result = Sprintf("Thread %zu created", thread_id);
}
if (path == "locs") {
std::string type = std::string(
o->GetAsDictionary()->GetValueForKey("type")->GetStringValue());
int thread_id =
o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
int fd =
o->GetObjectForDotSeparatedPath("file_descriptor")->GetIntegerValue();
tid_t thread_id =
o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue();
int fd = o->GetObjectForDotSeparatedPath("file_descriptor")
->GetSignedIntegerValue();
if (type == "heap") {
result = Sprintf("Heap block allocated by thread %d", thread_id);
result = Sprintf("Heap block allocated by thread %" PRIu64, thread_id);
} else if (type == "fd") {
result =
Sprintf("File descriptor %d created by thread %t", fd, thread_id);
result = Sprintf("File descriptor %d created by thread %" PRIu64, fd,
thread_id);
}
}
if (path == "mutexes") {
int mutex_id =
o->GetObjectForDotSeparatedPath("mutex_id")->GetIntegerValue();
o->GetObjectForDotSeparatedPath("mutex_id")->GetSignedIntegerValue();
result = Sprintf("Mutex M%d created", mutex_id);
}
if (path == "stacks") {
int thread_id =
o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
result = Sprintf("Thread %d", thread_id);
tid_t thread_id =
o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue();
result = Sprintf("Thread %" PRIu64, thread_id);
}
result[0] = toupper(result[0]);
@@ -1023,7 +1022,7 @@ static void AddThreadsForPath(const std::string &path,
std::vector<lldb::addr_t> pcs;
o->GetObjectForDotSeparatedPath("trace")->GetAsArray()->ForEach(
[&pcs](StructuredData::Object *pc) -> bool {
pcs.push_back(pc->GetAsInteger()->GetValue());
pcs.push_back(pc->GetUnsignedIntegerValue());
return true;
});
@@ -1032,7 +1031,8 @@ static void AddThreadsForPath(const std::string &path,
StructuredData::ObjectSP thread_id_obj =
o->GetObjectForDotSeparatedPath("thread_os_id");
tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
tid_t tid =
thread_id_obj ? thread_id_obj->GetUnsignedIntegerValue() : 0;
ThreadSP new_thread_sp =
std::make_shared<HistoryThread>(*process_sp, tid, pcs);

View File

@@ -154,7 +154,7 @@ StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData(
continue;
lldb::addr_t PC = FCA.GetLoadAddress(&target);
trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC)));
trace->AddIntegerItem(PC);
}
std::string IssueKind = RetrieveString(main_value, process_sp, ".issue_kind");
@@ -312,7 +312,7 @@ InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo(
std::vector<lldb::addr_t> PCs;
auto trace = info->GetObjectForDotSeparatedPath("trace")->GetAsArray();
trace->ForEach([&PCs](StructuredData::Object *PC) -> bool {
PCs.push_back(PC->GetAsInteger()->GetValue());
PCs.push_back(PC->GetUnsignedIntegerValue());
return true;
});
@@ -321,7 +321,7 @@ InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo(
StructuredData::ObjectSP thread_id_obj =
info->GetObjectForDotSeparatedPath("tid");
tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
tid_t tid = thread_id_obj ? thread_id_obj->GetUnsignedIntegerValue() : 0;
// We gather symbolication addresses above, so no need for HistoryThread to
// try to infer the call addresses.

View File

@@ -2370,7 +2370,7 @@ lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheBaseAddress() {
if (!value)
return LLDB_INVALID_ADDRESS;
return value->GetIntegerValue(LLDB_INVALID_ADDRESS);
return value->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS);
}
void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {

View File

@@ -721,7 +721,7 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
return false;
// Signal number and signal name are required.
int signo;
uint64_t signo;
if (!dict->GetValueForKeyAsInteger("signo", signo))
return false;

View File

@@ -2633,7 +2633,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer(
uint16_t port = 0;
if (StructuredData::ObjectSP port_osp =
element->GetValueForKey(llvm::StringRef("port")))
port = port_osp->GetIntegerValue(0);
port = port_osp->GetUnsignedIntegerValue(0);
std::string socket_name;
if (StructuredData::ObjectSP socket_name_osp =

View File

@@ -342,7 +342,7 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition(
target_definition_sp->GetValueForKey("breakpoint-pc-offset");
if (breakpoint_pc_offset_value) {
if (auto breakpoint_pc_int_value =
breakpoint_pc_offset_value->GetAsInteger())
breakpoint_pc_offset_value->GetAsSignedInteger())
m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();
}
@@ -1967,23 +1967,24 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
StructuredData::Object *object) -> bool {
if (key == g_key_tid) {
// thread in big endian hex
tid = object->GetIntegerValue(LLDB_INVALID_THREAD_ID);
tid = object->GetUnsignedIntegerValue(LLDB_INVALID_THREAD_ID);
} else if (key == g_key_metype) {
// exception type in big endian hex
exc_type = object->GetIntegerValue(0);
exc_type = object->GetUnsignedIntegerValue(0);
} else if (key == g_key_medata) {
// exception data in big endian hex
StructuredData::Array *array = object->GetAsArray();
if (array) {
array->ForEach([&exc_data](StructuredData::Object *object) -> bool {
exc_data.push_back(object->GetIntegerValue());
exc_data.push_back(object->GetUnsignedIntegerValue());
return true; // Keep iterating through all array items
});
}
} else if (key == g_key_name) {
thread_name = std::string(object->GetStringValue());
} else if (key == g_key_qaddr) {
thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS);
thread_dispatch_qaddr =
object->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS);
} else if (key == g_key_queue_name) {
queue_vars_valid = true;
queue_name = std::string(object->GetStringValue());
@@ -1997,11 +1998,11 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
queue_kind = eQueueKindConcurrent;
}
} else if (key == g_key_queue_serial_number) {
queue_serial_number = object->GetIntegerValue(0);
queue_serial_number = object->GetUnsignedIntegerValue(0);
if (queue_serial_number != 0)
queue_vars_valid = true;
} else if (key == g_key_dispatch_queue_t) {
dispatch_queue_t = object->GetIntegerValue(0);
dispatch_queue_t = object->GetUnsignedIntegerValue(0);
if (dispatch_queue_t != 0 && dispatch_queue_t != LLDB_INVALID_ADDRESS)
queue_vars_valid = true;
} else if (key == g_key_associated_with_dispatch_queue) {
@@ -2062,7 +2063,7 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
}
} else if (key == g_key_signal)
signo = object->GetIntegerValue(LLDB_INVALID_SIGNAL_NUMBER);
signo = object->GetUnsignedIntegerValue(LLDB_INVALID_SIGNAL_NUMBER);
return true; // Keep iterating through all dictionary key/value pairs
});
@@ -3818,10 +3819,8 @@ StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(
StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
StructuredData::ArraySP addresses(new StructuredData::Array);
for (auto addr : load_addresses) {
StructuredData::ObjectSP addr_sp(new StructuredData::Integer(addr));
addresses->AddItem(addr_sp);
}
for (auto addr : load_addresses)
addresses->AddIntegerItem(addr);
args_dict->GetAsDictionary()->AddItem("solib_addresses", addresses);

View File

@@ -457,7 +457,7 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() {
return error_with_message("Couldn't create or get module.");
lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
lldb::addr_t slide = LLDB_INVALID_OFFSET;
lldb::offset_t slide = LLDB_INVALID_OFFSET;
dict->GetValueForKeyAsInteger("load_addr", load_addr);
dict->GetValueForKeyAsInteger("slide", slide);
if (load_addr == LLDB_INVALID_ADDRESS)

View File

@@ -280,7 +280,7 @@ bool ScriptedThread::CalculateStopInfo() {
auto fetch_data = [&raw_codes](StructuredData::Object *obj) {
if (!obj)
return false;
raw_codes.push_back(obj->GetIntegerValue());
raw_codes.push_back(obj->GetUnsignedIntegerValue());
return true;
};

View File

@@ -25,6 +25,7 @@
#include "llvm/Support/Errno.h"
#include <cstdio>
#include <variant>
using namespace lldb_private;
using namespace lldb;
@@ -101,7 +102,7 @@ Expected<long long> PythonObject::AsLongLong() const {
return r;
}
Expected<long long> PythonObject::AsUnsignedLongLong() const {
Expected<unsigned long long> PythonObject::AsUnsignedLongLong() const {
if (!m_py_obj)
return nullDeref();
assert(!PyErr_Occurred());
@@ -117,6 +118,7 @@ Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const {
return nullDeref();
assert(!PyErr_Occurred());
unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj);
// FIXME: We should fetch the exception message and hoist it.
if (PyErr_Occurred())
return exception();
return r;
@@ -267,9 +269,15 @@ StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
case PyObjectType::Boolean:
return PythonBoolean(PyRefType::Borrowed, m_py_obj)
.CreateStructuredBoolean();
case PyObjectType::Integer:
return PythonInteger(PyRefType::Borrowed, m_py_obj)
.CreateStructuredInteger();
case PyObjectType::Integer: {
StructuredData::IntegerSP int_sp =
PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger();
if (std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp))
return std::get<StructuredData::UnsignedIntegerSP>(int_sp);
if (std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp))
return std::get<StructuredData::SignedIntegerSP>(int_sp);
return nullptr;
};
case PyObjectType::List:
return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
case PyObjectType::String:
@@ -459,17 +467,32 @@ void PythonInteger::SetInteger(int64_t value) {
}
StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
StructuredData::IntegerSP result(new StructuredData::Integer);
// FIXME this is really not ideal. Errors are silently converted to 0
// and overflows are silently wrapped. But we'd need larger changes
// to StructuredData to fix it, so that's how it is for now.
llvm::Expected<unsigned long long> value = AsModuloUnsignedLongLong();
if (!value) {
StructuredData::UnsignedIntegerSP uint_sp = CreateStructuredUnsignedInteger();
return uint_sp ? StructuredData::IntegerSP(uint_sp)
: CreateStructuredSignedInteger();
}
StructuredData::UnsignedIntegerSP
PythonInteger::CreateStructuredUnsignedInteger() const {
StructuredData::UnsignedIntegerSP result = nullptr;
llvm::Expected<unsigned long long> value = AsUnsignedLongLong();
if (!value)
llvm::consumeError(value.takeError());
result->SetValue(0);
} else {
result->SetValue(value.get());
}
else
result = std::make_shared<StructuredData::UnsignedInteger>(value.get());
return result;
}
StructuredData::SignedIntegerSP
PythonInteger::CreateStructuredSignedInteger() const {
StructuredData::SignedIntegerSP result = nullptr;
llvm::Expected<long long> value = AsLongLong();
if (!value)
llvm::consumeError(value.takeError());
else
result = std::make_shared<StructuredData::SignedInteger>(value.get());
return result;
}

View File

@@ -354,7 +354,7 @@ public:
llvm::Expected<long long> AsLongLong() const;
llvm::Expected<long long> AsUnsignedLongLong() const;
llvm::Expected<unsigned long long> AsUnsignedLongLong() const;
// wraps on overflow, instead of raising an error.
llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const;
@@ -480,6 +480,10 @@ public:
void SetInteger(int64_t value);
StructuredData::IntegerSP CreateStructuredInteger() const;
StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger() const;
StructuredData::SignedIntegerSP CreateStructuredSignedInteger() const;
};
class PythonBoolean : public TypedPythonObject<PythonBoolean> {

View File

@@ -152,7 +152,7 @@ lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress(
if (py_error.Fail())
error = py_error;
return obj->GetIntegerValue(LLDB_INVALID_OFFSET);
return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET);
}
StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
@@ -173,7 +173,7 @@ lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
return LLDB_INVALID_PROCESS_ID;
return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID);
return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID);
}
bool ScriptedProcessPythonInterface::IsAlive() {

View File

@@ -69,7 +69,7 @@ lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() {
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
return LLDB_INVALID_THREAD_ID;
return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID);
return obj->GetUnsignedIntegerValue(LLDB_INVALID_THREAD_ID);
}
std::optional<std::string> ScriptedThreadPythonInterface::GetName() {
@@ -89,7 +89,7 @@ lldb::StateType ScriptedThreadPythonInterface::GetState() {
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
return eStateInvalid;
return static_cast<StateType>(obj->GetIntegerValue(eStateInvalid));
return static_cast<StateType>(obj->GetUnsignedIntegerValue(eStateInvalid));
}
std::optional<std::string> ScriptedThreadPythonInterface::GetQueue() {

View File

@@ -262,7 +262,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
return 0;
}
int64_t bitsize = 0;
uint64_t bitsize = 0;
if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) {
Clear();
printf("error: invalid or missing 'bitsize' key/value pair in register "
@@ -296,7 +296,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
eEncodingUint);
size_t set = 0;
if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) ||
if (!reg_info_dict->GetValueForKeyAsInteger("set", set) ||
set >= m_sets.size()) {
Clear();
printf("error: invalid 'set' value in register dictionary, valid values "

View File

@@ -1806,7 +1806,7 @@ bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level,
id->GetType() == eStructuredDataTypeInteger) {
strm.Format(" Activity '{0}', {1:x}\n",
name->GetAsString()->GetValue(),
id->GetAsInteger()->GetValue());
id->GetUnsignedIntegerValue());
}
printed_activity = true;
}

View File

@@ -68,10 +68,10 @@ static StructuredData::ObjectSP ParseJSONValue(json::Value &value) {
return std::make_shared<StructuredData::Boolean>(*b);
if (auto u = value.getAsUINT64())
return std::make_shared<StructuredData::Integer>(*u);
return std::make_shared<StructuredData::UnsignedInteger>(*u);
if (auto i = value.getAsInteger())
return std::make_shared<StructuredData::Integer>(*i);
return std::make_shared<StructuredData::SignedInteger>(*i);
if (auto d = value.getAsNumber())
return std::make_shared<StructuredData::Float>(*d);
@@ -149,10 +149,6 @@ void StructuredData::Array::Serialize(json::OStream &s) const {
s.arrayEnd();
}
void StructuredData::Integer::Serialize(json::OStream &s) const {
s.value(static_cast<int64_t>(m_value));
}
void StructuredData::Float::Serialize(json::OStream &s) const {
s.value(m_value);
}
@@ -183,10 +179,6 @@ void StructuredData::Generic::Serialize(json::OStream &s) const {
s.value(llvm::formatv("{0:X}", m_object));
}
void StructuredData::Integer::GetDescription(lldb_private::Stream &s) const {
s.Printf("%" PRId64, static_cast<int64_t>(m_value));
}
void StructuredData::Float::GetDescription(lldb_private::Stream &s) const {
s.Printf("%f", m_value);
}

View File

@@ -17,8 +17,7 @@ class stop_handler:
increment = 1
value = self.extra_args.GetValueForKey("increment")
if value:
incr_as_str = value.GetStringValue(100)
increment = int(incr_as_str)
increment = value.GetUnsignedIntegerValue()
else:
stream.Print("Could not find increment in extra_args\n")
frame = exe_ctx.GetFrame()

View File

@@ -98,7 +98,7 @@ class StepReportsStopOthers():
def __init__(self, thread_plan, args_data, dict):
self.thread_plan = thread_plan
self.key = args_data.GetValueForKey("token").GetStringValue(1000)
self.key = str(args_data.GetValueForKey("token").GetUnsignedIntegerValue(1000))
def should_stop(self, event):
self.thread_plan.SetPlanComplete(True)

View File

@@ -22,12 +22,17 @@ class TestStructuredDataAPI(TestBase):
s = lldb.SBStream()
dict_str = json.dumps(
{"key_dict":
{"key_string":"STRING",
"key_uint":0xffffffff00000000,
"key_float":2.99,
"key_bool":True,
"key_array":["23","arr"]}})
{
"key_dict": {
"key_string": "STRING",
"key_uint": 0xFFFFFFFF00000000,
"key_sint": -42,
"key_float": 2.99,
"key_bool": True,
"key_array": ["23", "arr"],
}
}
)
s.Print(dict_str)
example = lldb.SBStructuredData()
@@ -46,7 +51,7 @@ class TestStructuredDataAPI(TestBase):
self.assertSuccess(error, "GetDescription works")
if not "key_float" in s.GetData():
self.fail("FAILED: could not find key_float in description output")
dict_struct = lldb.SBStructuredData()
dict_struct = example.GetValueForKey("key_dict")
@@ -59,6 +64,9 @@ class TestStructuredDataAPI(TestBase):
# Tests for integer data type
self.uint_struct_test(dict_struct)
# Tests for integer data type
self.sint_struct_test(dict_struct)
# Tests for floating point data type
self.double_struct_test(dict_struct)
@@ -90,7 +98,7 @@ class TestStructuredDataAPI(TestBase):
self.fail("Wrong type returned: " + str(dict_struct.GetType()))
# Check Size API for 'dictionary' type
if not dict_struct.GetSize() == 5:
if not dict_struct.GetSize() == 6:
self.fail("Wrong no of elements returned: " +
str(dict_struct.GetSize()))
@@ -131,14 +139,38 @@ class TestStructuredDataAPI(TestBase):
if not uint_struct.GetType() == lldb.eStructuredDataTypeInteger:
self.fail("Wrong type returned: " + str(uint_struct.GetType()))
# Check API returning 'integer' value
output = uint_struct.GetIntegerValue()
# Check API returning unsigned integer value
output = uint_struct.GetUnsignedIntegerValue()
if not output == 0xffffffff00000000:
self.fail("wrong output: " + str(output))
# Calling wrong API on a SBStructuredData
# (e.g. getting a string value from an integer type structure)
output = uint_struct.GetStringValue(25)
if output:
self.fail("Valid string " + output + " returned for an integer object")
def sint_struct_test(self, dict_struct):
# Check a valid SBStructuredData containing an signed integer.
# We intentionally make this smaller than what an uint64_t can hold but
# still small enough to fit a int64_t
sint_struct = lldb.SBStructuredData()
sint_struct = dict_struct.GetValueForKey("key_sint")
if not sint_struct.IsValid():
self.fail("A valid object should have been returned")
# Check Type API
if not sint_struct.GetType() == lldb.eStructuredDataTypeSignedInteger:
self.fail("Wrong type returned: " + str(sint_struct.GetType()))
# Check API returning signed integer value
output = sint_struct.GetSignedIntegerValue()
if not output == -42:
self.fail("wrong output: " + str(output))
# Calling wrong API on a SBStructuredData
# (e.g. getting a string value from an integer type structure)
output = sint_struct.GetStringValue(69)
if output:
self.fail(
"Valid string " +

View File

@@ -1161,8 +1161,11 @@ void FilterAndGetValueForKey(const lldb::SBStructuredData data, const char *key,
case lldb::eStructuredDataTypeFloat:
out.try_emplace(key_utf8, value.GetFloatValue());
break;
case lldb::eStructuredDataTypeInteger:
out.try_emplace(key_utf8, value.GetIntegerValue());
case lldb::eStructuredDataTypeUnsignedInteger:
out.try_emplace(key_utf8, value.GetIntegerValue((uint64_t)0));
break;
case lldb::eStructuredDataTypeSignedInteger:
out.try_emplace(key_utf8, value.GetIntegerValue((int64_t)0));
break;
case lldb::eStructuredDataTypeArray: {
lldb::SBStream contents;

View File

@@ -297,7 +297,7 @@ TEST_F(GDBRemoteCommunicationClientTest, TestPacketSpeedJSON) {
dict_sp = object_sp->GetAsDictionary();
ASSERT_TRUE(bool(dict_sp));
int num_packets;
size_t num_packets;
ASSERT_TRUE(dict_sp->GetValueForKeyAsInteger("num_packets", num_packets))
<< ss.GetString();
ASSERT_EQ(10, num_packets);

View File

@@ -19,6 +19,8 @@
#include "PythonTestSuite.h"
#include <variant>
using namespace lldb_private;
using namespace lldb_private::python;
using llvm::Error;
@@ -266,10 +268,23 @@ TEST_F(PythonDataObjectsTest, TestPythonStringToStr) {
TEST_F(PythonDataObjectsTest, TestPythonIntegerToStr) {}
TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredInteger) {
TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredUnsignedInteger) {
PythonInteger integer(7);
auto int_sp = integer.CreateStructuredInteger();
EXPECT_EQ(7U, int_sp->GetValue());
EXPECT_TRUE(
std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp));
StructuredData::UnsignedIntegerSP uint_sp =
std::get<StructuredData::UnsignedIntegerSP>(int_sp);
EXPECT_EQ(7U, uint_sp->GetValue());
}
TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredSignedInteger) {
PythonInteger integer(-42);
auto int_sp = integer.CreateStructuredInteger();
EXPECT_TRUE(std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp));
StructuredData::SignedIntegerSP sint_sp =
std::get<StructuredData::SignedIntegerSP>(int_sp);
EXPECT_EQ(-42, sint_sp->GetValue());
}
TEST_F(PythonDataObjectsTest, TestPythonStringToStructuredString) {
@@ -358,7 +373,7 @@ TEST_F(PythonDataObjectsTest, TestPythonListToStructuredList) {
EXPECT_EQ(lldb::eStructuredDataTypeString,
array_sp->GetItemAtIndex(1)->GetType());
auto int_sp = array_sp->GetItemAtIndex(0)->GetAsInteger();
auto int_sp = array_sp->GetItemAtIndex(0)->GetAsUnsignedInteger();
auto string_sp = array_sp->GetItemAtIndex(1)->GetAsString();
EXPECT_EQ(long_value0, long(int_sp->GetValue()));
@@ -522,7 +537,7 @@ TEST_F(PythonDataObjectsTest, TestPythonDictionaryToStructuredDictionary) {
EXPECT_TRUE(dict_sp->HasKey(string_key1));
auto string_sp = dict_sp->GetValueForKey(string_key0)->GetAsString();
auto int_sp = dict_sp->GetValueForKey(string_key1)->GetAsInteger();
auto int_sp = dict_sp->GetValueForKey(string_key1)->GetAsUnsignedInteger();
EXPECT_EQ(string_value0, string_sp->GetValue());
EXPECT_EQ(int_value1, long(int_sp->GetValue()));
@@ -592,7 +607,7 @@ TEST_F(PythonDataObjectsTest, TestExtractingUInt64ThroughStructuredData) {
structured_dict_ptr->GetValueForKey(key_name);
EXPECT_TRUE((bool)structured_addr_value_sp);
const uint64_t extracted_value =
structured_addr_value_sp->GetIntegerValue(123);
structured_addr_value_sp->GetUnsignedIntegerValue(123);
EXPECT_TRUE(extracted_value == value);
}
}