比如写了一个函数fun(),想知道都有谁调用了它,然后打印出函数的调用层次和函数名。
我查了一些网上的资料,有些是用宏的方式 内嵌函数体得知调用层次和函数名的
比如:
#define PRINT(g_nIndex) printf("%d,%s\n",g_nIndex,__FUNCTION__)
int g_nIndex = 0; //记录函数运行深度
void print1()
{
g_nIndex++;
PRINT(g_nIndex);
g_nIndex--;
}
void print2()
{
g_nIndex++;
PRINT(g_nIndex);
print1();
g_nIndex--;
}
void print3()
{
g_nIndex++;
PRINT(g_nIndex);
print1();
g_nIndex--;
}
int _tmain(int argc, _TCHAR* argv[])
{
print1();
print2();
print3();
return 0;
}
打印输出:
0,main
1,print1
1,print2
2,print1
1,print3
2,print1
其中数字代表函数调用关系,0是函数入口,1被0调用,2被1调用,每个相同的数字是平行被调用的关系;
数字后面是函数的名称;
画成图就是:
main
|_print1
|_print2
| |_print1
|_print3
|_print1
上面是一个例子,不过不是很满意,原因是首先要内嵌代码到每个函数中,如果函数很多,不好实现;
第二,也没有针对某一个函数打印它的栈信息,上面的代码实现了所有函数的调用情况;
比如我要知道都有谁调用了print1()
就像是VC调试器一样,得到当前调用print1()的所有函数,并把它们的名字打印出来;就像下面一样:
0 main
1 print1
0 main
1 print2
2 print1
0 main
1 print3
2 print1
采用即时打印的方式,只要走到print1()函数,就可以打印出调用它的层次。
请问各位高手大虾有没有好的方法,不用内嵌代码的方式,就能实现上面的叙述的功能哇,小弟不胜感激了~~
6 个解决方案
#1
改用java吧 通过异常的printstack可以实现
#2
http://203.208.37.132/search?q=cache:zbFf24AvwWMJ:www.ddj.com/article/printableArticle.jhtml%3FarticleID%3D184405270%26dept_url%3D/development-tools/+DDJ+call+stack&cd=1&hl=zh-CN&ct=clnk&gl=cn&st_usg=ALhdy29ym1apCdHN_M2UZ-TXp1dNby9hAw
参考这个
参考这个
#3
有个__FUNCTION__宏,还有StackWalkAPI~
#4
如果不用嵌入代码,C/C++是编译器,它已把你所有的函数编译成了机器码,原始信息只有以下两种方式存在执行文件中:
1.调试信息:就像VC调试器中一样,如果是Relesease版本,就没用了
2.RTTI,这个要编译器支持.且不一定能实现你的要求.
所以,宏替换(最终还是嵌入代码的)不失为一个好方法.
1.调试信息:就像VC调试器中一样,如果是Relesease版本,就没用了
2.RTTI,这个要编译器支持.且不一定能实现你的要求.
所以,宏替换(最终还是嵌入代码的)不失为一个好方法.
#5
每个进程的主线程有一个栈,这个栈里记录了所有的函数调用需要的参数,返回地址,调用现场,局部变量等信息。从这个栈中可以依次向上找到返回地址(属于某个函数的指令的地址),进而找到该函数。
#6
可以对照Map文件或反汇编exe的内容,查找堆栈中十六进制函数返回地址对应的调用函数地址。
计算机组成原理→DOS命令→汇编语言→C语言、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言、架构……
计算机组成原理→DOS命令→汇编语言→C语言、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言、架构……
#1
改用java吧 通过异常的printstack可以实现
#2
http://203.208.37.132/search?q=cache:zbFf24AvwWMJ:www.ddj.com/article/printableArticle.jhtml%3FarticleID%3D184405270%26dept_url%3D/development-tools/+DDJ+call+stack&cd=1&hl=zh-CN&ct=clnk&gl=cn&st_usg=ALhdy29ym1apCdHN_M2UZ-TXp1dNby9hAw
参考这个
参考这个
#3
有个__FUNCTION__宏,还有StackWalkAPI~
#4
如果不用嵌入代码,C/C++是编译器,它已把你所有的函数编译成了机器码,原始信息只有以下两种方式存在执行文件中:
1.调试信息:就像VC调试器中一样,如果是Relesease版本,就没用了
2.RTTI,这个要编译器支持.且不一定能实现你的要求.
所以,宏替换(最终还是嵌入代码的)不失为一个好方法.
1.调试信息:就像VC调试器中一样,如果是Relesease版本,就没用了
2.RTTI,这个要编译器支持.且不一定能实现你的要求.
所以,宏替换(最终还是嵌入代码的)不失为一个好方法.
#5
每个进程的主线程有一个栈,这个栈里记录了所有的函数调用需要的参数,返回地址,调用现场,局部变量等信息。从这个栈中可以依次向上找到返回地址(属于某个函数的指令的地址),进而找到该函数。
#6
可以对照Map文件或反汇编exe的内容,查找堆栈中十六进制函数返回地址对应的调用函数地址。
计算机组成原理→DOS命令→汇编语言→C语言、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言、架构……
计算机组成原理→DOS命令→汇编语言→C语言、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言、架构……