Bug 1270686. Log all dlls ever loaded. r=aklotz

This is a temporary patch to try to figure out if a dll is being unloaded that we still need.
This commit is contained in:
Jeff Muizelaar 2016-05-25 23:08:32 -04:00
parent 17fddfe3c0
commit 4ee421d8de
5 changed files with 81 additions and 4 deletions

View File

@ -17,10 +17,13 @@
#include <windows.h>
#include <winternl.h>
#include <io.h>
#define PSAPI_VERSION 1
#include <psapi.h>
#pragma warning( push )
#pragma warning( disable : 4275 4530 ) // See msvc-stl-wrapper.template.h
#include <map>
#include <vector>
#pragma warning( pop )
#include "nsAutoPtr.h"
@ -543,11 +546,15 @@ static wchar_t* lastslash(wchar_t* s, int len)
return nullptr;
}
#ifdef NIGHTLY_BUILD
static std::vector<DllLoadInfo> gDllLoadInfos;
static LoadCallBackFn gLoadInfoCallback;
#endif
static NTSTATUS NTAPI
patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileName, PHANDLE handle)
{
// We have UCS2 (UTF16?), we want ASCII, but we also just want the filename portion
#define DLLNAME_MAX 128
char dllName[DLLNAME_MAX+1];
wchar_t *dll_part;
char *dot;
@ -735,14 +742,41 @@ continue_loading:
return STATUS_DLL_NOT_FOUND;
}
}
return stub_LdrLoadDll(filePath, flags, moduleFileName, handle);
NTSTATUS ret = stub_LdrLoadDll(filePath, flags, moduleFileName, handle);
#if defined(NIGHTLY_BUILD) && !defined(_WIN64)
if (!ret) {
MODULEINFO moduleInfo;
if (GetModuleInformation(GetCurrentProcess(), *(HMODULE*)handle, &moduleInfo, sizeof(moduleInfo))) {
DllLoadInfo info;
strcpy(info.name, dllName);
info.lpBaseOfDll = moduleInfo.lpBaseOfDll;
info.SizeOfImage = moduleInfo.SizeOfImage;
if (gLoadInfoCallback) {
gLoadInfoCallback(info);
} else {
gDllLoadInfos.push_back(info);
}
}
}
#endif
return ret;
}
WindowsDllInterceptor NtDllIntercept;
} // namespace
#ifdef NIGHTLY_BUILD
MFBT_API void
RegisterDllLoadCallback(LoadCallBackFn aCallback) {
gLoadInfoCallback = aCallback;
for (DllLoadInfo &info : gDllLoadInfos) {
aCallback(info);
}
//gDllLoadInfos.clear();
}
#endif
MFBT_API void
DllBlocklist_Initialize()
{

View File

@ -34,5 +34,17 @@ class MOZ_RAII AutoSetXPCOMLoadOnMainThread
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
#define DLLNAME_MAX 128
#ifdef NIGHTLY_BUILD
struct DllLoadInfo
{
char name[DLLNAME_MAX+1];
LPVOID lpBaseOfDll;
DWORD SizeOfImage;
};
typedef void (*LoadCallBackFn)(DllLoadInfo&);
MFBT_API void RegisterDllLoadCallback(LoadCallBackFn);
#endif // NIGHTLY_BUILD
#endif // defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
#endif // mozilla_windowsdllblocklist_h

View File

@ -52,6 +52,7 @@ if not CONFIG['JS_STANDALONE']:
]
DISABLE_STL_WRAPPING = True
OS_LIBS += [
'psapi',
'version',
]

View File

@ -14,6 +14,7 @@
#include "mozilla/Services.h"
#include "nsIObserverService.h"
#include "mozilla/unused.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/Snprintf.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/TimeStamp.h"
@ -1437,9 +1438,30 @@ ChildFilter(void* context)
return result;
}
#if defined(XP_WIN) && defined(NIGHTLY_BUILD)
static void DllLoadCallback(DllLoadInfo& info)
{
nsAutoCString note;
note.AppendPrintf("%s-%p-%x\n", info.name, info.lpBaseOfDll, info.SizeOfImage);
CrashReporter::AppendAppNotesToCrashReport(note);
}
static void EmptyDllLoadCallback(DllLoadInfo& info)
{
}
#endif
nsresult SetExceptionHandler(nsIFile* aXREDirectory,
bool force/*=false*/)
{
#if defined(XP_WIN) && defined(NIGHTLY_BUILD)
auto dllCallbackGuard = MakeScopeExit([] {
RegisterDllLoadCallback(EmptyDllLoadCallback);
});
#endif
if (gExceptionHandler)
return NS_ERROR_ALREADY_INITIALIZED;
@ -1674,6 +1696,11 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
mozalloc_set_oom_abort_handler(AnnotateOOMAllocationSize);
#if defined(XP_WIN) && defined(NIGHTLY_BUILD)
dllCallbackGuard.release();
RegisterDllLoadCallback(DllLoadCallback);
#endif
return NS_OK;
}

View File

@ -45,7 +45,10 @@ function run_test()
function(mdump, extra) {
do_check_eq(extra.TestKey, "TestValue");
do_check_eq(extra["\u2665"], "\u{1F4A9}");
do_check_eq(extra.Notes, "JunkMoreJunk");
// we spam the crash dumps with dlls loading so temporarily disable
// this check on windows
if (!is_windows)
do_check_eq(extra.Notes, "JunkMoreJunk");
do_check_true(!("TelemetrySessionId" in extra));
});
}