diff --git a/mozglue/baseprofiler/core/platform.cpp b/mozglue/baseprofiler/core/platform.cpp index 4a31d096e280..70c971367312 100644 --- a/mozglue/baseprofiler/core/platform.cpp +++ b/mozglue/baseprofiler/core/platform.cpp @@ -1768,6 +1768,7 @@ static void AddSharedLibraryInfoToStream(JSONWriter& aWriter, aWriter.StringProperty("debugName", aLib.GetDebugName()); aWriter.StringProperty("debugPath", aLib.GetDebugPath()); aWriter.StringProperty("breakpadId", aLib.GetBreakpadId()); + aWriter.StringProperty("codeId", aLib.GetCodeId()); aWriter.StringProperty("arch", aLib.GetArch()); aWriter.EndObject(); } diff --git a/mozglue/baseprofiler/core/shared-libraries-linux.cc b/mozglue/baseprofiler/core/shared-libraries-linux.cc index 0e54573e1cbb..500cd78235ab 100644 --- a/mozglue/baseprofiler/core/shared-libraries-linux.cc +++ b/mozglue/baseprofiler/core/shared-libraries-linux.cc @@ -678,8 +678,8 @@ static SharedLibrary SharedLibraryAtPath(const char* path, std::string nameStr = (pos != std::string::npos) ? pathStr.substr(pos + 1) : pathStr; - return SharedLibrary(libStart, libEnd, offset, getId(path), nameStr, pathStr, - nameStr, pathStr, std::string{}, ""); + return SharedLibrary(libStart, libEnd, offset, getId(path), std::string{}, + nameStr, pathStr, nameStr, pathStr, std::string{}, ""); } static int dl_iterate_callback(struct dl_phdr_info* dl_info, size_t size, diff --git a/mozglue/baseprofiler/core/shared-libraries-macos.cc b/mozglue/baseprofiler/core/shared-libraries-macos.cc index 8e2bacf84fce..7b2a0fa5bbce 100644 --- a/mozglue/baseprofiler/core/shared-libraries-macos.cc +++ b/mozglue/baseprofiler/core/shared-libraries-macos.cc @@ -163,9 +163,9 @@ static void addSharedLibrary(const platform_mach_header* header, const NXArchInfo* archInfo = NXGetArchInfoFromCpuType(header->cputype, header->cpusubtype); - info.AddSharedLibrary(SharedLibrary(start, start + size, 0, uuid, nameStr, - pathStr, nameStr, pathStr, std::string{}, - archInfo ? archInfo->name : "")); + info.AddSharedLibrary(SharedLibrary( + start, start + size, 0, uuid, std::string{}, nameStr, pathStr, nameStr, + pathStr, std::string{}, archInfo ? archInfo->name : "")); } // Translate the statically stored sSharedLibrariesList information into a diff --git a/mozglue/baseprofiler/core/shared-libraries-win32.cc b/mozglue/baseprofiler/core/shared-libraries-win32.cc index ab9d527528d7..4abafa8feadb 100644 --- a/mozglue/baseprofiler/core/shared-libraries-win32.cc +++ b/mozglue/baseprofiler/core/shared-libraries-win32.cc @@ -93,98 +93,98 @@ static bool IsModuleUnsafeToLoad(const std::string& aModuleName) { SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() { SharedLibraryInfo sharedLibraryInfo; - auto addSharedLibraryFromModuleInfo = - [&sharedLibraryInfo](const wchar_t* aModulePath, HMODULE aModule) { - mozilla::UniquePtr utf8ModulePath( - mozilla::glue::WideToUTF8(aModulePath)); - if (!utf8ModulePath) { - return; - } + auto addSharedLibraryFromModuleInfo = [&sharedLibraryInfo]( + const wchar_t* aModulePath, + HMODULE aModule) { + mozilla::UniquePtr utf8ModulePath( + mozilla::glue::WideToUTF8(aModulePath)); + if (!utf8ModulePath) { + return; + } - std::string modulePathStr(utf8ModulePath.get()); - size_t pos = modulePathStr.find_last_of("\\/"); - std::string moduleNameStr = (pos != std::string::npos) - ? modulePathStr.substr(pos + 1) - : modulePathStr; + std::string modulePathStr(utf8ModulePath.get()); + size_t pos = modulePathStr.find_last_of("\\/"); + std::string moduleNameStr = (pos != std::string::npos) + ? modulePathStr.substr(pos + 1) + : modulePathStr; - // If the module is unsafe to call LoadLibraryEx for, we skip. - if (IsModuleUnsafeToLoad(moduleNameStr)) { - return; - } + // If the module is unsafe to call LoadLibraryEx for, we skip. + if (IsModuleUnsafeToLoad(moduleNameStr)) { + return; + } - // Load the module again to make sure that its handle will remain - // valid as we attempt to read the PDB information from it. We load the - // DLL as a datafile so that we don't end up running the newly loaded - // module's DllMain function. If the original handle |aModule| is - // valid, LoadLibraryEx just increments its refcount. - // LOAD_LIBRARY_AS_IMAGE_RESOURCE is needed to read information from the - // sections (not PE headers) which should be relocated by the loader, - // otherwise GetPdbInfo() will cause a crash. - nsModuleHandle handleLock(::LoadLibraryExW( - aModulePath, NULL, - LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)); - if (!handleLock) { - return; - } + // Load the module again to make sure that its handle will remain + // valid as we attempt to read the PDB information from it. We load the + // DLL as a datafile so that we don't end up running the newly loaded + // module's DllMain function. If the original handle |aModule| is + // valid, LoadLibraryEx just increments its refcount. + // LOAD_LIBRARY_AS_IMAGE_RESOURCE is needed to read information from the + // sections (not PE headers) which should be relocated by the loader, + // otherwise GetPdbInfo() will cause a crash. + nsModuleHandle handleLock(::LoadLibraryExW( + aModulePath, NULL, + LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)); + if (!handleLock) { + return; + } - mozilla::nt::PEHeaders headers(handleLock.get()); - if (!headers) { - return; - } + mozilla::nt::PEHeaders headers(handleLock.get()); + if (!headers) { + return; + } - mozilla::Maybe> bounds = - headers.GetBounds(); - if (!bounds) { - return; - } + mozilla::Maybe> bounds = headers.GetBounds(); + if (!bounds) { + return; + } - // Put the original |aModule| into SharedLibrary, but we get debug info - // from |handleLock| as |aModule| might be inaccessible. - const uintptr_t modStart = reinterpret_cast(aModule); - const uintptr_t modEnd = modStart + bounds->length(); + // Put the original |aModule| into SharedLibrary, but we get debug info + // from |handleLock| as |aModule| might be inaccessible. + const uintptr_t modStart = reinterpret_cast(aModule); + const uintptr_t modEnd = modStart + bounds->length(); - std::string breakpadId; - std::string pdbPathStr; - std::string pdbNameStr; - if (const auto* debugInfo = headers.GetPdbInfo()) { - MOZ_ASSERT(breakpadId.empty()); - const GUID& pdbSig = debugInfo->pdbSignature; - AppendHex(pdbSig.Data1, breakpadId, WITH_PADDING); - AppendHex(pdbSig.Data2, breakpadId, WITH_PADDING); - AppendHex(pdbSig.Data3, breakpadId, WITH_PADDING); - AppendHex(reinterpret_cast(&pdbSig.Data4), - reinterpret_cast(&pdbSig.Data4) + - sizeof(pdbSig.Data4), - breakpadId); - AppendHex(debugInfo->pdbAge, breakpadId, WITHOUT_PADDING); + std::string breakpadId; + std::string pdbPathStr; + std::string pdbNameStr; + if (const auto* debugInfo = headers.GetPdbInfo()) { + MOZ_ASSERT(breakpadId.empty()); + const GUID& pdbSig = debugInfo->pdbSignature; + AppendHex(pdbSig.Data1, breakpadId, WITH_PADDING); + AppendHex(pdbSig.Data2, breakpadId, WITH_PADDING); + AppendHex(pdbSig.Data3, breakpadId, WITH_PADDING); + AppendHex(reinterpret_cast(&pdbSig.Data4), + reinterpret_cast(&pdbSig.Data4) + + sizeof(pdbSig.Data4), + breakpadId); + AppendHex(debugInfo->pdbAge, breakpadId, WITHOUT_PADDING); - // The PDB file name could be different from module filename, - // so report both - // e.g. The PDB for C:\Windows\SysWOW64\ntdll.dll is wntdll.pdb - pdbPathStr = debugInfo->pdbFileName; - size_t pos = pdbPathStr.find_last_of("\\/"); - pdbNameStr = (pos != std::string::npos) ? pdbPathStr.substr(pos + 1) - : pdbPathStr; - } + // The PDB file name could be different from module filename, + // so report both + // e.g. The PDB for C:\Windows\SysWOW64\ntdll.dll is wntdll.pdb + pdbPathStr = debugInfo->pdbFileName; + size_t pos = pdbPathStr.find_last_of("\\/"); + pdbNameStr = + (pos != std::string::npos) ? pdbPathStr.substr(pos + 1) : pdbPathStr; + } - std::string versionStr; - uint64_t version; - if (headers.GetVersionInfo(version)) { - versionStr += std::to_string((version >> 48) & 0xFFFF); - versionStr += '.'; - versionStr += std::to_string((version >> 32) & 0xFFFF); - versionStr += '.'; - versionStr += std::to_string((version >> 16) & 0xFFFF); - versionStr += '.'; - versionStr += std::to_string(version & 0xFFFF); - } + std::string versionStr; + uint64_t version; + if (headers.GetVersionInfo(version)) { + versionStr += std::to_string((version >> 48) & 0xFFFF); + versionStr += '.'; + versionStr += std::to_string((version >> 32) & 0xFFFF); + versionStr += '.'; + versionStr += std::to_string((version >> 16) & 0xFFFF); + versionStr += '.'; + versionStr += std::to_string(version & 0xFFFF); + } - SharedLibrary shlib(modStart, modEnd, - 0, // DLLs are always mapped at offset 0 on Windows - breakpadId, moduleNameStr, modulePathStr, - pdbNameStr, pdbPathStr, versionStr, ""); - sharedLibraryInfo.AddSharedLibrary(shlib); - }; + SharedLibrary shlib(modStart, modEnd, + 0, // DLLs are always mapped at offset 0 on Windows + breakpadId, std::string{}, moduleNameStr, modulePathStr, + pdbNameStr, pdbPathStr, versionStr, ""); + sharedLibraryInfo.AddSharedLibrary(shlib); + }; mozilla::EnumerateProcessModules(addSharedLibraryFromModuleInfo); return sharedLibraryInfo; diff --git a/mozglue/baseprofiler/public/BaseProfilerSharedLibraries.h b/mozglue/baseprofiler/public/BaseProfilerSharedLibraries.h index 0a104193c394..4e7d39f4c603 100644 --- a/mozglue/baseprofiler/public/BaseProfilerSharedLibraries.h +++ b/mozglue/baseprofiler/public/BaseProfilerSharedLibraries.h @@ -22,14 +22,15 @@ class SharedLibrary { public: SharedLibrary(uintptr_t aStart, uintptr_t aEnd, uintptr_t aOffset, - const std::string& aBreakpadId, const std::string& aModuleName, - const std::string& aModulePath, const std::string& aDebugName, - const std::string& aDebugPath, const std::string& aVersion, - const char* aArch) + const std::string& aBreakpadId, const std::string& aCodeId, + const std::string& aModuleName, const std::string& aModulePath, + const std::string& aDebugName, const std::string& aDebugPath, + const std::string& aVersion, const char* aArch) : mStart(aStart), mEnd(aEnd), mOffset(aOffset), mBreakpadId(aBreakpadId), + mCodeId(aCodeId), mModuleName(aModuleName), mModulePath(aModulePath), mDebugName(aDebugName), @@ -42,6 +43,7 @@ class SharedLibrary { mEnd(aEntry.mEnd), mOffset(aEntry.mOffset), mBreakpadId(aEntry.mBreakpadId), + mCodeId(aEntry.mCodeId), mModuleName(aEntry.mModuleName), mModulePath(aEntry.mModulePath), mDebugName(aEntry.mDebugName), @@ -57,6 +59,7 @@ class SharedLibrary { mEnd = aEntry.mEnd; mOffset = aEntry.mOffset; mBreakpadId = aEntry.mBreakpadId; + mCodeId = aEntry.mCodeId; mModuleName = aEntry.mModuleName; mModulePath = aEntry.mModulePath; mDebugName = aEntry.mDebugName; @@ -72,14 +75,15 @@ class SharedLibrary { (mModulePath == other.mModulePath) && (mDebugName == other.mDebugName) && (mDebugPath == other.mDebugPath) && - (mBreakpadId == other.mBreakpadId) && (mVersion == other.mVersion) && - (mArch == other.mArch); + (mBreakpadId == other.mBreakpadId) && (mCodeId == other.mCodeId) && + (mVersion == other.mVersion) && (mArch == other.mArch); } uintptr_t GetStart() const { return mStart; } uintptr_t GetEnd() const { return mEnd; } uintptr_t GetOffset() const { return mOffset; } const std::string& GetBreakpadId() const { return mBreakpadId; } + const std::string& GetCodeId() const { return mCodeId; } const std::string& GetModuleName() const { return mModuleName; } const std::string& GetModulePath() const { return mModulePath; } const std::string& GetDebugName() const { return mDebugName; } @@ -94,6 +98,17 @@ class SharedLibrary { uintptr_t mEnd; uintptr_t mOffset; std::string mBreakpadId; + // A string carrying an identifier for a binary. + // + // All platforms have different formats: + // - Windows: The code ID for a Windows PE file. + // It's the PE timestamp and PE image size. + // - macOS: The code ID for a macOS / iOS binary (mach-O). + // It's the mach-O UUID without dashes and without the trailing 0 for the + // breakpad ID. + // - Linux/Android: The code ID for a Linux ELF file. + // It's the complete build ID, as hex string. + std::string mCodeId; std::string mModuleName; std::string mModulePath; std::string mDebugName; diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp index 0196dbb4e730..ecbe7346224e 100644 --- a/tools/profiler/core/platform.cpp +++ b/tools/profiler/core/platform.cpp @@ -2604,6 +2604,7 @@ static void AddSharedLibraryInfoToStream(JSONWriter& aWriter, aWriter.StringProperty("debugPath", NS_ConvertUTF16toUTF8(aLib.GetDebugPath())); aWriter.StringProperty("breakpadId", aLib.GetBreakpadId()); + aWriter.StringProperty("codeId", aLib.GetCodeId()); aWriter.StringProperty("arch", aLib.GetArch()); aWriter.EndObject(); } diff --git a/tools/profiler/core/shared-libraries-linux.cc b/tools/profiler/core/shared-libraries-linux.cc index db980db55ae4..36fe509b8c75 100644 --- a/tools/profiler/core/shared-libraries-linux.cc +++ b/tools/profiler/core/shared-libraries-linux.cc @@ -99,8 +99,8 @@ static SharedLibrary SharedLibraryAtPath(const char* path, nameStr.Cut(0, pos + 1); } - return SharedLibrary(libStart, libEnd, offset, getId(path), nameStr, pathStr, - nameStr, pathStr, ""_ns, ""); + return SharedLibrary(libStart, libEnd, offset, getId(path), nsCString(), + nameStr, pathStr, nameStr, pathStr, ""_ns, ""); } static int dl_iterate_callback(struct dl_phdr_info* dl_info, size_t size, diff --git a/tools/profiler/core/shared-libraries-macos.cc b/tools/profiler/core/shared-libraries-macos.cc index 606677de9d3d..cdf717032414 100644 --- a/tools/profiler/core/shared-libraries-macos.cc +++ b/tools/profiler/core/shared-libraries-macos.cc @@ -166,8 +166,8 @@ static void addSharedLibrary(const platform_mach_header* header, const NXArchInfo* archInfo = NXGetArchInfoFromCpuType(header->cputype, header->cpusubtype); - info.AddSharedLibrary(SharedLibrary(start, start + size, 0, uuid, nameStr, - pathStr, nameStr, pathStr, ""_ns, + info.AddSharedLibrary(SharedLibrary(start, start + size, 0, uuid, nsCString(), + nameStr, pathStr, nameStr, pathStr, ""_ns, archInfo ? archInfo->name : "")); } diff --git a/tools/profiler/core/shared-libraries-win32.cc b/tools/profiler/core/shared-libraries-win32.cc index b8b61a2a9eed..11ca6c21e27a 100644 --- a/tools/profiler/core/shared-libraries-win32.cc +++ b/tools/profiler/core/shared-libraries-win32.cc @@ -127,11 +127,11 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() { const nsString& pdbNameStr = PromiseFlatString(mozilla::nt::GetLeafName(pdbPathStr)); - SharedLibrary shlib(modStart, modEnd, - 0, // DLLs are always mapped at offset 0 on Windows - breakpadId, PromiseFlatString(moduleNameStr), - nsDependentString(aModulePath), pdbNameStr, pdbPathStr, - versionStr, ""); + SharedLibrary shlib( + modStart, modEnd, + 0, // DLLs are always mapped at offset 0 on Windows + breakpadId, nsCString(), PromiseFlatString(moduleNameStr), + nsDependentString(aModulePath), pdbNameStr, pdbPathStr, versionStr, ""); sharedLibraryInfo.AddSharedLibrary(shlib); }; diff --git a/tools/profiler/public/shared-libraries.h b/tools/profiler/public/shared-libraries.h index 2397fbd84f54..f35e000d4d60 100644 --- a/tools/profiler/public/shared-libraries.h +++ b/tools/profiler/public/shared-libraries.h @@ -24,14 +24,15 @@ class SharedLibrary { public: SharedLibrary(uintptr_t aStart, uintptr_t aEnd, uintptr_t aOffset, - const nsCString& aBreakpadId, const nsString& aModuleName, - const nsString& aModulePath, const nsString& aDebugName, - const nsString& aDebugPath, const nsCString& aVersion, - const char* aArch) + const nsCString& aBreakpadId, const nsCString& aCodeId, + const nsString& aModuleName, const nsString& aModulePath, + const nsString& aDebugName, const nsString& aDebugPath, + const nsCString& aVersion, const char* aArch) : mStart(aStart), mEnd(aEnd), mOffset(aOffset), mBreakpadId(aBreakpadId), + mCodeId(aCodeId), mModuleName(aModuleName), mModulePath(aModulePath), mDebugName(aDebugName), @@ -44,6 +45,7 @@ class SharedLibrary { mEnd(aEntry.mEnd), mOffset(aEntry.mOffset), mBreakpadId(aEntry.mBreakpadId), + mCodeId(aEntry.mCodeId), mModuleName(aEntry.mModuleName), mModulePath(aEntry.mModulePath), mDebugName(aEntry.mDebugName), @@ -59,6 +61,7 @@ class SharedLibrary { mEnd = aEntry.mEnd; mOffset = aEntry.mOffset; mBreakpadId = aEntry.mBreakpadId; + mCodeId = aEntry.mCodeId; mModuleName = aEntry.mModuleName; mModulePath = aEntry.mModulePath; mDebugName = aEntry.mDebugName; @@ -74,14 +77,15 @@ class SharedLibrary { (mModulePath == other.mModulePath) && (mDebugName == other.mDebugName) && (mDebugPath == other.mDebugPath) && - (mBreakpadId == other.mBreakpadId) && (mVersion == other.mVersion) && - (mArch == other.mArch); + (mBreakpadId == other.mBreakpadId) && (mCodeId == other.mCodeId) && + (mVersion == other.mVersion) && (mArch == other.mArch); } uintptr_t GetStart() const { return mStart; } uintptr_t GetEnd() const { return mEnd; } uintptr_t GetOffset() const { return mOffset; } const nsCString& GetBreakpadId() const { return mBreakpadId; } + const nsCString& GetCodeId() const { return mCodeId; } const nsString& GetModuleName() const { return mModuleName; } const nsString& GetModulePath() const { return mModulePath; } const std::string GetNativeDebugPath() const { @@ -103,6 +107,17 @@ class SharedLibrary { uintptr_t mEnd; uintptr_t mOffset; nsCString mBreakpadId; + // A string carrying an identifier for a binary. + // + // All platforms have different formats: + // - Windows: The code ID for a Windows PE file. + // It's the PE timestamp and PE image size. + // - macOS: The code ID for a macOS / iOS binary (mach-O). + // It's the mach-O UUID without dashes and without the trailing 0 for the + // breakpad ID. + // - Linux/Android: The code ID for a Linux ELF file. + // It's the complete build ID, as hex string. + nsCString mCodeId; nsString mModuleName; nsString mModulePath; nsString mDebugName;