From be175a2797bebf709760f872a2f0b4b39c2e0b4f Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 31 Oct 2007 14:41:27 +0000 Subject: [PATCH] - Dispatch all symbol loads to a single function, which determines type of passed name, and calls worker function. - Print source file:line in stack traces if possible, when KDBG is enabled - if KDBG is not defined, behaviour of the mainstream code is completely untouched. svn path=/trunk/; revision=30014 --- reactos/ntoskrnl/include/internal/kd.h | 9 ++- reactos/ntoskrnl/kdbg/kdb_symbols.c | 100 +++++++++++++++++++++---- reactos/ntoskrnl/ke/bug.c | 10 ++- reactos/ntoskrnl/mm/sysldr.c | 5 ++ 4 files changed, 105 insertions(+), 19 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/kd.h b/reactos/ntoskrnl/include/internal/kd.h index 053205ae529..d5c450a190f 100644 --- a/reactos/ntoskrnl/include/internal/kd.h +++ b/reactos/ntoskrnl/include/internal/kd.h @@ -84,7 +84,12 @@ VOID KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject); VOID -KdbSymProcessBootSymbols(IN PANSI_STRING FileName); +KdbSymProcessBootSymbols(IN PANSI_STRING AnsiFileName, + IN BOOLEAN FullName, + IN BOOLEAN LoadFromFile); + +VOID +KdbSymProcessSymbols(IN PANSI_STRING FileName); BOOLEAN KdbSymPrintAddress(IN PVOID Address); @@ -114,7 +119,7 @@ typedef struct _KDB_MODULE_INFO # define KDB_LOADUSERMODULE_HOOK(LDRMOD) KdbSymLoadUserModuleSymbols(LDRMOD) # define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) KdbSymLoadDriverSymbols(FILENAME, MODULE) # define KDB_UNLOADDRIVER_HOOK(MODULE) KdbSymUnloadDriverSymbols(MODULE) -# define KDB_SYMBOLFILE_HOOK(FILENAME) KdbSymProcessBootSymbols(FILENAME) +# define KDB_SYMBOLFILE_HOOK(FILENAME) KdbSymProcessSymbols(FILENAME) #else # define KDB_LOADUSERMODULE_HOOK(LDRMOD) do { } while (0) # define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) do { } while (0) diff --git a/reactos/ntoskrnl/kdbg/kdb_symbols.c b/reactos/ntoskrnl/kdbg/kdb_symbols.c index 847e6942db3..032dbc67bb0 100644 --- a/reactos/ntoskrnl/kdbg/kdb_symbols.c +++ b/reactos/ntoskrnl/kdbg/kdb_symbols.c @@ -442,7 +442,7 @@ KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName, FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) { - DPRINT("Could not open image file: %wZ\n", &FileName); + DPRINT("Could not open image file: %wZ\n", FileName); return; } @@ -577,6 +577,54 @@ KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject) ModuleObject->PatchInformation = NULL; } +VOID +KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName) +{ + ANSI_STRING SystemPrefix, RealPathPrefix, ProperName; + CHAR Buffer[MAX_PATH], RealPathBuffer[MAX_PATH]; + + /* Init our strings for compare operations */ + RtlInitAnsiString(&SystemPrefix, "\\SystemRoot"); + + /* Convert system root to ansi */ + sprintf(RealPathBuffer, "%S", (PWCHAR)&SharedUserData->NtSystemRoot[2]); + RtlInitAnsiString(&RealPathPrefix, RealPathBuffer); + RealPathPrefix.MaximumLength = MAX_PATH; + + /* There are 3 cases: + 1) \SystemRoot\System32\ -> no change + 2) \ReactOS\System32 -> \SystemRoot\System32 + 3) module.dll -> \??\C:\ReactOS\system32\module.dll + */ + if (RtlPrefixString(&SystemPrefix, AnsiFileName, FALSE)) + { + /* Case: \SystemRoot\System32\ , just directly load it */ + KdbSymProcessBootSymbols(AnsiFileName, TRUE, FALSE); + } + else if (RtlPrefixString(&RealPathPrefix, AnsiFileName, FALSE)) + { + /* It's prefixed with a real path, instead of a \SystemRoot. + So build a new, proper name. */ + RtlZeroMemory(Buffer, MAX_PATH); + strcpy(Buffer, "\\SystemRoot"); + strncat(Buffer, + AnsiFileName->Buffer + RealPathPrefix.Length, + AnsiFileName->Length - RealPathPrefix.Length); + + /* Convert it to ANSI_STRING */ + RtlInitAnsiString(&ProperName, Buffer); + + /* Process symbols */ + KdbSymProcessBootSymbols(&ProperName, TRUE, TRUE); + } + else + { + /* Just a bare filename, nothing else. Why? Who knows... */ + KdbSymProcessBootSymbols(AnsiFileName, FALSE, TRUE); + } +} + + /*! \brief Called when a symbol file is loaded by the loader? * * Tries to find a driver (.sys) or executable (.exe) with the same base name @@ -587,7 +635,9 @@ KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject) * \param FileName Filename for which the symbols are loaded. */ VOID -KdbSymProcessBootSymbols(IN PANSI_STRING AnsiFileName) +KdbSymProcessBootSymbols(IN PANSI_STRING AnsiFileName, + IN BOOLEAN FullName, + IN BOOLEAN LoadFromFile) { BOOLEAN Found = FALSE; PLIST_ENTRY ListHead, NextEntry; @@ -624,10 +674,21 @@ KdbSymProcessBootSymbols(IN PANSI_STRING AnsiFileName) LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - if (RtlEqualUnicodeString(&ModuleName, &LdrEntry->FullDllName, TRUE)) + if (FullName) { - Found = TRUE; - break; + if (RtlEqualUnicodeString(&ModuleName, &LdrEntry->FullDllName, TRUE)) + { + Found = TRUE; + break; + } + } + else + { + if (RtlEqualUnicodeString(&ModuleName, &LdrEntry->BaseDllName, TRUE)) + { + Found = TRUE; + break; + } } /* Go to the next one */ @@ -651,17 +712,26 @@ KdbSymProcessBootSymbols(IN PANSI_STRING AnsiFileName) KdbpSymRemoveCachedFile(LdrEntry->PatchInformation); } - /* Load new symbol information */ - if (! RosSymCreateFromMem(LdrEntry->DllBase, - LdrEntry->SizeOfImage, - (PROSSYM_INFO*)&LdrEntry->PatchInformation)) + if (LoadFromFile) { - /* Error loading symbol info, exit */ - return; + /* Load symbol info from file */ + KdbpSymLoadModuleSymbols(&LdrEntry->FullDllName, + (PROSSYM_INFO*)&LdrEntry->PatchInformation); } + else + { + /* Load new symbol information */ + if (! RosSymCreateFromMem(LdrEntry->DllBase, + LdrEntry->SizeOfImage, + (PROSSYM_INFO*)&LdrEntry->PatchInformation)) + { + /* Error loading symbol info, exit */ + return; + } - /* Add file to cache */ - KdbpSymAddCachedFile(&ModuleName, LdrEntry->PatchInformation); + /* Add file to cache */ + KdbpSymAddCachedFile(&ModuleName, LdrEntry->PatchInformation); + } DPRINT("Installed symbols: %wZ@%08x-%08x %p\n", &ModuleName, @@ -767,9 +837,9 @@ KdbInitialize(PKD_DISPATCH_TABLE DispatchTable, /* FIXME: Load as 1st and 2nd entries of InLoadOrderList instead of hardcoding them here! */ RtlInitAnsiString(&FileName, "\\SystemRoot\\System32\\NTOSKRNL.EXE"); - KdbSymProcessBootSymbols(&FileName); + KdbSymProcessBootSymbols(&FileName, TRUE, FALSE); RtlInitAnsiString(&FileName, "\\SystemRoot\\System32\\HAL.DLL"); - KdbSymProcessBootSymbols(&FileName); + KdbSymProcessBootSymbols(&FileName, TRUE, FALSE); } } diff --git a/reactos/ntoskrnl/ke/bug.c b/reactos/ntoskrnl/ke/bug.c index 010e380daaa..7c6a2ffa38d 100644 --- a/reactos/ntoskrnl/ke/bug.c +++ b/reactos/ntoskrnl/ke/bug.c @@ -290,8 +290,14 @@ KeRosDumpStackFrames(IN PULONG Frame OPTIONAL, if (KiRosPcToUserFileHeader((PVOID)Addr, &LdrEntry)) { /* Print out the module name */ - Addr -= (ULONG_PTR)LdrEntry->DllBase; - DbgPrint("<%wZ: %x>", &LdrEntry->FullDllName, Addr); +#ifdef KDBG + if (!KdbSymPrintAddress((PVOID)Addr)) +#endif + { + /* Fall back to usual printing */ + Addr -= (ULONG_PTR)LdrEntry->DllBase; + DbgPrint("<%wZ: %x>", &LdrEntry->FullDllName, Addr); + } } else if (Addr) { diff --git a/reactos/ntoskrnl/mm/sysldr.c b/reactos/ntoskrnl/mm/sysldr.c index d24c446c0e6..b79cd61add6 100644 --- a/reactos/ntoskrnl/mm/sysldr.c +++ b/reactos/ntoskrnl/mm/sysldr.c @@ -1860,7 +1860,12 @@ LoaderScan: } /* Check if there's symbols */ +#ifdef KDBG + /* If KDBG is defined, then we always have symbols */ + if (TRUE) +#else if (MiCacheImageSymbols(LdrEntry->DllBase)) +#endif { /* Check if the system root is present */ if ((PrefixName.Length > (11 * sizeof(WCHAR))) &&