<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      使用DbgHelp獲取函數(shù)調(diào)用堆棧之inline assembly(內(nèi)聯(lián)匯編)法

      如果想自己獲取應(yīng)用程序的Call Stack,就需要查看Stack的內(nèi)容。Stack Walker,在最近查看SSCLI源碼的時候發(fā)現(xiàn)這個東西是和Stack Frame緊密聯(lián)系在一起的。

      Walking the Stack

      We could conceivably attempt to unwind the stack ourselves using inline assembly. But stack frames can be organized in different ways, depending on compiler optimizations and calling conventions, so it could become complicated to do it that way. Once again, Microsoft has provided us with a tool to help us out. This time it is a function that we can call iteratively to walk the stack, frame by frame. That function is StackWalk64. It is part of the Debug Help Library (dbghelp.dll). As long as we provide it with the information that it needs to establish a starting "frame of reference", so to speak, it can examine our stack from there and reliably unwind it for us. Each time StackWalk64 is called, it gives back a STACKFRAME64 structure that can be reused as input for the next call to StackWalk64. It can be repeatedly called this way until the end of the stack is reached.

             從上面的Walking the Stack可以看到,查看AppStack有兩種方法。使用內(nèi)聯(lián)匯編或者是使用DbgHelp庫里面的StackWalk64方法。

             找到DbgHelp里面是StackWalk64

       

      BOOL

      IMAGEAPI

      StackWalk64(

      DWORD

      MachineType,

      HANDLE

      hProcess,

      HANDLE

      hThread,

      LPSTACKFRAME64

      StackFrame,

      PVOID

      ContextRecord,

      PREAD_PROCESS_MEMORY_ROUTINE64

      ReadMemoryRoutine,

      PFUNCTION_TABLE_ACCESS_ROUTINE64

      FunctionTableAccessRoutine,

      PGET_MODULE_BASE_ROUTINE64

      GetModuleBaseRoutine,

      PTRANSLATE_ADDRESS_ROUTINE64

      TranslateAddress

      );

       

             可以參考MSDN里面:http://msdn2.microsoft.com/en-us/library/ms680650(VS.85).aspx的關(guān)于這個方法的詳細(xì)使用。

             Kevin Lynx也給做了關(guān)于使用這個方法來獲取調(diào)用堆棧的例子:

      http://www.cppblog.com/kevinlynx/archive/2008/03/28/45628.html

       

      這里,就給出一個采用內(nèi)聯(lián)匯編來獲取App調(diào)用堆棧的例子,這個例子里面,由于調(diào)試生成的符號文件沒有加載好,故而Mudule的信息不能很好的顯示出來,不過這個例子很好的演示了使用內(nèi)聯(lián)匯編來獲取Stack Frame,從而print出整個函數(shù)的調(diào)用堆棧來,同時也是一個很好的使用DbgHelp來獲取調(diào)試信息的例子:

      #include "stdafx.h"

      #include <windows.h>

      #include <dbghelp.h>

       

      #define INVALID_FP_RET_ADDR_VALUE 0x00000000

       

      BOOL g_fSymInit;

      HANDLE g_hProcess;

       

            

      //address of the founction stack-call to walk.

      BOOL DisplaySymbolDetails(DWORD dwAddress)

      {

             DWORD64 displacement = 0;

       

             ULONG64 buffer[(sizeof(SYMBOL_INFO) +

          MAX_SYM_NAME*sizeof(TCHAR) +

          sizeof(ULONG64) - 1) /

          sizeof(ULONG64)];

             PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;

       

             pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);

             pSymbol->MaxNameLen = MAX_SYM_NAME;

       

       

             if (SymFromAddr(g_hProcess,dwAddress,&displacement,pSymbol))

             {

                    // Try to get the Module details

                    IMAGEHLP_MODULE64 moduleinfo;

                    moduleinfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);

                    if (SymGetModuleInfo64(g_hProcess,pSymbol->Address,&moduleinfo))

                    {

                           printf("%s!",moduleinfo.ModuleName);

                    }

                    else

                    {

                           printf("<ErrorModuleInfo_%d>!", GetLastError());

                    }

       

                    // now print the function name

                    if (pSymbol->MaxNameLen > 0)

                    {

                           printf("%s",pSymbol->Name);

                    }

                    else

                    {

                           printf("<Unknown_Function>");

                    }

             }

             else

             {

                    printf(" <Unable to get symbol details_%d>", GetLastError());

             }

       

             return TRUE;

      }

       

       

      //采用內(nèi)聯(lián)匯編獲取當(dāng)前stack Frame地址和當(dāng)前程序指令地址.

      bool WalkTheStack()

      {

             DWORD _ebp = INVALID_FP_RET_ADDR_VALUE;

             DWORD dwIPOfCurrentFunction = (DWORD)&WalkTheStack;

       

             // Get the current Frame pointer

             __asm

             {

                    mov [_ebp], ebp

             }

            

             // We cannot walk the stack (yet!) without a frame pointer

             if (_ebp == INVALID_FP_RET_ADDR_VALUE)

                    return false;

            

             printf("CurFP\t\t\tRetAddr\n");

       

             //current Frame Pointer

             DWORD *pCurFP = (DWORD *)_ebp;

             BOOL fFirstFP = TRUE;

             while (pCurFP != INVALID_FP_RET_ADDR_VALUE)

             {

                    // pointer arithmetic works in terms of type pointed to. Thus,

                    // "+1" below is equivalent of 4 bytes since we are doing DWORD

                    // math.

                    // Find Caller,next print.

                    DWORD pRetAddrInCaller = (*((DWORD *)(pCurFP + 1)));

                    printf("%p\t\t%p  ",pCurFP, (DWORD *)pRetAddrInCaller);

                   

                    if (g_fSymInit)

                    {

                           if (fFirstFP)

                           {

                                  fFirstFP = FALSE;

                           }

       

                           DisplaySymbolDetails(dwIPOfCurrentFunction);

       

                           // To get the name of the next function up the stack,

                           // we use the return address of the current frame

                           dwIPOfCurrentFunction = pRetAddrInCaller;

                    }

       

                    printf("\n");

                    if (pRetAddrInCaller == INVALID_FP_RET_ADDR_VALUE)

                    {

                           // StackWalk is over now...

                           break;

                    }

       

                    // move up the stack to our caller

                    DWORD pCallerFP = *((DWORD *)pCurFP);

                    pCurFP = (DWORD *)pCallerFP;

             }

            

             return true;

      }

       

      int _tmain(int argc, _TCHAR* argv[])

      {

             // Initialize the debugger services to retrieve detailed stack info

             g_fSymInit = FALSE;

             g_hProcess = GetCurrentProcess();

             if (!SymInitialize(g_hProcess, NULL,TRUE))

             {

                    printf("Unable to initialize symbols!\n\n");    

             }

             g_fSymInit = TRUE;

       

             //SYMOPT_UNDNAME:All symbols are presented in undecorated form.

             //SYMOPT_INCLUDE_32BIT_MODULES:

      //When debugging on 64-bit Windows, include any 32-bit modules.

             //SYMOPT_ALLOW_ABSOLUTE_SYMBOLS:

      //Enables the use of symbols that are stored with absolute addresses. instead of RAVS forms.

             SymSetOptions(SYMOPT_UNDNAME|SYMOPT_INCLUDE_32BIT_MODULES|SYMOPT_ALLOW_ABSOLUTE_SYMBOLS);

       

             if (WalkTheStack() == false)

                    printf("Stackwalk failed!\n");

       

             return 0;

      }

       

            兩個程序種需要用到的比較重要的結(jié)構(gòu)體,一個是關(guān)于某個方法Symbol信息的
      typedef struct _SYMBOL_INFO,另外一個是關(guān)于模塊信息的,
      typedef struct _IMAGEHLP_MODULE64.
           
      下面是運(yùn)行這個代碼打印出的調(diào)用代碼示意圖:

      r_aaaa.JPG



      posted on 2008-04-18 14:58  lbq1221119  閱讀(3899)  評論(3)    收藏  舉報

      導(dǎo)航

      主站蜘蛛池模板: 她也色tayese在线视频| 国产日韩一区二区天美麻豆| 免费观看性行为视频的网站| 天天躁夜夜躁狠狠喷水| 高清性欧美暴力猛交| 亚洲国产成人久久精品不卡| 精品久久久无码人妻中文字幕| 国产成人午夜福利精品| 97精品久久久大香线焦| 一本av高清一区二区三区| 高h纯肉无码视频在线观看| 午夜综合网| 亚洲黄日本午夜一区二区| 久久综合色之久久综合| 精品人妻日韩中文字幕| 国产无套内射又大又猛又粗又爽 | 精品久久丝袜熟女一二三| 四虎国产精品永久入口| 中文字幕无码不卡一区二区三区| 无码免费大香伊蕉在人线国产| 2020年最新国产精品正在播放 | 亚洲理论在线A中文字幕| 四虎成人精品无码| 精品国产综合成人亚洲区| 免费国产一区二区不卡| 国产乱子伦一区二区三区四区五区| 国产剧情视频一区二区麻豆| 精品国偷自产在线视频99| 成人嫩草研究院久久久精品| 国产精品久久久久鬼色| 精品一区二区三区日韩版| 久久精品国产亚洲精品色婷婷| 国产精品v欧美精品∨日韩| 国产三级精品三级色噜噜| 久久精品av国产一区二区 | 成人欧美一区在线视频| 亚洲精品一区二区区别| 白嫩少妇激情无码| 九九热精品免费在线视频| 亚洲人亚洲人成电影网站色 | 人妻无码vs中文字幕久久av爆|