1. #include <Windows.h>  
  2.  
  3. #define  PULONG_PTR ULONG**
  4. #define  PULONG ULONG*
  5. #define  ULONG_PTR ULONG*
  6.  
  7. #include <DbgHelp.h>  
  8. #include <stdio.h>
  9. #include <stdarg.h>
  10. #include <stdlib.h>
  11.  
  12. // 添加对dbghelp.lib的编译依赖  
  13. //  
  14. #pragma comment(lib, "dbghelp.lib")
  15.  
  16.    
  17. const int MAX_ADDRESS_LENGTH = ;  
  18. const int MAX_NAME_LENGTH = ;  
  19.  
  20. // 崩溃信息  
  21. //   
  22.  
  23.  
  24. // 安全拷贝字符串函数  
  25. //  
  26.  
  27.  
  28. // 得到程序崩溃信息  
  29. //  
  30.  
  31. // 得到CallStack信息  
  32. //  
  33. #define  GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS         (0x04)  // lpModuleName是模块中的一个地址
  34. typedef BOOL (WINAPI* GetModuleHandleExA_T)(
  35.                                             DWORD        dwFlags,
  36.                                             LPCSTR     lpModuleName,
  37.                                             HMODULE*    phModule
  38.                                             );
  39. HMODULE getmodulename(char* buffer,int size,void* addri)
  40. {
  41.     HMODULE hmodule;
  42.     char FileName[MAX_PATH] = {};
  43.     GetModuleHandleExA_T GetModuleHandleExA=(GetModuleHandleExA_T)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetModuleHandleExA");
  44.     GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)addri, &hmodule);
  45.     GetModuleFileNameA(hmodule, buffer, size);
  46.     return hmodule;
  47. }
  48. char* gettimestring(char* buffer)
  49. {
  50.     SYSTEMTIME  systemtime;
  51.     GetSystemTime( &systemtime);
  52.     sprintf(buffer,"[%2.2d.%2.2d]",systemtime.wHour,systemtime.wMinute,systemtime.wSecond,systemtime.wMilliseconds);
  53.     return buffer;
  54. }
  55. void log(const char*format,...)
  56. {
  57.     va_list v;
  58.     char buffer[];
  59.     char tbuffer[];
  60.     
  61.     va_start(v,format);
  62.     _vsnprintf(buffer,,format,v);
  63.     va_end(v);    
  64.     char fname[];
  65.     sprintf(fname,"%d.txt",GetCurrentThreadId());
  66.     
  67.     FILE* fd = fopen(fname,"a+b");
  68.     fprintf(fd,"  %s[%d.%d]%s\r\n",gettimestring(tbuffer),GetCurrentProcessId(),GetCurrentThreadId(),buffer);
  69.     fclose(fd);
  70.     //OutputDebugStringA(buffer);
  71.     
  72. }
  73. void logthread(DWORD threadid,const char*format,...)
  74. {
  75.     va_list v;
  76.     char buffer[];
  77.     char tbuffer[];
  78.     
  79.     va_start(v,format);
  80.     _vsnprintf(buffer,,format,v);
  81.     va_end(v);    
  82.     char fname[];
  83.     sprintf(fname,"%d.txt",threadid);
  84.     
  85.     FILE* fd = fopen(fname,"a+b");
  86.     fprintf(fd,"  %s[%d.%d]%s\r\n",gettimestring(tbuffer),GetCurrentProcessId(),GetCurrentThreadId(),buffer);
  87.     fclose(fd);
  88.     //OutputDebugStringA(buffer);
  89.     
  90. }
  91. void PrintCallStackFromContext(const CONTEXT *pContext,HANDLE hThread,DWORD dwThreadId) ;
  92. typedef HANDLE (WINAPI * OPENTHREADFUN)(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwThreadId);  
  93. DWORD WINAPI __printstack(void* p)
  94. {
  95.     DWORD dwThreadId = (DWORD)p;
  96.     DWORD error;    
  97.     //1:kernel32 大部分程序都自动加载了kernel32.dll  所以再获得句柄之前不需要Loadlibray  
  98.     HMODULE hKernel32 = ::GetModuleHandle("kernel32.dll");      
  99.     //2获得函数指针  
  100.     OPENTHREADFUN pFun = (OPENTHREADFUN)GetProcAddress(hKernel32,"OpenThread");  
  101.     HANDLE hThread  = pFun(THREAD_GET_CONTEXT,,dwThreadId);
  102.     if(hThread==){
  103.         error = GetLastError();
  104.         ::MessageBox(,"error1",,);
  105.         return -;
  106.     }
  107.     CONTEXT tagContext;
  108.     tagContext.ContextFlags = CONTEXT_FULL;
  109.     if(GetThreadContext(hThread,&tagContext)){
  110.         PrintCallStackFromContext(&tagContext,hThread,dwThreadId);
  111.     }else{
  112.         error = GetLastError();
  113.         ::MessageBox(,"error2",,);
  114.         return -;
  115.     }
  116.     return ;
  117. }
  118. void  PrintCurrentCallStack()
  119. {
  120.     HANDLE hThread = CreateThread(,,__printstack,(void*)GetCurrentThreadId(),,);
  121.     WaitForSingleObject(hThread,-);
  122. }
  123. void PrintCallStackFromContext(const CONTEXT *pContext,HANDLE hThread,DWORD dwThreadId)  
  124. {  
  125.     HANDLE hProcess = GetCurrentProcess();  
  126.  
  127.    
  128.     CONTEXT c = *pContext;  
  129.  
  130.     STACKFRAME64 sf;  
  131.     memset(&sf, , sizeof(STACKFRAME64));  
  132.     DWORD dwImageType = IMAGE_FILE_MACHINE_I386;  
  133.  
  134.     // 不同的CPU类型,具体信息可查询MSDN  
  135.     //  
  136. #ifdef _M_IX86  
  137.     sf.AddrPC.Offset = c.Eip;  
  138.     sf.AddrPC.Mode = AddrModeFlat;  
  139.     sf.AddrStack.Offset = c.Esp;  
  140.     sf.AddrStack.Mode = AddrModeFlat;  
  141.     sf.AddrFrame.Offset = c.Ebp;  
  142.     sf.AddrFrame.Mode = AddrModeFlat;  
  143. #elif _M_X64  
  144.     dwImageType = IMAGE_FILE_MACHINE_AMD64;  
  145.     sf.AddrPC.Offset = c.Rip;  
  146.     sf.AddrPC.Mode = AddrModeFlat;  
  147.     sf.AddrFrame.Offset = c.Rsp;  
  148.     sf.AddrFrame.Mode = AddrModeFlat;  
  149.     sf.AddrStack.Offset = c.Rsp;  
  150.     sf.AddrStack.Mode = AddrModeFlat;  
  151. #elif _M_IA64  
  152.     dwImageType = IMAGE_FILE_MACHINE_IA64;  
  153.     sf.AddrPC.Offset = c.StIIP;  
  154.     sf.AddrPC.Mode = AddrModeFlat;  
  155.     sf.AddrFrame.Offset = c.IntSp;  
  156.     sf.AddrFrame.Mode = AddrModeFlat;  
  157.     sf.AddrBStore.Offset = c.RsBSP;  
  158.     sf.AddrBStore.Mode = AddrModeFlat;  
  159.     sf.AddrStack.Offset = c.IntSp;  
  160.     sf.AddrStack.Mode = AddrModeFlat;  
  161. #else  
  162.     #error "Platform not supported!"  
  163. #endif  
  164.  
  165.     //HANDLE hThread = GetCurrentThread();  
  166.     logthread(dwThreadId,"=====stackwalk64=====");
  167.  
  168.     while (true)  
  169.     {  
  170.         // 该函数是实现这个功能的最重要的一个函数  
  171.         // 函数的用法以及参数和返回值的具体解释可以查询MSDN  
  172.         //  
  173.         if (!StackWalk64(dwImageType, hProcess, hThread, &sf, &c, NULL, , , NULL))  
  174.         {  
  175.             break;  
  176.         }  
  177.  
  178.         if (sf.AddrFrame.Offset == )  
  179.         {  
  180.             break;  
  181.         }  
  182.                   
  183.         // 得到函数名  
  184.         //  
  185.             DWORD retaddress = (DWORD)sf.AddrPC.Offset;
  186.             char buffer[];
  187.             HMODULE hmod = getmodulename(buffer,,(void*)retaddress);
  188.              logthread(dwThreadId,"retaddress=%s %x",buffer,retaddress-(DWORD)hmod);
  189.  
  190.     }  
  191.     logthread(dwThreadId,"==========");
  192.    
  193.  }

StackWalk64的更多相关文章

  1. 《Note --- Unreal --- MemPro (CONTINUE... ...)》

    Mem pro 是一个主要集成内存泄露检测的工具,其具有自身的源码和GUI,在GUI中利用"Launch" button进行加载自己待检测的application,目前支持的平台为 ...

  2. 《Walking the callstack(转载)》

    本文转载自:https://www.codeproject.com/articles/11132/walking-the-callstack Download demo project with so ...

  3. Google之Chromium浏览器源码学习——base公共通用库(四)

    本文将介绍debug调试相关的内容,包括调试器.性能分析.堆跟踪.跟踪事件等: alias.h:Alias函数,提供防止载微软的编译器优化某参数变量的操作,内部通过#pragma optimize(& ...

  4. 【转】调试Release发布版程序的Crash错误

    http://www.cppblog.com/Walker/archive/2012/11/08/146153.html http://blog.sina.com.cn/s/blog_48f93b53 ...

  5. 使用Visual Leak Detector检测内存泄漏[转]

      1.初识Visual Leak Detector 灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题.当程序越来越复杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题 ...

  6. VLD(Visual LeakDetector)内存泄露库的使用

    VLD简介 由于C/C++语言没有所谓的垃圾收集器,内存的分配和释放都需要程序员自己来控制,这会给C/C++程序员带来一定的困难.当您的程序越来越复杂时,它的内存管理也会变得越来越困难.内存泄漏.内存 ...

  7. [转]让程序在崩溃时体面的退出之CallStack

    原文地址:http://blog.csdn.net/starlee/article/details/6618849 在我的那篇<让程序在崩溃时体面的退出之Unhandled Exception& ...

  8. 内存泄漏工具VLD1.0_要点分析

    0X01 关闭FPO优化 // Frame pointer omission (FPO) optimization should be turned off for this // entire fi ...

  9. vld(Visual Leak Detector) 内存泄露检测工具

    初识Visual Leak Detector 灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题.当程序越来越复 杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题.内存 ...

随机推荐

  1. ubantu下安装pip,python,pycharm,numpy,scipy,matplotlibm,pandas 以及sklearn

    ubuntu 安装 pip 及 pip 常用命令: https://blog.csdn.net/danielpei1222/article/details/62969815 ubuntu下不同版本py ...

  2. Elixir 单元测试

    概述 elixir 中自带了单元测试框架 ExUnit ,其中提供单元测试的一系列,主要包含以下模块: ExUnit: 单元测试框架 ExUnit.Assertions: 断言 ExUnit.Case ...

  3. [WeChall] Training: MySQL I (MySQL, Exploit, Training)

    Training: MySQL I (MySQL, Exploit, Training) MySQL Authentication Bypass - The classic This one is t ...

  4. 前端性能优化成神之路--SSR(服务端渲染)

    Nuxt.js的介绍 Nuxt.js概述 nuxt.js简单的说是Vue.js的通用框架,最常用的就是用来作SSR(服务器端渲染).Vue.js是开发SPA(单页应用)的,Nuxt.js这个框架,用V ...

  5. Linux vi/vim编辑器

    所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正 ...

  6. android studio 定位具体的错误原因

    编译一个数据监测APP的时候出现了报错: Error:Compilation failed; see the compiler error output for details. 在网上查到方法如下: ...

  7. oldboy-作业01.登录多次进行账号锁定

    """可以支持多个用户登录 (提示,通过列表存多个账户信息)用户3次认证失败后,退出程序,再次启动程序尝试登录时,还是锁定状态(提示:需把用户锁定的状态存到文件里) &q ...

  8. 构建企业 YUM仓库

    构建企业 YUM仓库 本地光盘提供基础软件包Base yum缓存提供update软件包 yum缓存提供常用软件包: nginx, zabbix, docker, saltstack 环境准备 系统 I ...

  9. 网站建设部署与发布--笔记2-部署Apache

    网站部署(Linux) 部署Apache 操作系统:CentOS 7.2 1.首先连接云服务器,清楚系统垃圾. $ yum clean all Loaded plugins: fastestmirro ...

  10. 吴恩达课后作业学习2-week3-tensorflow learning-1-基本概念

    参考:https://blog.csdn.net/u013733326/article/details/79971488 希望大家直接到上面的网址去查看代码,下面是本人的笔记  到目前为止,我们一直在 ...