Skidmark for bug 524944 r=bsmedberg

This commit is contained in:
Jonas Sicking 2009-12-17 21:54:02 -08:00
parent ff387b5bf2
commit e97d2a7def
6 changed files with 114 additions and 0 deletions

View File

@ -207,6 +207,8 @@ continue_loading:
printf_stderr("LdrLoadDll: continuing load... ('%S')\n", moduleFileName->Buffer);
#endif
NS_SetHasLoadedNewDLLs();
return stub_LdrLoadDll(filePath, flags, moduleFileName, handle);
}

View File

@ -41,6 +41,11 @@
#include "nsToolkit.h"
#include "nsThreadUtils.h"
#include "WinTaskbar.h"
#include "nsString.h"
// For skidmark code
#include <windows.h>
#include <tlhelp32.h>
#ifdef WINCE
BOOL WaitMessage(VOID)
@ -155,6 +160,87 @@ nsAppShell::Init()
return nsBaseAppShell::Init();
}
/**
* This is some temporary code to keep track of where in memory dlls are
* loaded. This is useful in case someone calls into a dll that has been
* unloaded. This code lets us see which dll used to be loaded at the given
* called address.
*/
#if defined(_MSC_VER) && defined(_M_IX86)
#define LOADEDMODULEINFO_STRSIZE 23
#define NUM_LOADEDMODULEINFO 250
struct LoadedModuleInfo {
void* mStartAddr;
void* mEndAddr;
char mName[LOADEDMODULEINFO_STRSIZE + 1];
};
static LoadedModuleInfo* sLoadedModules = 0;
static void
CollectNewLoadedModules()
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 module;
// Take a snapshot of all modules in our process.
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
if (hModuleSnap == INVALID_HANDLE_VALUE)
return;
// Set the size of the structure before using it.
module.dwSize = sizeof(MODULEENTRY32);
// Now walk the module list of the process,
// and display information about each module
PRBool done = !Module32First(hModuleSnap, &module);
while (!done) {
NS_LossyConvertUTF16toASCII moduleName(module.szModule);
PRBool found = PR_FALSE;
PRUint32 i;
for (i = 0; i < NUM_LOADEDMODULEINFO &&
sLoadedModules[i].mStartAddr; ++i) {
if (sLoadedModules[i].mStartAddr == module.modBaseAddr &&
!strcmp(moduleName.get(),
sLoadedModules[i].mName)) {
found = PR_TRUE;
break;
}
}
if (!found && i < NUM_LOADEDMODULEINFO) {
sLoadedModules[i].mStartAddr = module.modBaseAddr;
sLoadedModules[i].mEndAddr = module.modBaseAddr + module.modBaseSize;
strncpy(sLoadedModules[i].mName, moduleName.get(),
LOADEDMODULEINFO_STRSIZE);
sLoadedModules[i].mName[LOADEDMODULEINFO_STRSIZE] = 0;
}
done = !Module32Next(hModuleSnap, &module);
}
PRUint32 i;
for (i = 0; i < NUM_LOADEDMODULEINFO &&
sLoadedModules[i].mStartAddr; ++i) {}
CloseHandle(hModuleSnap);
}
NS_IMETHODIMP
nsAppShell::Run(void)
{
LoadedModuleInfo modules[NUM_LOADEDMODULEINFO];
memset(modules, 0, sizeof(modules));
sLoadedModules = modules;
return nsBaseAppShell::Run();
}
#endif
void
nsAppShell::ScheduleNativeEventCallback()
{
@ -166,6 +252,13 @@ nsAppShell::ScheduleNativeEventCallback()
PRBool
nsAppShell::ProcessNextNativeEvent(PRBool mayWait)
{
#if defined(_MSC_VER) && defined(_M_IX86)
if (sXPCOMHasLoadedNewDLLs && sLoadedModules) {
sXPCOMHasLoadedNewDLLs = PR_FALSE;
CollectNewLoadedModules();
}
#endif
PRBool gotMessage = PR_FALSE;
do {

View File

@ -56,6 +56,9 @@ public:
#endif
protected:
#if defined(_MSC_VER) && defined(_M_IX86)
NS_IMETHOD Run();
#endif
virtual void ScheduleNativeEventCallback();
virtual PRBool ProcessNextNativeEvent(PRBool mayWait);
virtual ~nsAppShell();

View File

@ -558,3 +558,12 @@ NS_ErrorAccordingToNSPR()
////////////////////////////////////////////////////////////////////////////////
#ifdef XP_WIN
NS_COM PRBool sXPCOMHasLoadedNewDLLs = PR_FALSE;
NS_EXPORT void
NS_SetHasLoadedNewDLLs()
{
sXPCOMHasLoadedNewDLLs = PR_TRUE;
}
#endif

View File

@ -330,4 +330,9 @@ NS_ErrorAccordingToNSPR();
#pragma warning(disable: 4275) /* non dll-interface class 'nsISupports' used as base for dll-interface class 'nsIRDFNode' */
#endif
#ifdef XP_WIN
extern NS_COM PRBool sXPCOMHasLoadedNewDLLs;
NS_EXPORT void NS_SetHasLoadedNewDLLs();
#endif
#endif

View File

@ -286,6 +286,8 @@ void XXXNeverCalled()
nsXPCOMCycleCollectionParticipant();
nsCycleCollector_collect();
sXPCOMHasLoadedNewDLLs = !sXPCOMHasLoadedNewDLLs;
NS_SetHasLoadedNewDLLs();
#if !defined(XP_OS2)
NS_NewWindowsRegKey(nsnull);