Bug 1811068 - Add codeId field to SharedLibrary class and output it in profile json r=mstange

Differential Revision: https://phabricator.services.mozilla.com/D169515
This commit is contained in:
Nazım Can Altınova 2023-02-14 14:50:56 +00:00
Родитель 0caf39c7dc
Коммит a224d65e3f
10 изменённых файлов: 140 добавлений и 108 удалений

Просмотреть файл

@ -1768,6 +1768,7 @@ static void AddSharedLibraryInfoToStream(JSONWriter& aWriter,
aWriter.StringProperty("debugName", aLib.GetDebugName()); aWriter.StringProperty("debugName", aLib.GetDebugName());
aWriter.StringProperty("debugPath", aLib.GetDebugPath()); aWriter.StringProperty("debugPath", aLib.GetDebugPath());
aWriter.StringProperty("breakpadId", aLib.GetBreakpadId()); aWriter.StringProperty("breakpadId", aLib.GetBreakpadId());
aWriter.StringProperty("codeId", aLib.GetCodeId());
aWriter.StringProperty("arch", aLib.GetArch()); aWriter.StringProperty("arch", aLib.GetArch());
aWriter.EndObject(); aWriter.EndObject();
} }

Просмотреть файл

@ -678,8 +678,8 @@ static SharedLibrary SharedLibraryAtPath(const char* path,
std::string nameStr = std::string nameStr =
(pos != std::string::npos) ? pathStr.substr(pos + 1) : pathStr; (pos != std::string::npos) ? pathStr.substr(pos + 1) : pathStr;
return SharedLibrary(libStart, libEnd, offset, getId(path), nameStr, pathStr, return SharedLibrary(libStart, libEnd, offset, getId(path), std::string{},
nameStr, pathStr, std::string{}, ""); nameStr, pathStr, nameStr, pathStr, std::string{}, "");
} }
static int dl_iterate_callback(struct dl_phdr_info* dl_info, size_t size, static int dl_iterate_callback(struct dl_phdr_info* dl_info, size_t size,

Просмотреть файл

@ -163,9 +163,9 @@ static void addSharedLibrary(const platform_mach_header* header,
const NXArchInfo* archInfo = const NXArchInfo* archInfo =
NXGetArchInfoFromCpuType(header->cputype, header->cpusubtype); NXGetArchInfoFromCpuType(header->cputype, header->cpusubtype);
info.AddSharedLibrary(SharedLibrary(start, start + size, 0, uuid, nameStr, info.AddSharedLibrary(SharedLibrary(
pathStr, nameStr, pathStr, std::string{}, start, start + size, 0, uuid, std::string{}, nameStr, pathStr, nameStr,
archInfo ? archInfo->name : "")); pathStr, std::string{}, archInfo ? archInfo->name : ""));
} }
// Translate the statically stored sSharedLibrariesList information into a // Translate the statically stored sSharedLibrariesList information into a

Просмотреть файл

@ -93,98 +93,98 @@ static bool IsModuleUnsafeToLoad(const std::string& aModuleName) {
SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() { SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
SharedLibraryInfo sharedLibraryInfo; SharedLibraryInfo sharedLibraryInfo;
auto addSharedLibraryFromModuleInfo = auto addSharedLibraryFromModuleInfo = [&sharedLibraryInfo](
[&sharedLibraryInfo](const wchar_t* aModulePath, HMODULE aModule) { const wchar_t* aModulePath,
mozilla::UniquePtr<char[]> utf8ModulePath( HMODULE aModule) {
mozilla::glue::WideToUTF8(aModulePath)); mozilla::UniquePtr<char[]> utf8ModulePath(
if (!utf8ModulePath) { mozilla::glue::WideToUTF8(aModulePath));
return; if (!utf8ModulePath) {
} return;
}
std::string modulePathStr(utf8ModulePath.get()); std::string modulePathStr(utf8ModulePath.get());
size_t pos = modulePathStr.find_last_of("\\/"); size_t pos = modulePathStr.find_last_of("\\/");
std::string moduleNameStr = (pos != std::string::npos) std::string moduleNameStr = (pos != std::string::npos)
? modulePathStr.substr(pos + 1) ? modulePathStr.substr(pos + 1)
: modulePathStr; : modulePathStr;
// If the module is unsafe to call LoadLibraryEx for, we skip. // If the module is unsafe to call LoadLibraryEx for, we skip.
if (IsModuleUnsafeToLoad(moduleNameStr)) { if (IsModuleUnsafeToLoad(moduleNameStr)) {
return; return;
} }
// Load the module again to make sure that its handle will remain // 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 // 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 // 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 // module's DllMain function. If the original handle |aModule| is
// valid, LoadLibraryEx just increments its refcount. // valid, LoadLibraryEx just increments its refcount.
// LOAD_LIBRARY_AS_IMAGE_RESOURCE is needed to read information from the // LOAD_LIBRARY_AS_IMAGE_RESOURCE is needed to read information from the
// sections (not PE headers) which should be relocated by the loader, // sections (not PE headers) which should be relocated by the loader,
// otherwise GetPdbInfo() will cause a crash. // otherwise GetPdbInfo() will cause a crash.
nsModuleHandle handleLock(::LoadLibraryExW( nsModuleHandle handleLock(::LoadLibraryExW(
aModulePath, NULL, aModulePath, NULL,
LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)); LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE));
if (!handleLock) { if (!handleLock) {
return; return;
} }
mozilla::nt::PEHeaders headers(handleLock.get()); mozilla::nt::PEHeaders headers(handleLock.get());
if (!headers) { if (!headers) {
return; return;
} }
mozilla::Maybe<mozilla::Range<const uint8_t>> bounds = mozilla::Maybe<mozilla::Range<const uint8_t>> bounds = headers.GetBounds();
headers.GetBounds(); if (!bounds) {
if (!bounds) { return;
return; }
}
// Put the original |aModule| into SharedLibrary, but we get debug info // Put the original |aModule| into SharedLibrary, but we get debug info
// from |handleLock| as |aModule| might be inaccessible. // from |handleLock| as |aModule| might be inaccessible.
const uintptr_t modStart = reinterpret_cast<uintptr_t>(aModule); const uintptr_t modStart = reinterpret_cast<uintptr_t>(aModule);
const uintptr_t modEnd = modStart + bounds->length(); const uintptr_t modEnd = modStart + bounds->length();
std::string breakpadId; std::string breakpadId;
std::string pdbPathStr; std::string pdbPathStr;
std::string pdbNameStr; std::string pdbNameStr;
if (const auto* debugInfo = headers.GetPdbInfo()) { if (const auto* debugInfo = headers.GetPdbInfo()) {
MOZ_ASSERT(breakpadId.empty()); MOZ_ASSERT(breakpadId.empty());
const GUID& pdbSig = debugInfo->pdbSignature; const GUID& pdbSig = debugInfo->pdbSignature;
AppendHex(pdbSig.Data1, breakpadId, WITH_PADDING); AppendHex(pdbSig.Data1, breakpadId, WITH_PADDING);
AppendHex(pdbSig.Data2, breakpadId, WITH_PADDING); AppendHex(pdbSig.Data2, breakpadId, WITH_PADDING);
AppendHex(pdbSig.Data3, breakpadId, WITH_PADDING); AppendHex(pdbSig.Data3, breakpadId, WITH_PADDING);
AppendHex(reinterpret_cast<const unsigned char*>(&pdbSig.Data4), AppendHex(reinterpret_cast<const unsigned char*>(&pdbSig.Data4),
reinterpret_cast<const unsigned char*>(&pdbSig.Data4) + reinterpret_cast<const unsigned char*>(&pdbSig.Data4) +
sizeof(pdbSig.Data4), sizeof(pdbSig.Data4),
breakpadId); breakpadId);
AppendHex(debugInfo->pdbAge, breakpadId, WITHOUT_PADDING); AppendHex(debugInfo->pdbAge, breakpadId, WITHOUT_PADDING);
// The PDB file name could be different from module filename, // The PDB file name could be different from module filename,
// so report both // so report both
// e.g. The PDB for C:\Windows\SysWOW64\ntdll.dll is wntdll.pdb // e.g. The PDB for C:\Windows\SysWOW64\ntdll.dll is wntdll.pdb
pdbPathStr = debugInfo->pdbFileName; pdbPathStr = debugInfo->pdbFileName;
size_t pos = pdbPathStr.find_last_of("\\/"); size_t pos = pdbPathStr.find_last_of("\\/");
pdbNameStr = (pos != std::string::npos) ? pdbPathStr.substr(pos + 1) pdbNameStr =
: pdbPathStr; (pos != std::string::npos) ? pdbPathStr.substr(pos + 1) : pdbPathStr;
} }
std::string versionStr; std::string versionStr;
uint64_t version; uint64_t version;
if (headers.GetVersionInfo(version)) { if (headers.GetVersionInfo(version)) {
versionStr += std::to_string((version >> 48) & 0xFFFF); versionStr += std::to_string((version >> 48) & 0xFFFF);
versionStr += '.'; versionStr += '.';
versionStr += std::to_string((version >> 32) & 0xFFFF); versionStr += std::to_string((version >> 32) & 0xFFFF);
versionStr += '.'; versionStr += '.';
versionStr += std::to_string((version >> 16) & 0xFFFF); versionStr += std::to_string((version >> 16) & 0xFFFF);
versionStr += '.'; versionStr += '.';
versionStr += std::to_string(version & 0xFFFF); versionStr += std::to_string(version & 0xFFFF);
} }
SharedLibrary shlib(modStart, modEnd, SharedLibrary shlib(modStart, modEnd,
0, // DLLs are always mapped at offset 0 on Windows 0, // DLLs are always mapped at offset 0 on Windows
breakpadId, moduleNameStr, modulePathStr, breakpadId, std::string{}, moduleNameStr, modulePathStr,
pdbNameStr, pdbPathStr, versionStr, ""); pdbNameStr, pdbPathStr, versionStr, "");
sharedLibraryInfo.AddSharedLibrary(shlib); sharedLibraryInfo.AddSharedLibrary(shlib);
}; };
mozilla::EnumerateProcessModules(addSharedLibraryFromModuleInfo); mozilla::EnumerateProcessModules(addSharedLibraryFromModuleInfo);
return sharedLibraryInfo; return sharedLibraryInfo;

Просмотреть файл

@ -22,14 +22,15 @@
class SharedLibrary { class SharedLibrary {
public: public:
SharedLibrary(uintptr_t aStart, uintptr_t aEnd, uintptr_t aOffset, SharedLibrary(uintptr_t aStart, uintptr_t aEnd, uintptr_t aOffset,
const std::string& aBreakpadId, const std::string& aModuleName, const std::string& aBreakpadId, const std::string& aCodeId,
const std::string& aModulePath, const std::string& aDebugName, const std::string& aModuleName, const std::string& aModulePath,
const std::string& aDebugPath, const std::string& aVersion, const std::string& aDebugName, const std::string& aDebugPath,
const char* aArch) const std::string& aVersion, const char* aArch)
: mStart(aStart), : mStart(aStart),
mEnd(aEnd), mEnd(aEnd),
mOffset(aOffset), mOffset(aOffset),
mBreakpadId(aBreakpadId), mBreakpadId(aBreakpadId),
mCodeId(aCodeId),
mModuleName(aModuleName), mModuleName(aModuleName),
mModulePath(aModulePath), mModulePath(aModulePath),
mDebugName(aDebugName), mDebugName(aDebugName),
@ -42,6 +43,7 @@ class SharedLibrary {
mEnd(aEntry.mEnd), mEnd(aEntry.mEnd),
mOffset(aEntry.mOffset), mOffset(aEntry.mOffset),
mBreakpadId(aEntry.mBreakpadId), mBreakpadId(aEntry.mBreakpadId),
mCodeId(aEntry.mCodeId),
mModuleName(aEntry.mModuleName), mModuleName(aEntry.mModuleName),
mModulePath(aEntry.mModulePath), mModulePath(aEntry.mModulePath),
mDebugName(aEntry.mDebugName), mDebugName(aEntry.mDebugName),
@ -57,6 +59,7 @@ class SharedLibrary {
mEnd = aEntry.mEnd; mEnd = aEntry.mEnd;
mOffset = aEntry.mOffset; mOffset = aEntry.mOffset;
mBreakpadId = aEntry.mBreakpadId; mBreakpadId = aEntry.mBreakpadId;
mCodeId = aEntry.mCodeId;
mModuleName = aEntry.mModuleName; mModuleName = aEntry.mModuleName;
mModulePath = aEntry.mModulePath; mModulePath = aEntry.mModulePath;
mDebugName = aEntry.mDebugName; mDebugName = aEntry.mDebugName;
@ -72,14 +75,15 @@ class SharedLibrary {
(mModulePath == other.mModulePath) && (mModulePath == other.mModulePath) &&
(mDebugName == other.mDebugName) && (mDebugName == other.mDebugName) &&
(mDebugPath == other.mDebugPath) && (mDebugPath == other.mDebugPath) &&
(mBreakpadId == other.mBreakpadId) && (mVersion == other.mVersion) && (mBreakpadId == other.mBreakpadId) && (mCodeId == other.mCodeId) &&
(mArch == other.mArch); (mVersion == other.mVersion) && (mArch == other.mArch);
} }
uintptr_t GetStart() const { return mStart; } uintptr_t GetStart() const { return mStart; }
uintptr_t GetEnd() const { return mEnd; } uintptr_t GetEnd() const { return mEnd; }
uintptr_t GetOffset() const { return mOffset; } uintptr_t GetOffset() const { return mOffset; }
const std::string& GetBreakpadId() const { return mBreakpadId; } const std::string& GetBreakpadId() const { return mBreakpadId; }
const std::string& GetCodeId() const { return mCodeId; }
const std::string& GetModuleName() const { return mModuleName; } const std::string& GetModuleName() const { return mModuleName; }
const std::string& GetModulePath() const { return mModulePath; } const std::string& GetModulePath() const { return mModulePath; }
const std::string& GetDebugName() const { return mDebugName; } const std::string& GetDebugName() const { return mDebugName; }
@ -94,6 +98,17 @@ class SharedLibrary {
uintptr_t mEnd; uintptr_t mEnd;
uintptr_t mOffset; uintptr_t mOffset;
std::string mBreakpadId; 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 mModuleName;
std::string mModulePath; std::string mModulePath;
std::string mDebugName; std::string mDebugName;

Просмотреть файл

@ -2604,6 +2604,7 @@ static void AddSharedLibraryInfoToStream(JSONWriter& aWriter,
aWriter.StringProperty("debugPath", aWriter.StringProperty("debugPath",
NS_ConvertUTF16toUTF8(aLib.GetDebugPath())); NS_ConvertUTF16toUTF8(aLib.GetDebugPath()));
aWriter.StringProperty("breakpadId", aLib.GetBreakpadId()); aWriter.StringProperty("breakpadId", aLib.GetBreakpadId());
aWriter.StringProperty("codeId", aLib.GetCodeId());
aWriter.StringProperty("arch", aLib.GetArch()); aWriter.StringProperty("arch", aLib.GetArch());
aWriter.EndObject(); aWriter.EndObject();
} }

Просмотреть файл

@ -99,8 +99,8 @@ static SharedLibrary SharedLibraryAtPath(const char* path,
nameStr.Cut(0, pos + 1); nameStr.Cut(0, pos + 1);
} }
return SharedLibrary(libStart, libEnd, offset, getId(path), nameStr, pathStr, return SharedLibrary(libStart, libEnd, offset, getId(path), nsCString(),
nameStr, pathStr, ""_ns, ""); nameStr, pathStr, nameStr, pathStr, ""_ns, "");
} }
static int dl_iterate_callback(struct dl_phdr_info* dl_info, size_t size, static int dl_iterate_callback(struct dl_phdr_info* dl_info, size_t size,

Просмотреть файл

@ -166,8 +166,8 @@ static void addSharedLibrary(const platform_mach_header* header,
const NXArchInfo* archInfo = const NXArchInfo* archInfo =
NXGetArchInfoFromCpuType(header->cputype, header->cpusubtype); NXGetArchInfoFromCpuType(header->cputype, header->cpusubtype);
info.AddSharedLibrary(SharedLibrary(start, start + size, 0, uuid, nameStr, info.AddSharedLibrary(SharedLibrary(start, start + size, 0, uuid, nsCString(),
pathStr, nameStr, pathStr, ""_ns, nameStr, pathStr, nameStr, pathStr, ""_ns,
archInfo ? archInfo->name : "")); archInfo ? archInfo->name : ""));
} }

Просмотреть файл

@ -127,11 +127,11 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
const nsString& pdbNameStr = const nsString& pdbNameStr =
PromiseFlatString(mozilla::nt::GetLeafName(pdbPathStr)); PromiseFlatString(mozilla::nt::GetLeafName(pdbPathStr));
SharedLibrary shlib(modStart, modEnd, SharedLibrary shlib(
0, // DLLs are always mapped at offset 0 on Windows modStart, modEnd,
breakpadId, PromiseFlatString(moduleNameStr), 0, // DLLs are always mapped at offset 0 on Windows
nsDependentString(aModulePath), pdbNameStr, pdbPathStr, breakpadId, nsCString(), PromiseFlatString(moduleNameStr),
versionStr, ""); nsDependentString(aModulePath), pdbNameStr, pdbPathStr, versionStr, "");
sharedLibraryInfo.AddSharedLibrary(shlib); sharedLibraryInfo.AddSharedLibrary(shlib);
}; };

Просмотреть файл

@ -24,14 +24,15 @@
class SharedLibrary { class SharedLibrary {
public: public:
SharedLibrary(uintptr_t aStart, uintptr_t aEnd, uintptr_t aOffset, SharedLibrary(uintptr_t aStart, uintptr_t aEnd, uintptr_t aOffset,
const nsCString& aBreakpadId, const nsString& aModuleName, const nsCString& aBreakpadId, const nsCString& aCodeId,
const nsString& aModulePath, const nsString& aDebugName, const nsString& aModuleName, const nsString& aModulePath,
const nsString& aDebugPath, const nsCString& aVersion, const nsString& aDebugName, const nsString& aDebugPath,
const char* aArch) const nsCString& aVersion, const char* aArch)
: mStart(aStart), : mStart(aStart),
mEnd(aEnd), mEnd(aEnd),
mOffset(aOffset), mOffset(aOffset),
mBreakpadId(aBreakpadId), mBreakpadId(aBreakpadId),
mCodeId(aCodeId),
mModuleName(aModuleName), mModuleName(aModuleName),
mModulePath(aModulePath), mModulePath(aModulePath),
mDebugName(aDebugName), mDebugName(aDebugName),
@ -44,6 +45,7 @@ class SharedLibrary {
mEnd(aEntry.mEnd), mEnd(aEntry.mEnd),
mOffset(aEntry.mOffset), mOffset(aEntry.mOffset),
mBreakpadId(aEntry.mBreakpadId), mBreakpadId(aEntry.mBreakpadId),
mCodeId(aEntry.mCodeId),
mModuleName(aEntry.mModuleName), mModuleName(aEntry.mModuleName),
mModulePath(aEntry.mModulePath), mModulePath(aEntry.mModulePath),
mDebugName(aEntry.mDebugName), mDebugName(aEntry.mDebugName),
@ -59,6 +61,7 @@ class SharedLibrary {
mEnd = aEntry.mEnd; mEnd = aEntry.mEnd;
mOffset = aEntry.mOffset; mOffset = aEntry.mOffset;
mBreakpadId = aEntry.mBreakpadId; mBreakpadId = aEntry.mBreakpadId;
mCodeId = aEntry.mCodeId;
mModuleName = aEntry.mModuleName; mModuleName = aEntry.mModuleName;
mModulePath = aEntry.mModulePath; mModulePath = aEntry.mModulePath;
mDebugName = aEntry.mDebugName; mDebugName = aEntry.mDebugName;
@ -74,14 +77,15 @@ class SharedLibrary {
(mModulePath == other.mModulePath) && (mModulePath == other.mModulePath) &&
(mDebugName == other.mDebugName) && (mDebugName == other.mDebugName) &&
(mDebugPath == other.mDebugPath) && (mDebugPath == other.mDebugPath) &&
(mBreakpadId == other.mBreakpadId) && (mVersion == other.mVersion) && (mBreakpadId == other.mBreakpadId) && (mCodeId == other.mCodeId) &&
(mArch == other.mArch); (mVersion == other.mVersion) && (mArch == other.mArch);
} }
uintptr_t GetStart() const { return mStart; } uintptr_t GetStart() const { return mStart; }
uintptr_t GetEnd() const { return mEnd; } uintptr_t GetEnd() const { return mEnd; }
uintptr_t GetOffset() const { return mOffset; } uintptr_t GetOffset() const { return mOffset; }
const nsCString& GetBreakpadId() const { return mBreakpadId; } const nsCString& GetBreakpadId() const { return mBreakpadId; }
const nsCString& GetCodeId() const { return mCodeId; }
const nsString& GetModuleName() const { return mModuleName; } const nsString& GetModuleName() const { return mModuleName; }
const nsString& GetModulePath() const { return mModulePath; } const nsString& GetModulePath() const { return mModulePath; }
const std::string GetNativeDebugPath() const { const std::string GetNativeDebugPath() const {
@ -103,6 +107,17 @@ class SharedLibrary {
uintptr_t mEnd; uintptr_t mEnd;
uintptr_t mOffset; uintptr_t mOffset;
nsCString mBreakpadId; 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 mModuleName;
nsString mModulePath; nsString mModulePath;
nsString mDebugName; nsString mDebugName;