From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=17.151.62.27; helo=mail-in5.apple.com; envelope-from=afish@apple.com; receiver=edk2-devel@lists.01.org Received: from mail-in5.apple.com (mail-out5.apple.com [17.151.62.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 35467220D4BEB for ; Tue, 14 Nov 2017 05:57:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; d=apple.com; s=mailout2048s; c=relaxed/simple; q=dns/txt; i=@apple.com; t=1510668068; h=From:Sender:Reply-To:Subject:Date:Message-id:To:Cc:MIME-version:Content-type: Content-transfer-encoding:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-reply-to:References:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=vs2vV0ecVGYQELX7cdeT0PmVzBzmgjOZlHRddWGuo1s=; b=T8XrTUbI6TNlcB9QX63bF+28490P74azxDJx35oadIYdbceFn0Fd/TiUYn08FSfl JIB6vvcfsh+eP5ly1+aJErGckYPX/Fs+udAnee9VhzcPfBK9+i55MFDRkrc/ObRs LTHULwpj6oFROnQDt3VqA2yiZaaC+5L9tgeb8uHZo1AkHng+VK5IhWnFR1FzlQMB CsglCEc89PkqG9A6kYV28WxFKATmOFfjmqhqiyQRGar12grczJQO8JBB9yYpKNk5 xmzCQxrUQOylMr6p5NB3JI1C79Rwpzl67Haa7gOGyeUmv26TgEIi8b+8bvdSEjVb Jc9Pccm5EWy7W65r9eoR5g==; Received: from relay6.apple.com (relay6.apple.com [17.128.113.90]) (using TLS with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mail-in5.apple.com (Apple Secure Mail Relay) with SMTP id 14.16.23913.427FA0A5; Tue, 14 Nov 2017 06:01:08 -0800 (PST) X-AuditID: 11973e13-c5d259c000005d69-5d-5a0af724d34f Received: from nwk-mmpp-sz12.apple.com (nwk-mmpp-sz12.apple.com [17.128.115.204]) by relay6.apple.com (Apple SCV relay) with SMTP id C5.17.05652.427FA0A5; Tue, 14 Nov 2017 06:01:08 -0800 (PST) MIME-version: 1.0 Received: from [17.234.126.199] by nwk-mmpp-sz12.apple.com (Oracle Communications Messaging Server 8.0.1.3.20170825 64bit (built Aug 25 2017)) with ESMTPSA id <0OZE004ZYUXV2980@nwk-mmpp-sz12.apple.com>; Tue, 14 Nov 2017 06:01:08 -0800 (PST) Sender: afish@apple.com From: Andrew Fish In-reply-to: <00e14f85d93a2e81ab008f32020f3048fe4857fb.1510662518.git.pcacjr@zytor.com> Date: Tue, 14 Nov 2017 06:01:08 -0800 Cc: edk2-devel@lists.01.org, Laszlo Ersek , Eric Dong Message-id: References: <00e14f85d93a2e81ab008f32020f3048fe4857fb.1510662518.git.pcacjr@zytor.com> To: Paulo Alcantara X-Mailer: Apple Mail (2.3273) X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrPLMWRmVeSWpSXmKPExsUi2FAYpavynSvK4PxEEYs9h44yW2x+EWyx 7NgOFot9rz8yOrB4LN7zksmje/Y/Fo/3+66yeZxo+cIawBLFZZOSmpNZllqkb5fAlXH+6SL2 grfBFfMeTWVvYFxr3cXIySEhYCLx4NQi1i5GLg4hgdVMEu3b17LAJI7M7WaGSBxilNj5sJ8d JMErICjxY/I9oCIODmYBeYmD52VBwswCWhLfH7WyQNR/Y5S4MPcpG0hCWEBc4t2ZTcwQdpzE q//HwBawCShLrJj/AWwmp0CkxJzrM1lBbBYBVYl1i98xQwxNkGho2sYCsddGYvPSv2wQC1Yx SvxcvhWsWURATeLynrusEFfLStyafQnsagmBBWwSr/a/YZzAKDwLyeGzEA6fheTwBYzMqxiF chMzc3Qz80z1EgsKclL1kvNzNzGCYmC6nfAOxtOrrA4xCnAwKvHwOlzhjBJiTSwrrsw9xCjN waIkzpv2iiFKSCA9sSQ1OzW1ILUovqg0J7X4ECMTB6dUA+NSKzver5uVW1OFt7ruqc9jc77f v2iaj6nEteZlj9ZVTThW805mb9ecMvm4j4EZ/Wc2ZFyY+F5YNF9oz+GvG3JWrt7y7+S7SNEF lzY0LWBNXe/70Ozm1T3zPQX9j7x3n81jv3LqcYNXmsaLN4fu+1h22X5FZm0TV5rKhHiepZ0v j2exGii+3iCqxFKckWioxVxUnAgAVZGF7GICAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrELMWRmVeSWpSXmKPExsUi2FB8RlflO1eUwa9WAYs9h44yW2x+EWyx 7NgOFot9rz8yOrB4LN7zksmje/Y/Fo/3+66yeZxo+cIawBLFZZOSmpNZllqkb5fAlXH+6SL2 grfBFfMeTWVvYFxr3cXIySEhYCJxZG43cxcjF4eQwCFGiZ0P+9lBErwCghI/Jt9j6WLk4GAW kJc4eF4WJMwsoCXx/VErC0T9N0aJC3OfsoEkhAXEJd6d2cQMYcdJvPp/jAXEZhNQllgx/wPY TE6BSIk512eygtgsAqoS6xa/Y4YYmiDR0LSNBWKvjcTmpX/ZIBasYpT4uXwrWLOIgJrE5T13 WSGulpW4NfsS8wRGgVlIbp2FcOssJLcuYGRexShQlJqTWGmml1hQkJOql5yfu4kRHLKFUTsY G5ZbHWIU4GBU4uF9eZEzSog1say4MhcYGBzMSiK8O2dxRQnxpiRWVqUW5ccXleakFh9ilOZg URLn1RMBSgmkJ5akZqemFqQWwWSZODilGhj5BG8a7WPhUFZUn3Nhy+rVChpii385fQ+9kyt8 7t0uLY8LfO3/Ooy2B948Fnoqr3NTzePgxS2uKvyiPpvDF0qc1b/564DPx+qHlczL3s7RWB7T I7ea0/f1RbXMBv8bRZ99Nl5/JmnamC+v8ikh5hHT9z+en3tju/psJy3tjfzvsKyt/5Fm/wQl luKMREMt5qLiRADwkV8pVQIAAA== Subject: Re: [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Nov 2017 13:57:02 -0000 Content-transfer-encoding: 7BIT Content-type: text/plain; CHARSET=US-ASCII Paulo, Cool feature. How does this code deal with VC++ that code does not store the frame pointer and requires symbols to unwind. Also on the page fault you can print the fault address since it is in CR2. It should be possible to post process the text file and make a symbolicated backtrace. Thanks, Andrew Fish > On Nov 14, 2017, at 4:47 AM, Paulo Alcantara wrote: > > This patch adds stack trace support during a X64 CPU exception. > > It will dump out back trace, stack contents as well as image module > names that were part of the call stack. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Cc: Eric Dong > Cc: Laszlo Ersek > Signed-off-by: Paulo Alcantara > --- > UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 344 +++++++++++++++++++- > 1 file changed, 342 insertions(+), 2 deletions(-) > > diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c > index 65f0cff680..7048247be3 100644 > --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c > +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c > @@ -14,6 +14,11 @@ > > #include "CpuExceptionCommon.h" > > +// > +// Unknown PDB file name > +// > +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = "????"; > + > /** > Return address map of exception handler template so that C code can generate > exception tables. > @@ -243,6 +248,325 @@ DumpCpuContext ( > } > > /** > + Dump stack contents. > + > + @param[in] ImageBase Base address of PE/COFF image. > + @param[out] PdbAbsoluteFilePath Absolute path of PDB file. > + @param[out] PdbFileName File name of PDB file. > +**/ > +STATIC > +VOID > +GetPdbFileName ( > + IN UINTN ImageBase, > + OUT CHAR8 **PdbAbsoluteFilePath, > + OUT CHAR8 **PdbFileName > + ) > +{ > + VOID *PdbPointer; > + CHAR8 *Str; > + > + // > + // Get PDB file name from PE/COFF image > + // > + PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)ImageBase); > + if (PdbPointer == NULL) { > + // > + // No PDB file name found. Set it to an unknown file name. > + // > + *PdbFileName = (CHAR8 *)mUnknownPdbFileName; > + if (PdbAbsoluteFilePath != NULL) { > + *PdbAbsoluteFilePath = NULL; > + } > + } else { > + // > + // Get file name portion out of PDB file in PE/COFF image > + // > + Str = (CHAR8 *)((UINTN)PdbPointer + > + AsciiStrLen ((CHAR8 *)PdbPointer) - sizeof *Str); > + for (; *Str != '/' && *Str != '\\'; Str--) { > + ; > + } > + > + // > + // Set PDB file name (also skip trailing path separator: '/' or '\\') > + // > + *PdbFileName = Str + 1; > + > + if (PdbAbsoluteFilePath != NULL) { > + // > + // Set absolute file path of PDB file > + // > + *PdbAbsoluteFilePath = PdbPointer; > + } > + } > +} > + > +/** > + Dump stack contents. > + > + @param[in] CurrentRsp Current stack pointer address. > + @param[in] UnwondStacksCount Count of unwond stack frames. > +**/ > +STATIC > +VOID > +DumpStackContents ( > + IN UINT64 CurrentRsp, > + IN INTN UnwondStacksCount > + ) > +{ > + if (UnwondStacksCount == 0) { > + return; > + } > + > + // > + // Dump out stack contents > + // > + InternalPrintMessage ("\nStack dump:\n"); > + while (UnwondStacksCount-- > 0) { > + InternalPrintMessage ( > + "0x%016lx: %016lx %016lx\n", > + CurrentRsp, > + *(UINT64 *)CurrentRsp, > + *(UINT64 *)((UINTN)CurrentRsp + 8) > + ); > + > + // > + // As per Microsoft x64 ABI, the stack pointer must be aligned on a 16 byte > + // boundary. > + // > + CurrentRsp = CurrentRsp + 16; > + } > +} > + > +/** > + Dump all image module names from call stack. > + > + @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. > +**/ > +STATIC > +VOID > +DumpImageModuleNames ( > + IN EFI_SYSTEM_CONTEXT SystemContext > + ) > +{ > + EFI_STATUS Status; > + UINT64 Rip; > + UINTN ImageBase; > + VOID *EntryPoint; > + CHAR8 *PdbAbsoluteFilePath; > + CHAR8 *PdbFileName; > + UINT64 Rbp; > + > + // > + // Set current RIP address > + // > + Rip = SystemContext.SystemContextX64->Rip; > + > + // > + // Set current frame pointer address > + // > + Rbp = SystemContext.SystemContextX64->Rbp; > + > + // > + // Get initial PE/COFF image base address from current RIP > + // > + ImageBase = PeCoffSearchImageBase (Rip); > + if (ImageBase == 0) { > + InternalPrintMessage ("!!!! Could not find image module names. !!!!"); > + return; > + } > + > + // > + // Get initial PE/COFF image's entry point > + // > + Status = PeCoffLoaderGetEntryPoint ((VOID *)ImageBase, &EntryPoint); > + if (EFI_ERROR (Status)) { > + EntryPoint = NULL; > + } > + > + // > + // Get file name and absolute path of initial PDB file > + // > + GetPdbFileName (ImageBase, &PdbAbsoluteFilePath, &PdbFileName); > + > + // > + // Print out initial image module name (if any) > + // > + if (PdbAbsoluteFilePath != NULL) { > + InternalPrintMessage ( > + "\n%a (ImageBase=0x%016lx, EntryPoint=0x%016lx):\n", > + PdbFileName, > + ImageBase, > + (UINTN)EntryPoint > + ); > + InternalPrintMessage ("%a\n", PdbAbsoluteFilePath); > + } > + > + // > + // Walk through call stack and find next module names > + // > + for (;;) { > + // > + // Set RIP with return address from current stack frame > + // > + Rip = *(UINT64 *)((UINTN)Rbp + 8); > + > + // > + // Check if RIP is within another PE/COFF image base address > + // > + if (Rip < ImageBase) { > + // > + // Search for the respective PE/COFF image based on RIP > + // > + ImageBase = PeCoffSearchImageBase (Rip); > + if (ImageBase == 0) { > + // > + // Stop stack trace > + // > + break; > + } > + > + // > + // Get PE/COFF image's entry point > + // > + Status = PeCoffLoaderGetEntryPoint ((VOID *)ImageBase, &EntryPoint); > + if (EFI_ERROR (Status)) { > + EntryPoint = NULL; > + } > + > + // > + // Get file name and absolute path of PDB file > + // > + GetPdbFileName (ImageBase, &PdbAbsoluteFilePath, &PdbFileName); > + > + // > + // Print out image module name (if any) > + // > + if (PdbAbsoluteFilePath != NULL) { > + InternalPrintMessage ( > + "%a (ImageBase=0x%016lx, EntryPoint=0x%016lx):\n", > + PdbFileName, > + ImageBase, > + (UINTN)EntryPoint > + ); > + InternalPrintMessage ("%a\n", PdbAbsoluteFilePath); > + } > + } > + > + // > + // Unwind the stack > + // > + Rbp = *(UINT64 *)(UINTN)Rbp; > + } > +} > + > +/** > + Dump stack trace. > + > + @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. > + @param[out] UnwondStacksCount Count of unwond stack frames. > +**/ > +STATIC > +VOID > +DumpStackTrace ( > + IN EFI_SYSTEM_CONTEXT SystemContext, > + OUT INTN *UnwondStacksCount > + ) > +{ > + UINT64 Rip; > + UINT64 Rbp; > + UINTN ImageBase; > + CHAR8 *PdbFileName; > + > + // > + // Initialize count of unwond stacks > + // > + *UnwondStacksCount = 0; > + > + // > + // Set current RIP address > + // > + Rip = SystemContext.SystemContextX64->Rip; > + > + // > + // Set current frame pointer address > + // > + Rbp = SystemContext.SystemContextX64->Rbp; > + > + // > + // Get initial PE/COFF image base address from current RIP > + // > + ImageBase = PeCoffSearchImageBase (Rip); > + if (ImageBase == 0) { > + InternalPrintMessage ("!!!! Could not find backtrace information. !!!!"); > + return; > + } > + > + // > + // Get PDB file name from initial PE/COFF image > + // > + GetPdbFileName (ImageBase, NULL, &PdbFileName); > + > + // > + // Print out back trace > + // > + InternalPrintMessage ("\nBack trace:\n"); > + > + for (;;) { > + // > + // Print stack frame in the following format: > + // > + // # @ + (RBP) in [ | ????] > + // > + InternalPrintMessage ( > + "%d 0x%016lx @ 0x%016lx+0x%x (0x%016lx) in %a\n", > + *UnwondStacksCount, > + Rip, > + ImageBase, > + Rip - ImageBase - 1, > + Rbp, > + PdbFileName > + ); > + > + // > + // Set RIP with return address from current stack frame > + // > + Rip = *(UINT64 *)((UINTN)Rbp + 8); > + > + // > + // Check if RIP is within another PE/COFF image base address > + // > + if (Rip < ImageBase) { > + // > + // Search for the respective PE/COFF image based on RIP > + // > + ImageBase = PeCoffSearchImageBase (Rip); > + if (ImageBase == 0) { > + // > + // Stop stack trace > + // > + break; > + } > + > + // > + // Get PDB file name > + // > + GetPdbFileName (ImageBase, NULL, &PdbFileName); > + } > + > + // > + // Unwind the stack > + // > + Rbp = *(UINT64 *)(UINTN)Rbp; > + > + // > + // Increment count of unwond stacks > + // > + (*UnwondStacksCount)++; > + } > +} > + > +/** > Display CPU information. > > @param ExceptionType Exception type. > @@ -254,9 +578,25 @@ DumpImageAndCpuContent ( > IN EFI_SYSTEM_CONTEXT SystemContext > ) > { > + INTN UnwondStacksCount; > + > + // > + // Dump CPU context > + // > DumpCpuContext (ExceptionType, SystemContext); > + > + // > + // Dump stack trace > + // > + DumpStackTrace (SystemContext, &UnwondStacksCount); > + > + // > + // Dump image module names > + // > + DumpImageModuleNames (SystemContext); > + > // > - // Dump module image base and module entry point by RIP > + // Dump stack contents > // > - DumpModuleImageInfo (SystemContext.SystemContextX64->Rip); > + DumpStackContents (SystemContext.SystemContextX64->Rsp, UnwondStacksCount); > } > -- > 2.11.0 > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel