Chinaunix首页 | 论坛 | 博客
  • 博客访问: 99175
  • 博文数量: 41
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 486
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-18 20:09
文章分类

全部博文(41)

文章存档

2016年(1)

2015年(1)

2014年(9)

2013年(30)

我的朋友

分类: C/C++

2014-04-14 10:17:28

 

参考url:

http://blog.yeshj.com/onandoff/archive/2009/10/27/1479630.html

 

 

最近主要在修改bug, 发现单纯输入日志还是很难定位错误,就添加了一个堆栈输出的功能。用函数CaptureStackBackTraceType来实现的。发现在vs2008上编译通过,在vs2005上提示找不到该函数标示符。

 

查看msdn

Requirements

Minimum supported client

Windows XP [desktop apps only]

Minimum supported server

Windows Server 2003 [desktop apps only]

Header

WinBase.h (include Windows.h)

 

Library

Kernel32.lib

 

DLL

Kernel32.dll

 

 

很奇怪,为什么在vs2005下就找不到呢,

 

vs2005工程下发现windows.h文件是来自以下目录:

D:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\windows.h

 

Vs2008工程下的windows.h文件来自

C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\windows.h

 

打开文件,发现D:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\windows.h

没有CaptureStackBackTraceType函数,

打开C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\windows.h 发现有

#define CaptureStackBackTrace RtlCaptureStackBackTrace

 

到这里就明白为什么vs2005编译有错了。但是为什么会有2个不同的windows.h文件呢,这个头文件都是对kernel32.dll抛出的库文件啊,为什么会有2个不同的呢。

 

猜测如下:vs2005的时候,自带了Platformsdk,所以所有的系统库kernel32.lib等都在此包里。

Vs2008的时候,自带了winsdk6.4, winsdk中包括了platfromsdk。 所以一些新的函数如CaptureStackBackTraceType,在vs2005中就编译不过。

 

如何能够在vs2005中使用CaptureStackBackTraceType呢, 既然vs2008中能使用这个api,那说明kernel32.dll中是有该api抛出的。 而vs2005的库文件没有抛出而已。在vs2005中可以这样使用:

    typedef USHORT (WINAPI *CaptureStackBackTraceType)(__in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG);

    CaptureStackBackTraceType func = (CaptureStackBackTraceType)(GetProcAddress(LoadLibrary("kernel32.dll"), "RtlCaptureStackBackTrace"));

 
查看vs2005的kernel32.lib文件,发现也存在该api, 所以自己申明一下函数也可以使用:
extern"C"  USHORT __stdcall RtlCaptureStackBackTrace(
                                    __in       ULONG FramesToSkip,
                                    __in       ULONG FramesToCapture,
                                    __out      PVOID *BackTrace,
                                    __out_opt  PULONG BackTraceHash
                                    );

我选择用动态导入的方式。

 源码如下:

点击(此处)折叠或打开

  1. /************************************************************************/
  2. /*
  3. 支持vs2005以上版本
  4. */
  5. /************************************************************************/
  6. #include <windows.h>
  7. #include <DbgHelp.h>
  8. #include <malloc.h>
  9. #include <iostream>
  10. #include "dll_export.h"


  11. #pragma comment(lib, "dbghelp.lib")

  12. //栈的最大深度
  13. #define MAXSTACKDEEPTH 5


  14. std::string StackInfo()
  15. {
  16.     unsigned int i;
  17.     void * stack[ MAXSTACKDEEPTH ];
  18.     unsigned short frames;
  19.     SYMBOL_INFO * symbol;
  20.     HANDLE process;

  21.     process = GetCurrentProcess();

  22.     SymInitialize( process, NULL, TRUE );

  23. #if _MSC_VER == 1400
  24.     typedef USHORT (WINAPI *CaptureStackBackTraceType)(__in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG);
  25.     CaptureStackBackTraceType func = (CaptureStackBackTraceType)(GetProcAddress(LoadLibrary("kernel32.dll"), "RtlCaptureStackBackTrace"));

  26.     //参数2限制:xp, server 2003要求最大不能超过63
  27.     frames = func( 1, MAXSTACKDEEPTH, stack, NULL);

  28. #else if _MSC_VER >= 1500
  29.     frames = CaptureStackBackTrace( 1, MAXSTACKDEEPTH, stack, NULL);
  30. #endif

  31.     ULONG64 buffer[ (sizeof( SYMBOL_INFO ) + 1024 + sizeof( ULONG64 ) - 1) / sizeof( ULONG64 ) ] = { 0 };
  32.     //symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
  33.     symbol=( SYMBOL_INFO * )buffer;
  34.     symbol->MaxNameLen = 255;
  35.     symbol->SizeOfStruct = sizeof( SYMBOL_INFO );

  36.     std::string strRet;
  37.     char buf[100];

  38.     for( i = 0; i < frames; i++ )
  39.     {
  40.         SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );

  41.         sprintf(buf, "(%s:0x%08x)->", symbol->Name, symbol->Address);
  42.         strRet+=buf;
  43.     }

  44.     return strRet;
  45. }

  46. int main()
  47. {
  48.     std::string str=StackInfo();
  49.     return 1;
  50. }


阅读(1515) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~