• StackWalk64


    #include <Windows.h>  
    
    #define  PULONG_PTR ULONG**
    #define  PULONG ULONG*
    #define  ULONG_PTR ULONG*
     
    #include <DbgHelp.h>  
    #include <stdio.h>
    #include <stdarg.h>
    #include <stdlib.h>
    
    // 添加对dbghelp.lib的编译依赖  
    //  
    #pragma comment(lib, "dbghelp.lib") 
      
       
    const int MAX_ADDRESS_LENGTH = 32;  
    const int MAX_NAME_LENGTH = 1024;  
      
    // 崩溃信息  
    //   
    
      
    // 安全拷贝字符串函数  
    //  
    
      
    // 得到程序崩溃信息  
    //  
    
    // 得到CallStack信息  
    //  
    #define  GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS         (0x04)  // lpModuleName是模块中的一个地址
    typedef BOOL (WINAPI* GetModuleHandleExA_T)(
                                                DWORD        dwFlags,
                                                LPCSTR     lpModuleName,
                                                HMODULE*    phModule
                                                );
    HMODULE getmodulename(char* buffer,int size,void* addri)
    {
        HMODULE hmodule;
        char FileName[MAX_PATH] = {0};
        GetModuleHandleExA_T GetModuleHandleExA=(GetModuleHandleExA_T)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetModuleHandleExA");
        GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)addri, &hmodule);
        GetModuleFileNameA(hmodule, buffer, size);
        return hmodule;
    }
    char* gettimestring(char* buffer)
    {
        SYSTEMTIME  systemtime;
        GetSystemTime( &systemtime);
        sprintf(buffer,"[%2.2d.%2.2d]",systemtime.wHour,systemtime.wMinute,systemtime.wSecond,systemtime.wMilliseconds);
        return buffer;
    }
    void log(const char*format,...)
    {
        va_list v;
        char buffer[300];
        char tbuffer[100];
        
        va_start(v,format);
        _vsnprintf(buffer,299,format,v);
        va_end(v);    
        char fname[100];
        sprintf(fname,"%d.txt",GetCurrentThreadId());
        
        FILE* fd = fopen(fname,"a+b");
        fprintf(fd,"  %s[%d.%d]%s
    ",gettimestring(tbuffer),GetCurrentProcessId(),GetCurrentThreadId(),buffer);
        fclose(fd);
        //OutputDebugStringA(buffer);
        
    }
    void logthread(DWORD threadid,const char*format,...)
    {
        va_list v;
        char buffer[300];
        char tbuffer[100];
        
        va_start(v,format);
        _vsnprintf(buffer,299,format,v);
        va_end(v);    
        char fname[100];
        sprintf(fname,"%d.txt",threadid);
        
        FILE* fd = fopen(fname,"a+b");
        fprintf(fd,"  %s[%d.%d]%s
    ",gettimestring(tbuffer),GetCurrentProcessId(),GetCurrentThreadId(),buffer);
        fclose(fd);
        //OutputDebugStringA(buffer);
        
    }
    void PrintCallStackFromContext(const CONTEXT *pContext,HANDLE hThread,DWORD dwThreadId) ;
    typedef HANDLE (WINAPI * OPENTHREADFUN)(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwThreadId);  
    DWORD WINAPI __printstack(void* p)
    {
        DWORD dwThreadId = (DWORD)p;
        DWORD error;    
        //1:kernel32 大部分程序都自动加载了kernel32.dll  所以再获得句柄之前不需要Loadlibray  
        HMODULE hKernel32 = ::GetModuleHandle("kernel32.dll");      
        //2获得函数指针  
        OPENTHREADFUN pFun = (OPENTHREADFUN)GetProcAddress(hKernel32,"OpenThread");  
        HANDLE hThread  = pFun(THREAD_GET_CONTEXT,0,dwThreadId);
        if(hThread==0){
            error = GetLastError();
            ::MessageBox(0,"error1",0,0);
            return -1;
        }
        CONTEXT tagContext;
        tagContext.ContextFlags = CONTEXT_FULL;
        if(GetThreadContext(hThread,&tagContext)){
            PrintCallStackFromContext(&tagContext,hThread,dwThreadId);
        }else{
            error = GetLastError();
            ::MessageBox(0,"error2",0,0);
            return -2;
        }
        return 0;
    }
    void  PrintCurrentCallStack()
    {
        HANDLE hThread = CreateThread(0,0,__printstack,(void*)GetCurrentThreadId(),0,0);
        WaitForSingleObject(hThread,-1);
    }
    void PrintCallStackFromContext(const CONTEXT *pContext,HANDLE hThread,DWORD dwThreadId)  
    {  
        HANDLE hProcess = GetCurrentProcess();  
      
       
        CONTEXT c = *pContext;  
      
        STACKFRAME64 sf;  
        memset(&sf, 0, sizeof(STACKFRAME64));  
        DWORD dwImageType = IMAGE_FILE_MACHINE_I386;  
      
        // 不同的CPU类型,具体信息可查询MSDN  
        //  
    #ifdef _M_IX86  
        sf.AddrPC.Offset = c.Eip;  
        sf.AddrPC.Mode = AddrModeFlat;  
        sf.AddrStack.Offset = c.Esp;  
        sf.AddrStack.Mode = AddrModeFlat;  
        sf.AddrFrame.Offset = c.Ebp;  
        sf.AddrFrame.Mode = AddrModeFlat;  
    #elif _M_X64  
        dwImageType = IMAGE_FILE_MACHINE_AMD64;  
        sf.AddrPC.Offset = c.Rip;  
        sf.AddrPC.Mode = AddrModeFlat;  
        sf.AddrFrame.Offset = c.Rsp;  
        sf.AddrFrame.Mode = AddrModeFlat;  
        sf.AddrStack.Offset = c.Rsp;  
        sf.AddrStack.Mode = AddrModeFlat;  
    #elif _M_IA64  
        dwImageType = IMAGE_FILE_MACHINE_IA64;  
        sf.AddrPC.Offset = c.StIIP;  
        sf.AddrPC.Mode = AddrModeFlat;  
        sf.AddrFrame.Offset = c.IntSp;  
        sf.AddrFrame.Mode = AddrModeFlat;  
        sf.AddrBStore.Offset = c.RsBSP;  
        sf.AddrBStore.Mode = AddrModeFlat;  
        sf.AddrStack.Offset = c.IntSp;  
        sf.AddrStack.Mode = AddrModeFlat;  
    #else  
        #error "Platform not supported!"  
    #endif  
      
        //HANDLE hThread = GetCurrentThread();  
        logthread(dwThreadId,"=====stackwalk64=====");
      
        while (true)  
        {  
            // 该函数是实现这个功能的最重要的一个函数  
            // 函数的用法以及参数和返回值的具体解释可以查询MSDN  
            //  
            if (!StackWalk64(dwImageType, hProcess, hThread, &sf, &c, NULL, 0, 0, NULL))  
            {  
                break;  
            }  
      
            if (sf.AddrFrame.Offset == 0)  
            {  
                break;  
            }  
                      
            // 得到函数名  
            //  
                DWORD retaddress = (DWORD)sf.AddrPC.Offset;
                char buffer[300];
                HMODULE hmod = getmodulename(buffer,300,(void*)retaddress);
                 logthread(dwThreadId,"retaddress=%s %x",buffer,retaddress-(DWORD)hmod);
      
        }  
        logthread(dwThreadId,"==========");
       
     }
  • 相关阅读:
    Redis学习六(java中使用redis)
    Redis学习五(新数据类型)
    Redis学习四(发布和订阅)
    Redis学习三(配置文件说明)
    Redis学习二(常用五大数据类型)
    Redis学习一(源码安装redis)
    RocketMq常见问题记录
    总结多种容器化技术对比
    关于Redis集群部署和持久化的相关问题
    配置Jenkins连接kubernetes的Pod Template模板
  • 原文地址:https://www.cnblogs.com/hjbf/p/10414477.html
Copyright © 2020-2023  润新知