From: Andrew Fish <afish@apple.com>
To: Fan Jeff <vanjeff_919@hotmail.com>
Cc: Paulo Alcantara <pcacjr@zytor.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
Laszlo Ersek <lersek@redhat.com>, Eric Dong <eric.dong@intel.com>
Subject: Re: [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
Date: Tue, 14 Nov 2017 06:38:02 -0800 [thread overview]
Message-ID: <1AA80444-D1BB-405F-8C2D-E9EF5FE62285@apple.com> (raw)
In-Reply-To: <CY1PR19MB0283031D0B48FE0FFFC4CB4CD7280@CY1PR19MB0283.namprd19.prod.outlook.com>
> On Nov 14, 2017, at 6:26 AM, Fan Jeff <vanjeff_919@hotmail.com> wrote:
>
> Andrew,
>
> We could use he EIP offset in Paul’s trace message and work with the generated map file under debug directory for debug trace.
It would also be possible to use gdb.
Given
0 0x000000007E510F7F @ 0x000000007E509000+0x7F7E (0x000000007F762CB0) in PartitionDxe.dll
If you load PartitionDxe.dll into gdb you can then do "l *0x7F7E" to dump the source.
I'm mapping lldb behavior to gdb, but it should be close.
Thanks,
Andrew Fish
>
> Jeff
>
> 发件人: Andrew Fish <mailto:afish@apple.com>
> 发送时间: 2017年11月14日 22:01
> 收件人: Paulo Alcantara <mailto:pcacjr@zytor.com>
> 抄送: edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>; Laszlo Ersek <mailto:lersek@redhat.com>; Eric Dong <mailto:eric.dong@intel.com>
> 主题: Re: [edk2] [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
>
> 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 <pcacjr@zytor.com> 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 <eric.dong@intel.com>
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
> > ---
> > 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:
> > + //
> > + // # <RIP> @ <ImageBase>+<RelOffset> (RBP) in [<ModuleName> | ????]
> > + //
> > + 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 <https://lists.01.org/mailman/listinfo/edk2-devel>
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>
> https://lists.01.org/mailman/listinfo/edk2-devel <https://lists.01.org/mailman/listinfo/edk2-devel>
next prev parent reply other threads:[~2017-11-14 14:33 UTC|newest]
Thread overview: 82+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-14 12:47 [RFC 0/1] Stack trace support in X64 exception handling Paulo Alcantara
2017-11-14 12:47 ` [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support Paulo Alcantara
2017-11-14 14:01 ` Andrew Fish
2017-11-14 14:26 ` 答复: " Fan Jeff
2017-11-14 14:38 ` Andrew Fish [this message]
2017-11-14 15:30 ` Paulo Alcantara
2017-11-14 16:51 ` Brian J. Johnson
2017-12-29 3:48 ` [RFC v4 0/6] Stack trace support in X64 exception handling Paulo Alcantara
2017-12-29 4:39 ` [RFC v4 1/6] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support Paulo Alcantara
2018-01-03 8:53 ` 答复: " Fan Jeff
2018-01-03 14:51 ` Paulo Alcantara
2017-12-29 4:39 ` [RFC v4 2/6] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName() Paulo Alcantara
2017-12-29 4:39 ` [RFC v4 3/6] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support Paulo Alcantara
2017-12-29 4:39 ` [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to valid memory addresses Paulo Alcantara
2018-01-03 8:42 ` 答复: " Fan Jeff
2018-01-03 14:45 ` Paulo Alcantara
2018-01-03 16:59 ` Brian J. Johnson
2018-01-04 13:03 ` Paulo Alcantara
2018-01-04 1:36 ` Yao, Jiewen
2018-01-04 1:58 ` Yao, Jiewen
2018-01-04 13:29 ` Paulo Alcantara
2018-01-04 14:35 ` Yao, Jiewen
2018-01-04 15:15 ` Paulo Alcantara
2018-01-04 13:18 ` Paulo Alcantara
2017-12-29 4:39 ` [RFC v4 5/6] UefiCpuPkg/CpuExceptionHandlerLib: Ensure valid frame/stack pointers Paulo Alcantara
2018-01-03 8:45 ` 答复: " Fan Jeff
2018-01-03 14:48 ` Paulo Alcantara
2018-01-04 1:07 ` Yao, Jiewen
2017-12-29 4:39 ` [RFC v4 6/6] UefiCpuPkg/CpuExceptionHandlerLib: Correctly print IP addresses Paulo Alcantara
2018-01-03 8:46 ` 答复: " Fan Jeff
2018-01-04 0:59 ` [RFC v4 0/6] Stack trace support in X64 exception handling Yao, Jiewen
2018-01-04 13:36 ` Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 0/8] " Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 1/8] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 2/8] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName() Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 3/8] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 4/8] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to validate memory addresses Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 5/8] UefiCpuPkg/CpuExceptionHandlerLib: Ensure valid frame/stack pointers Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 6/8] UefiCpuPkg/CpuExceptionHandlerLib: Correctly print IP addresses Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 7/8] UefiCpuPkg/CpuExceptionHandlerLib: Validate memory address ranges Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 8/8] UefiCpuPkg/CpuExceptionHandlerLib: Add early check in DumpStackContents Paulo Alcantara
2018-01-17 12:57 ` [RFC v5 0/8] Stack trace support in X64 exception handling Yao, Jiewen
2018-01-17 22:48 ` Yao, Jiewen
2018-01-19 0:09 ` Paulo Alcantara
2018-01-19 0:02 ` Paulo Alcantara
2018-01-19 0:15 ` Paulo Alcantara
2018-01-29 13:38 ` Paulo Alcantara
2018-01-31 5:56 ` Yao, Jiewen
2018-01-31 19:05 ` Paulo Alcantara
2017-11-14 13:21 ` [RFC 0/1] " Paulo Alcantara
2017-11-14 14:03 ` 答复: " Fan Jeff
2017-11-14 14:12 ` 答复: " Fan Jeff
2017-11-14 15:37 ` Paulo Alcantara
2017-11-14 16:33 ` Brian J. Johnson
2017-11-14 17:23 ` Andrew Fish
2017-11-14 17:41 ` Brian J. Johnson
2017-11-14 17:56 ` Paulo Alcantara
2017-11-15 13:21 ` 答复: 答复: " Fan Jeff
2017-11-15 14:41 ` Paulo Alcantara
2017-11-15 14:52 ` 答复: " Fan Jeff
2017-11-16 1:18 ` [RFC v2 0/3] " Paulo Alcantara
2017-11-16 1:18 ` [RFC v2 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support Paulo Alcantara
2017-11-16 1:57 ` Yao, Jiewen
2017-11-16 22:13 ` Paulo Alcantara
2017-11-17 3:43 ` Yao, Jiewen
2017-11-20 14:51 ` Paulo Alcantara
2017-11-16 15:43 ` Brian J. Johnson
2017-11-16 22:19 ` Paulo Alcantara
2017-11-16 1:18 ` [RFC v2 2/3] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName() Paulo Alcantara
2017-11-16 1:18 ` [RFC v2 3/3] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support Paulo Alcantara
2017-11-16 1:46 ` [RFC v2 0/3] Stack trace support in X64 exception handling Paulo Alcantara
2017-11-16 5:01 ` Andrew Fish
2017-11-16 22:02 ` Paulo Alcantara
2017-11-16 21:56 ` [RFC v3 " Paulo Alcantara
2017-11-16 21:56 ` [RFC v3 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support Paulo Alcantara
2017-11-17 7:24 ` 答复: " Fan Jeff
2017-11-20 14:59 ` Paulo Alcantara
2017-11-23 14:27 ` 答复: " Fan Jeff
2017-11-23 18:34 ` Andrew Fish
2017-11-23 19:49 ` Fan Jeff
2017-11-16 21:56 ` [RFC v3 2/3] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName() Paulo Alcantara
2017-11-16 21:56 ` [RFC v3 3/3] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support Paulo Alcantara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1AA80444-D1BB-405F-8C2D-E9EF5FE62285@apple.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox