这篇文章综合了我在网上找到的一些相关文章这里整理一下:
在VC6以后的VS版本中可以在函数体内 通过 __FUNCSIG__ 等方式获取函数的名字;
但是在VC6中要自己实现,以下是我找到的方法:
方法1:
#pragma once
#include <windows.h>
typedef unsigned long ULONG_PTR,*PULONG_PTR;
#define __out_ecount_opt(x)
#include <dbghelp.h>
#include <stdio.h>
#pragma comment(lib,"dbghelp.lib")
static LPSTR GetSymbolSearchpath ()
{
char directory [MAX_PATH];
char drive [MAX_PATH];
HMODULE module;
LPSTR path = new char [MAX_PATH];
memset(path,0,MAX_PATH * sizeof(path[0]));
// Oddly, the symbol handler ignores the link to the PDB embedded in the
// executable image. So, we'll manually add the location of the executable
// to the search path since that is often where the PDB will be located.
path[0] = '\0';
module = GetModuleHandle(NULL);
GetModuleFileNameA(module, path, MAX_PATH);
_splitpath(path, drive, directory, NULL, 0);
strcpy(path, drive);
strcat(path, directory);
// Append the working directory.
strcat(path, ";.\\");
return path;
}
class mydbg
{
public:
mydbg(DWORD dwAddr)
{
memset(szFuctionName,0,sizeof(szFuctionName));
BYTE symbolBuffer [sizeof(SYMBOL_INFO) + 256 * sizeof(CHAR)] = { 0 };
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO) &symbolBuffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = 256;
if( SymFromAddr( GetCurrentProcess(),dwAddr, 0, pSymbol ) )
{
strcpy(szFuctionName, pSymbol->Name);
}
else
{
printf("SymFromAddr Failed! %d\n",GetLastError());
}
}
CHAR szFuctionName[32];
};
#define INIT_SYM(fInvadeProcess) \
LPSTR symbolpath = GetSymbolSearchpath();\
SymInitialize( GetCurrentProcess(), symbolpath, fInvadeProcess); \
delete[] symbolpath;
#define UNINIT_SYM() \
SymCleanup(GetCurrentProcess());
static DWORD GetEIP()
{
DWORD dwCallerAddr;
__asm
{
push DWORD ptr[ebp+4]
pop DWORD ptr[dwCallerAddr]
sub DWORD ptr[dwCallerAddr],5 //减去 call GetEIP() 的长度
}
return dwCallerAddr;
}
#define __func_for_vc6__ (mydbg(GetEIP()).szFuctionName)
// test.cpp #include " stdafx.h " //#include " stdlib.h " #include " dbghelpapi.h " //#pragma comment(lib,"dbghelp.lib") int main( int argc, char * argv[]) { INIT_SYM(TRUE) printf( " this is <%s> fuction\n " ,__func_for_vc6__); UNINIT_SYM() return 0 ; }
output:
this is <main> fuction
说明
release 下必须在设置里选中 "产生调试信息"选项
copy C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib下的DbgHelp.Lib到当前文件夹下;
方法二:http://www.codeproject.com/KB/debug/extendedtrace.aspx
方法三:http://www.codeproject.com/KB/tips/xtrace.aspx
方法二和三基本属于同一种方法,在我的机器上(win7 + VC6 )没有得到预期;
方法四:就是在 VC 中 编写一个 DLL ,这个DLL可以返回当前的函数名(当然是利用现成的__FUNCSIG__),通过VC6 调用这个DLL中的函数获取VC6中的函数名;