wordpress   发布时间:2022-04-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了windows – Win64异常堆栈走不显示条目大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

在阅读Win64结构化异常跟踪(从 ProgrAMMing against the x64 exception handling support, part 7: PutTing it all together, or building a stack walk routIne开始)时,我转换了代码 StackWalk64.cpp. procedure DumpExceptionStack();@H_262_5@
在阅读Win64结构化异常跟踪(从 Programming against the x64 exception handling support,part 7: Putting it all together,or building a stack walk routine开始)时,我转换了代码 StackWalk64.cpp.

procedure DumpExceptionStack();
var
  LContext : COntexT;
  LUnwindHistoryTable : _UNWIND_HISTORY_TABLE;
  LRuntimeFunction : Pointer;
  LImageBase : ULONGLONG;
    HandlerData : Pointer;
    EstablisherFrame : ULONG64;
    NvContext : KNONVOLATILE_COntexT_POINTERS;

  LLinenumber                    : Integer;
  LModulename                    : UnicodeString;
  LPublicAddr                    : pointer;
  LPublicName                    : UnicodeString;
  LUnitName                      : UnicodeString;
begin
    //
    // First,we'll get the caller's context.
    //
  RtlCaptureContext(LContext);

    //
    // Initialize the (optional) unwind history table.
    //
  LUnwindHistoryTable := Default(_UNWIND_HISTORY_TABLE);

  // LUnwindHistoryTable.Unwind := True;

    //
    // This unwind loop intentionally skips the first call frame,as it shall
    // correspond to the call to StackTrace64,which we aren't interested in.
    //
  repeat
        //
        // Try to look up unwind Metadata for the current function.
        //
        LRuntimeFunction := RtlLookupFunctionEntry(LContext.Rip,LImageBase,LUnwindHistoryTablE);

    NvContext := Default(KNONVOLATILE_COntexT_POINTERS);

    if not Assigned(LRuntimeFunction) then
    begin
            //
            // If we don't have a RUNTIME_FUNCTION,then we've encountered
            // a leaf function.  Adjust the stack approprately.
            //

      //LContext.Rip  := (ULONG64)(*(PULONG64)Context.Rsp);
      LContext.Rip  := ULONG64(Pointer(LContext.Rsp)^);
            LContext.Rsp := LContext.Rsp + 8;
    end
    else
    begin
            //
            // Otherwise,call upon RtlVirtualUnwind to execute the unwind for
            // us.
            //
            RtlVirtualUnwind(UNW_FLAG_NHANDLER,LContext.Rip,LRuntimeFunction,LContext,HandlerData,EstablisherFrame,NvContext);
    end;

        //
        // If we reach an RIP of zero,this means that we've walked off the end
        // of the call stack and are done.
        //
    if LContext.Rip = 0 then
      Break;

        //
        // Display the context.  Note that we don't bother showing the XMM
        // context,although we have the nonvolatile portion of it.
        //
    if madMapFile.GetMapFileInfos(Pointer(LContext.Rip),LModulename,LUnitName,LPublicName,LPublicAddr,LLinenumber) then
    begin
      Writeln(Format('%p %s.%s %d',[Pointer(LContext.Rip),LLinenumber{,LSEHTypE}]));
    end;
  until LContext.Rip = 0;
end;

然后我用以下内容称呼它:

procedure Main();
begin
  try
    try
      try
        try
          DumpExceptionStack();
        finally
          //
        end;
      except
        on E : Exception do
         raise
      end;
    except
      on E : Exception do
       raise
    end;
  except
    on E : Exception do
     raise
  end;
end;

当我运行应用程序(只是一个控制台应用程序)时,我只获得了Main的一个条目,但我期待有四个(三个嵌套异常,最后一个).

可能是我错误解释了,DumpExceptionStack只会在抛出异常时给出我感兴趣的结果吗?如果是这样,那么获得所有异常堆栈(如果可能)所需的更改是什么 – 即.主要有四个输出

解决方法

与基于堆栈的x86模型相比,x64异常模型是基于表的.这意味着不存在异常堆栈.无论如何,我从未见过试图包含异常和最终阻塞的stalk walk例程.这个没什么不同.它遍历函数调用堆栈.

单个函数中的异常流由范围表控制.在您的函数中,如果您的代码调用DumpExceptionStack的位置引发异常,则多个范围表条目与异常位置匹配.该异常由最内部匹配范围处理.范围的开始和结束地址之间的距离可用于推断哪个范围是最里面的.如果最内层范围不处理异常,或者重新引发异常,则要求下一个最内层范围处理它.依此类推,直到函数的所有匹配范围都用完为止.

大佬总结

以上是大佬教程为你收集整理的windows – Win64异常堆栈走不显示条目全部内容,希望文章能够帮你解决windows – Win64异常堆栈走不显示条目所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。