diff --git a/lldb/bindings/interface/SBStructuredDataExtensions.i b/lldb/bindings/interface/SBStructuredDataExtensions.i new file mode 100644 --- /dev/null +++ b/lldb/bindings/interface/SBStructuredDataExtensions.i @@ -0,0 +1,6 @@ +%extend lldb::SBStructuredData { +#ifdef SWIGPYTHON + %template(GetIntegerValue) GetIntegerValue; + %template(GetIntegerValue) GetIntegerValue; +#endif +} diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig --- a/lldb/bindings/interfaces.swig +++ b/lldb/bindings/interfaces.swig @@ -179,6 +179,7 @@ %include "./interface/SBSectionExtensions.i" %include "./interface/SBStreamExtensions.i" %include "./interface/SBStringListExtensions.i" +%include "./interface/SBStructuredDataExtensions.i" %include "./interface/SBSymbolExtensions.i" %include "./interface/SBSymbolContextExtensions.i" %include "./interface/SBSymbolContextListExtensions.i" diff --git a/lldb/include/lldb/API/SBStructuredData.h b/lldb/include/lldb/API/SBStructuredData.h --- a/lldb/include/lldb/API/SBStructuredData.h +++ b/lldb/include/lldb/API/SBStructuredData.h @@ -9,6 +9,8 @@ #ifndef LLDB_API_SBSTRUCTUREDDATA_H #define LLDB_API_SBSTRUCTUREDDATA_H +#include "lldb/Core/StructuredDataImpl.h" + #include "lldb/API/SBDefines.h" #include "lldb/API/SBModule.h" @@ -54,7 +56,7 @@ /// 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. @@ -65,7 +67,14 @@ lldb::SBStructuredData GetItemAtIndex(size_t idx) const; /// Return the integer value if this data structure is an integer type. - uint64_t GetIntegerValue(uint64_t fail_value = 0) const; + template T GetIntegerValue(T fail_value = {}) const { + if constexpr (!std::is_integral_v) + return fail_value; + + return m_impl_up->GetType() == eStructuredDataTypeSignedInteger + ? m_impl_up->GetIntegerValue(static_cast(fail_value)) + : m_impl_up->GetIntegerValue(static_cast(fail_value)); + } /// Return the floating point value if this data structure is a floating /// type. diff --git a/lldb/include/lldb/Core/StructuredDataImpl.h b/lldb/include/lldb/Core/StructuredDataImpl.h --- a/lldb/include/lldb/Core/StructuredDataImpl.h +++ b/lldb/include/lldb/Core/StructuredDataImpl.h @@ -129,7 +129,13 @@ } 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 { diff --git a/lldb/include/lldb/Utility/StructuredData.h b/lldb/include/lldb/Utility/StructuredData.h --- a/lldb/include/lldb/Utility/StructuredData.h +++ b/lldb/include/lldb/Utility/StructuredData.h @@ -48,10 +48,13 @@ /// that may be present. class StructuredData { + template class Integer; + public: class Object; class Array; - class Integer; + using UnsignedInteger = Integer; + using SignedInteger = Integer; class Float; class Boolean; class String; @@ -60,7 +63,8 @@ typedef std::shared_ptr ObjectSP; typedef std::shared_ptr ArraySP; - typedef std::shared_ptr IntegerSP; + typedef std::shared_ptr UnsignedIntegerSP; + typedef std::shared_ptr SignedIntegerSP; typedef std::shared_ptr FloatSP; typedef std::shared_ptr BooleanSP; typedef std::shared_ptr StringSP; @@ -94,14 +98,26 @@ : nullptr); } - Integer *GetAsInteger() { - return ((m_type == lldb::eStructuredDataTypeInteger) - ? static_cast(this) + UnsignedInteger *GetAsUnsignedInteger() { + return ((m_type == lldb::eStructuredDataTypeInteger || + m_type == lldb::eStructuredDataTypeUnsignedInteger) + ? static_cast(this) + : nullptr); + } + + SignedInteger *GetAsSignedInteger() { + return ((m_type == lldb::eStructuredDataTypeSignedInteger) + ? static_cast(this) : nullptr); } - uint64_t GetIntegerValue(uint64_t fail_value = 0) { - Integer *integer = GetAsInteger(); + 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 +218,16 @@ 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(int_value->GetValue()); - return true; + if constexpr (std::numeric_limits::is_signed) { + if (auto signed_value = value_sp->GetAsSignedInteger()) { + result = static_cast(signed_value->GetValue()); + return true; + } + } else { + if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) { + result = static_cast(unsigned_value->GetValue()); + return true; + } } } return false; @@ -281,6 +304,25 @@ void AddItem(const ObjectSP &item) { m_items.push_back(item); } + template void AddIntegerItem(T value) { + static_assert(std::is_integral::value, + "value type should be integral"); + if constexpr (std::numeric_limits::is_signed) + AddItem(std::make_shared(value)); + else + AddItem(std::make_shared(value)); + } + + void AddFloatItem(double value) { AddItem(std::make_shared(value)); } + + void AddStringItem(llvm::StringRef value) { + AddItem(std::make_shared(std::move(value))); + } + + void AddBooleanItem(bool value) { + AddItem(std::make_shared(value)); + } + void Serialize(llvm::json::OStream &s) const override; void GetDescription(lldb_private::Stream &s) const override; @@ -290,25 +332,36 @@ collection m_items; }; - class Integer : public Object { - public: - Integer(uint64_t i = 0) - : Object(lldb::eStructuredDataTypeInteger), m_value(i) {} +private: + template class Integer : public Object { + static_assert(std::is_integral::value, "N must be an integral type"); + public: + Integer(N i = 0) + : Object(std::numeric_limits::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(m_value)); + } - void GetDescription(lldb_private::Stream &s) const override; + void GetDescription(lldb_private::Stream &s) const override { + s.Printf(std::numeric_limits::is_signed ? "%" PRId64 : "%" PRIu64, + static_cast(m_value)); + } protected: - uint64_t m_value; + N m_value; }; +public: class Float : public Object { public: Float(double d = 0.0) @@ -429,9 +482,16 @@ 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(int_value->GetValue()); - return true; + if constexpr (std::numeric_limits::is_signed) { + if (auto signed_value = value_sp->GetAsSignedInteger()) { + result = static_cast(signed_value->GetValue()); + return true; + } + } else { + if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) { + result = static_cast(unsigned_value->GetValue()); + return true; + } } } return false; @@ -522,8 +582,14 @@ m_dict[key_cs] = std::move(value_sp); } - void AddIntegerItem(llvm::StringRef key, uint64_t value) { - AddItem(key, std::make_shared(value)); + template void AddIntegerItem(llvm::StringRef key, T value) { + static_assert(std::is_integral::value || + std::is_floating_point::value, + "value type should be integral"); + if constexpr (std::numeric_limits::is_signed) + AddItem(key, std::make_shared(value)); + else + AddItem(key, std::make_shared(value)); } void AddFloatItem(llvm::StringRef key, double value) { diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -813,6 +813,8 @@ eStructuredDataTypeGeneric, eStructuredDataTypeArray, eStructuredDataTypeInteger, + eStructuredDataTypeUnsignedInteger = eStructuredDataTypeInteger, + eStructuredDataTypeSignedInteger, eStructuredDataTypeFloat, eStructuredDataTypeBoolean, eStructuredDataTypeString, diff --git a/lldb/source/API/SBStructuredData.cpp b/lldb/source/API/SBStructuredData.cpp --- a/lldb/source/API/SBStructuredData.cpp +++ b/lldb/source/API/SBStructuredData.cpp @@ -11,7 +11,6 @@ #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" @@ -162,12 +161,6 @@ return result; } -uint64_t SBStructuredData::GetIntegerValue(uint64_t fail_value) const { - LLDB_INSTRUMENT_VA(this, fail_value); - - return m_impl_up->GetIntegerValue(fail_value); -} - double SBStructuredData::GetFloatValue(double fail_value) const { LLDB_INSTRUMENT_VA(this, fail_value); diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -463,7 +463,7 @@ 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) { diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp --- a/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -197,8 +197,8 @@ 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); diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp --- a/lldb/source/Core/FormatEntity.cpp +++ b/lldb/source/Core/FormatEntity.cpp @@ -1008,7 +1008,7 @@ 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()); diff --git a/lldb/source/Host/common/XML.cpp b/lldb/source/Host/common/XML.cpp --- a/lldb/source/Host/common/XML.cpp +++ b/lldb/source/Host/common/XML.cpp @@ -490,7 +490,7 @@ } 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; diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -382,9 +382,9 @@ } // clang-format on image_infos[i].address = - image->GetValueForKey("load_address")->GetAsInteger()->GetValue(); + image->GetValueForKey("load_address")->GetUnsignedIntegerValue(); image_infos[i].mod_date = - image->GetValueForKey("mod_date")->GetAsInteger()->GetValue(); + image->GetValueForKey("mod_date")->GetUnsignedIntegerValue(); image_infos[i].file_spec.SetFile( image->GetValueForKey("pathname")->GetAsString()->GetValue(), FileSpec::Style::native); @@ -392,13 +392,13 @@ 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 = @@ -441,19 +441,19 @@ 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; @@ -466,35 +466,32 @@ 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; diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp @@ -570,7 +570,7 @@ 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()) diff --git a/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp b/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp --- a/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp @@ -132,7 +132,7 @@ 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 @@ std::vector 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 @@ 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. diff --git a/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp b/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp --- a/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp @@ -217,7 +217,7 @@ trace_value_object->GetChildAtIndex(j, true)->GetValueAsUnsigned(0); if (trace_addr == 0) break; - trace_sp->AddItem(std::make_shared(trace_addr)); + trace_sp->AddIntegerItem(trace_addr); } return trace_sp; } @@ -668,13 +668,11 @@ } 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 @@ } 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ ->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 @@ std::vector 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 @@ 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(*process_sp, tid, pcs); diff --git a/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp b/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp --- a/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp @@ -154,7 +154,7 @@ 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 @@ std::vector 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 @@ 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. diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -2370,7 +2370,7 @@ if (!value) return LLDB_INVALID_ADDRESS; - return value->GetIntegerValue(LLDB_INVALID_ADDRESS); + return value->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS); } void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() { diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2635,7 +2635,7 @@ 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 = diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -343,7 +343,7 @@ 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(); } @@ -1968,23 +1968,24 @@ 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()); @@ -1998,11 +1999,11 @@ 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) { @@ -2063,7 +2064,7 @@ } } 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 }); @@ -3812,10 +3813,8 @@ 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); diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -280,7 +280,7 @@ 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; }; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -479,7 +479,7 @@ void SetInteger(int64_t value); - StructuredData::IntegerSP CreateStructuredInteger() const; + StructuredData::UnsignedIntegerSP CreateStructuredInteger() const; }; class PythonBoolean : public TypedPythonObject { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -458,11 +458,16 @@ *this = Take(PyLong_FromLongLong(value)); } -StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const { - StructuredData::IntegerSP result(new StructuredData::Integer); - // FIXME this is really not ideal. Errors are silently converted to 0 +StructuredData::UnsignedIntegerSP +PythonInteger::CreateStructuredInteger() const { + StructuredData::UnsignedIntegerSP result( + new StructuredData::UnsignedInteger()); + // 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. + + // FIXME: Now that StructuredData support signed interger, we should convert + // python integer properly, handling negative integers. llvm::Expected value = AsModuloUnsignedLongLong(); if (!value) { llvm::consumeError(value.takeError()); diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp @@ -152,7 +152,7 @@ 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 @@ 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() { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp @@ -69,7 +69,7 @@ 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 ScriptedThreadPythonInterface::GetName() { @@ -89,7 +89,7 @@ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return eStateInvalid; - return static_cast(obj->GetIntegerValue(eStateInvalid)); + return static_cast(obj->GetUnsignedIntegerValue(eStateInvalid)); } std::optional ScriptedThreadPythonInterface::GetQueue() { diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -1807,7 +1807,7 @@ id->GetType() == eStructuredDataTypeInteger) { strm.Format(" Activity '{0}', {1:x}\n", name->GetAsString()->GetValue(), - id->GetAsInteger()->GetValue()); + id->GetUnsignedIntegerValue()); } printed_activity = true; } diff --git a/lldb/source/Utility/StructuredData.cpp b/lldb/source/Utility/StructuredData.cpp --- a/lldb/source/Utility/StructuredData.cpp +++ b/lldb/source/Utility/StructuredData.cpp @@ -68,10 +68,10 @@ return std::make_shared(*b); if (auto u = value.getAsUINT64()) - return std::make_shared(*u); + return std::make_shared(*u); if (auto i = value.getAsInteger()) - return std::make_shared(*i); + return std::make_shared(*i); if (auto d = value.getAsNumber()) return std::make_shared(*d); @@ -149,10 +149,6 @@ s.arrayEnd(); } -void StructuredData::Integer::Serialize(json::OStream &s) const { - s.value(static_cast(m_value)); -} - void StructuredData::Float::Serialize(json::OStream &s) const { s.value(m_value); } @@ -183,10 +179,6 @@ s.value(llvm::formatv("{0:X}", m_object)); } -void StructuredData::Integer::GetDescription(lldb_private::Stream &s) const { - s.Printf("%" PRId64, static_cast(m_value)); -} - void StructuredData::Float::GetDescription(lldb_private::Stream &s) const { s.Printf("%f", m_value); } diff --git a/lldb/tools/lldb-vscode/JSONUtils.cpp b/lldb/tools/lldb-vscode/JSONUtils.cpp --- a/lldb/tools/lldb-vscode/JSONUtils.cpp +++ b/lldb/tools/lldb-vscode/JSONUtils.cpp @@ -1162,7 +1162,11 @@ 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;