kernel/eka/nkern/win32/ncsched.cpp
branchRCL_3
changeset 21 e7d2d738d3c2
parent 0 a41df078684a
equal deleted inserted replaced
20:597aaf25e343 21:e7d2d738d3c2
   833 // deferred.
   833 // deferred.
   834 //
   834 //
   835 
   835 
   836 #include <winnt.h>
   836 #include <winnt.h>
   837 
   837 
       
   838 // Uncomment the following line to turn on tracing when we examine the call stack
       
   839 // #define DUMP_STACK_BACKTRACE
       
   840 
       
   841 #ifdef DUMP_STACK_BACKTRACE
       
   842 
       
   843 #include <psapi.h>
       
   844 
       
   845 typedef BOOL (WINAPI GMIFunc)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb);
       
   846 typedef BOOL (WINAPI EPMFunc)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded);
       
   847 typedef DWORD (WINAPI GMBNFunc)(HANDLE hProcess, HMODULE hModule, LPSTR lpBaseName, DWORD nSize);
       
   848 
       
   849 void PrintAllModuleInfo()
       
   850 	{
       
   851 	HMODULE psapiLibrary = LoadLibraryA("psapi.dll");
       
   852 	__NK_ASSERT_ALWAYS(psapiLibrary != NULL);
       
   853 
       
   854 	EPMFunc* epmFunc = (EPMFunc*)GetProcAddress(psapiLibrary, "EnumProcessModules");
       
   855 	__NK_ASSERT_ALWAYS(epmFunc != NULL);
       
   856 	
       
   857 	GMIFunc* gmiFunc = (GMIFunc*)GetProcAddress(psapiLibrary, "GetModuleInformation");
       
   858 	__NK_ASSERT_ALWAYS(gmiFunc != NULL);
       
   859 	
       
   860 	GMBNFunc* gmbnFunc = (GMBNFunc*)GetProcAddress(psapiLibrary, "GetModuleBaseNameA");
       
   861 	__NK_ASSERT_ALWAYS(gmbnFunc != NULL);
       
   862 
       
   863 	const TInt maxModules = 256;
       
   864 	HMODULE modules[maxModules];
       
   865 
       
   866 	DWORD spaceNeeded;
       
   867 	BOOL r = epmFunc(GetCurrentProcess(), modules, sizeof(HMODULE) * maxModules, &spaceNeeded);
       
   868 	__NK_ASSERT_ALWAYS(r);
       
   869 	__NK_ASSERT_ALWAYS(spaceNeeded <= sizeof(HMODULE) * maxModules);
       
   870 
       
   871 	for (TUint i = 0 ; i < spaceNeeded / sizeof(HMODULE) ; ++i)
       
   872 		{
       
   873 		HMODULE library = modules[i];
       
   874 		
       
   875 		const TUint maxNameLen = 64;
       
   876 		char name[maxNameLen];
       
   877 		WORD len = gmbnFunc(GetCurrentProcess(), library, name, sizeof(name));
       
   878 		__NK_ASSERT_ALWAYS(len > 0 && len < maxNameLen);
       
   879 		
       
   880 		MODULEINFO info;
       
   881 		r = gmiFunc(GetCurrentProcess(), library, &info, sizeof(info));
       
   882 		__NK_ASSERT_ALWAYS(r);
       
   883 		
       
   884 		DEBUGPRINT("Module %s found at %08x to %08x", name, (TUint)info.lpBaseOfDll, (TUint)info.lpBaseOfDll + info.SizeOfImage);
       
   885 		}
       
   886 
       
   887 	r = FreeLibrary(psapiLibrary);
       
   888 	__NK_ASSERT_ALWAYS(r);
       
   889 	}
       
   890 
       
   891 #endif
       
   892 
   838 const TInt KWin32NonPreemptibleFunctionCount = 2;
   893 const TInt KWin32NonPreemptibleFunctionCount = 2;
   839 
   894 
   840 struct TWin32FunctionInfo
   895 struct TWin32FunctionInfo
   841 	{
   896 	{
   842 	TUint iStartAddr;
   897 	TUint iStartAddr;
   843 	TUint iLength;
   898 	TUint iLength;
   844 	};
   899 	};
   845 
   900 
   846 static TWin32FunctionInfo Win32NonPreemptibleFunctions[KWin32NonPreemptibleFunctionCount];
   901 static TWin32FunctionInfo Win32NonPreemptibleFunctions[KWin32NonPreemptibleFunctionCount];
   847 
   902 
   848 TWin32FunctionInfo Win32FindExportedFunction(const char* aModuleName, const char* aFunctionName)
   903 HMODULE GetFirstLoadedModuleHandleA(const char* aModuleName1, const char* aModuleName2)
   849 	{
   904 	{
   850 	HMODULE library = GetModuleHandleA(aModuleName);
   905 	HMODULE result = GetModuleHandleA(aModuleName1);
       
   906 	return result ? result : GetModuleHandleA(aModuleName2);
       
   907 	}
       
   908 
       
   909 TWin32FunctionInfo Win32FindExportedFunction(const char* aFunctionName, ...)
       
   910 	{
       
   911 	const char *libname;
       
   912 	HMODULE library = NULL;
       
   913 
       
   914 	va_list arg;
       
   915 	va_start(arg, aFunctionName);
       
   916 
       
   917 	// Loop through arguments until we find a library we can get a handle to.  List of library names
       
   918 	// is NULL-terminated.
       
   919 	while ((libname = va_arg(arg, const char *)) != NULL)
       
   920 		{
       
   921 		library = GetModuleHandleA(libname);
       
   922 		if (library != NULL)
       
   923 			break;
       
   924 		}
       
   925 
       
   926 	va_end(arg);
       
   927 
       
   928 	// Make sure we did get a valid library
   851 	__NK_ASSERT_ALWAYS(library != NULL);
   929 	__NK_ASSERT_ALWAYS(library != NULL);
   852 
   930 	
   853 	// Find the start address of the function
   931 	// Find the start address of the function
   854 	TUint start = (TUint)GetProcAddress(library, aFunctionName);
   932 	TUint start = (TUint)GetProcAddress(library, aFunctionName);
   855 	__NK_ASSERT_ALWAYS(start);
   933 	__NK_ASSERT_ALWAYS(start != 0);
   856 
   934 
   857 	// Now have to check all other exports to find the end of the function
   935 	// Now have to check all other exports to find the end of the function
   858 	TUint end = 0xffffffff;
   936 	TUint end = 0xffffffff;
   859 	TInt i = 1;
   937 	TInt i = 1;
   860 	for (;;)
   938 	for (;;)
   865 		if (addr > start && addr < end)
   943 		if (addr > start && addr < end)
   866 			end = addr;
   944 			end = addr;
   867 		++i;
   945 		++i;
   868 		}
   946 		}
   869 	__NK_ASSERT_ALWAYS(end != 0xffffffff);
   947 	__NK_ASSERT_ALWAYS(end != 0xffffffff);
   870 
   948 	
   871 	TWin32FunctionInfo result = { start, end - start };
   949 	TWin32FunctionInfo result = { start, end - start };
       
   950 	
       
   951 #ifdef DUMP_STACK_BACKTRACE
       
   952 	DEBUGPRINT("Function %s found at %08x to %08x", aFunctionName, start, end);
       
   953 #endif
       
   954 	
   872 	return result;
   955 	return result;
   873 	}
   956 	}
   874 
   957 
   875 void Win32FindNonPreemptibleFunctions()
   958 void Win32FindNonPreemptibleFunctions()
   876 	{
   959 	{
   877 	Win32NonPreemptibleFunctions[0] = Win32FindExportedFunction("kernel32.dll", "RaiseException");
   960 #ifdef DUMP_STACK_BACKTRACE
   878 	Win32NonPreemptibleFunctions[1] = Win32FindExportedFunction("ntdll.dll", "KiUserExceptionDispatcher");
   961 	PrintAllModuleInfo();
       
   962 #endif
       
   963 
       
   964 	TUint i = 0;
       
   965 	Win32NonPreemptibleFunctions[i++] = Win32FindExportedFunction("RaiseException", "kernelbase.dll", "kernel32.dll", NULL);
       
   966 	Win32NonPreemptibleFunctions[i++] = Win32FindExportedFunction("KiUserExceptionDispatcher", "ntdll.dll", NULL);
       
   967 	__NK_ASSERT_ALWAYS(i == KWin32NonPreemptibleFunctionCount);
   879 	}
   968 	}
   880 	
   969 	
   881 TBool Win32IsThreadInNonPreemptibleFunction(HANDLE aWinThread, TLinAddr aStackTop)
   970 TBool Win32IsThreadInNonPreemptibleFunction(HANDLE aWinThread, TLinAddr aStackTop)
   882 	{
   971 	{
   883 	const TInt KMaxSearchDepth = 16;		 // 12 max observed while handling exceptions
   972 	const TInt KMaxSearchDepth = 16;		 // 12 max observed while handling exceptions
   890 
   979 
   891 	TUint eip = c.Eip;
   980 	TUint eip = c.Eip;
   892 	TUint ebp = c.Ebp;
   981 	TUint ebp = c.Ebp;
   893 	TUint lastEbp = c.Esp;
   982 	TUint lastEbp = c.Esp;
   894 
   983 
       
   984 	#ifdef DUMP_STACK_BACKTRACE
       
   985 	DEBUGPRINT("Stack backtrace for thread %x", aWinThread);
       
   986 	#endif	
       
   987 
   895 	// Walk the call stack
   988 	// Walk the call stack
   896 	for (TInt i = 0 ; i < KMaxSearchDepth ; ++i)
   989 	for (TInt i = 0 ; i < KMaxSearchDepth ; ++i)
   897 		{
   990 		{
       
   991 		#ifdef DUMP_STACK_BACKTRACE
       
   992 		DEBUGPRINT("  %08x", eip);
       
   993 		#endif
       
   994 		
   898 		for (TInt j = 0 ; j < KWin32NonPreemptibleFunctionCount ; ++j)
   995 		for (TInt j = 0 ; j < KWin32NonPreemptibleFunctionCount ; ++j)
   899 			{
   996 			{
   900 			const TWin32FunctionInfo& info = Win32NonPreemptibleFunctions[j];
   997 			const TWin32FunctionInfo& info = Win32NonPreemptibleFunctions[j];
   901 			if (TUint(eip - info.iStartAddr) < info.iLength)
   998 			if (TUint(eip - info.iStartAddr) < info.iLength)
   902 				{
   999 				{