Bug 735829. Report PDB filename in chrome hang reports. r=ehsan

This commit is contained in:
Vladan Djeric 2012-03-19 19:05:25 -04:00
parent f2f24e59a6
commit 3f47c98434
5 changed files with 48 additions and 6 deletions

View File

@ -1089,6 +1089,20 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, jsval *ret)
if (!JS_SetElement(cx, moduleInfoArray, 4, &val)) {
return NS_ERROR_FAILURE;
}
// Name of associated PDB file
const char *pdbName = "";
#if defined(MOZ_PROFILING) && defined(XP_WIN)
pdbName = module.GetPdbName();
#endif
str = JS_NewStringCopyZ(cx, pdbName);
if (!str) {
return NS_ERROR_FAILURE;
}
val = STRING_TO_JSVAL(str);
if (!JS_SetElement(cx, moduleInfoArray, 5, &val)) {
return NS_ERROR_FAILURE;
}
}
#endif
}

View File

@ -99,6 +99,7 @@ AddSharedLibraryInfoToStream(std::ostream& aStream, SharedLibrary& aLib)
#ifdef XP_WIN
aStream << ",\"pdbSignature\":\"" << aLib.GetPdbSignature().ToString() << "\"";
aStream << ",\"pdbAge\":" << aLib.GetPdbAge();
aStream << ",\"pdbName\":" << aLib.GetPdbName();
#endif
aStream << "}";
}

View File

@ -51,10 +51,10 @@ struct CodeViewRecord70
uint32_t signature;
GUID pdbSignature;
uint32_t pdbAge;
uint8_t pdbFileName[1];
char pdbFileName[1];
};
static bool GetPdbInfo(uintptr_t aStart, nsID& aSignature, uint32_t& aAge)
static bool GetPdbInfo(uintptr_t aStart, nsID& aSignature, uint32_t& aAge, char** aPdbName)
{
if (!aStart) {
return false;
@ -95,6 +95,17 @@ static bool GetPdbInfo(uintptr_t aStart, nsID& aSignature, uint32_t& aAge)
aSignature.m1 = pdbSignature.Data2;
aSignature.m2 = pdbSignature.Data3;
memcpy(aSignature.m3, pdbSignature.Data4, sizeof(pdbSignature.Data4));
// 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
char * leafName = strrchr(debugInfo->pdbFileName, '\\');
if (leafName) {
// Only report the file portion of the path
*aPdbName = leafName + 1;
} else {
*aPdbName = debugInfo->pdbFileName;
}
return true;
}
@ -110,12 +121,14 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf()
do {
nsID pdbSig;
uint32_t pdbAge;
if (GetPdbInfo((uintptr_t)module.modBaseAddr, pdbSig, pdbAge)) {
char *pdbName = NULL;
if (GetPdbInfo((uintptr_t)module.modBaseAddr, pdbSig, pdbAge, &pdbName)) {
SharedLibrary shlib((uintptr_t)module.modBaseAddr,
(uintptr_t)module.modBaseAddr+module.modBaseSize,
0, // DLLs are always mapped at offset 0 on Windows
pdbSig,
pdbAge,
pdbName,
module.szModule);
sharedLibraryInfo.AddSharedLibrary(shlib);
}

View File

@ -59,6 +59,7 @@ public:
#ifdef XP_WIN
nsID aPdbSignature,
unsigned long aPdbAge,
char *aPdbName,
#endif
char *aName)
: mStart(aStart)
@ -67,6 +68,7 @@ public:
#ifdef XP_WIN
, mPdbSignature(aPdbSignature)
, mPdbAge(aPdbAge)
, mPdbName(strdup(aPdbName))
#endif
, mName(strdup(aName))
{}
@ -78,6 +80,7 @@ public:
#ifdef XP_WIN
, mPdbSignature(aEntry.mPdbSignature)
, mPdbAge(aEntry.mPdbAge)
, mPdbName(strdup(aEntry.mPdbName))
#endif
, mName(strdup(aEntry.mName))
{}
@ -93,6 +96,9 @@ public:
#ifdef XP_WIN
mPdbSignature = aEntry.mPdbSignature;
mPdbAge = aEntry.mPdbAge;
if (mPdbName)
free(mPdbName);
mPdbName = strdup(aEntry.mPdbName);
#endif
if (mName)
free(mName);
@ -109,13 +115,18 @@ public:
#ifdef XP_WIN
equal = equal &&
(mPdbSignature.Equals(other.mPdbSignature)) &&
(mPdbAge == other.mPdbAge);
(mPdbAge == other.mPdbAge) &&
(mPdbName && other.mPdbName && (strcmp(mPdbName, other.mPdbName) == 0));
#endif
return equal;
}
~SharedLibrary()
{
#ifdef XP_WIN
free(mPdbName);
mPdbName = NULL;
#endif
free(mName);
mName = NULL;
}
@ -125,6 +136,7 @@ public:
#ifdef XP_WIN
nsID GetPdbSignature() const { return mPdbSignature; }
uint32_t GetPdbAge() const { return mPdbAge; }
char* GetPdbName() const { return mPdbName; }
#endif
char* GetName() const { return mName; }
@ -138,6 +150,7 @@ private:
// Windows-specific PDB file identifiers
nsID mPdbSignature;
uint32_t mPdbAge;
char *mPdbName;
#endif
char *mName;
};

View File

@ -150,8 +150,6 @@ static void
GetChromeHangReport(Telemetry::HangStack &callStack, SharedLibraryInfo &moduleMap)
{
MOZ_ASSERT(winMainThreadHandle);
moduleMap = SharedLibraryInfo::GetInfoForSelf();
moduleMap.SortByAddress();
DWORD ret = ::SuspendThread(winMainThreadHandle);
if (ret == -1) {
@ -168,6 +166,9 @@ GetChromeHangReport(Telemetry::HangStack &callStack, SharedLibraryInfo &moduleMa
return;
}
moduleMap = SharedLibraryInfo::GetInfoForSelf();
moduleMap.SortByAddress();
// Remove all modules not referenced by a PC on the stack
Telemetry::HangStack sortedStack = callStack;
sortedStack.Sort();