免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7028 | 回复: 10

[函数] 关于在运行时“怎么知道自己写的c函数正在被那些函数调用?”的问题。 [复制链接]

论坛徽章:
0
发表于 2007-05-08 22:00 |显示全部楼层
偶尔重读“精灵进程”于2007年1月24日发的帖子,看到大家对他的第一个问题还没有什么明确的答案,就在这里说一下我的方法,不一定是最好的,大家共同学习。
原题是这样的:
1。怎么知道自己写的c函数正在被那些函数调用?请说明方法。

我估计面试官的本意是,如何设计你的函数(called 函数和calling 函数),使得这个函数可以知道是谁在调用它, 这么做的目的是为了便于debug。

我的方法其实很简单,就是在每个函数的参数列表加上两个参数,一个是文件名,一个是行号, 如:
void myFunction1 (int var1, int var2, ... , char *file, int line )

然后在每个需要调用 myFunction1 的地方, 比如 myFunction2 内调用 myFunction1, 使用如下方式调用:
void myFunction2 () {
   ....
   myFunction1(a, b, ... , __FILE__, __LINE__ ); // 调用时,编译器会自动把当前的文件名和行号填入作为参数。
   ....
}

这样在myFunction1 内就能*实时*的知道是那个函数在调用它,因为我们知道了文件名和行号,就可以唯一定位到某个函数内。

如我所述,这不一定是最好的方法,但起码可以达到目的。

论坛徽章:
0
发表于 2007-05-08 22:04 |显示全部楼层
不错。这是种思路。

论坛徽章:
0
发表于 2007-05-08 22:16 |显示全部楼层
这种方法用一个 宏就可以了, 可跟踪任何函数,不需要改函数定义。
void myFunction1(......)
#define DEBUG_MY_FUNCTION 1
#if DEBUG_MY_FUNCTION
#define CALL_MY_FUNCTION debug("called at %s:%d %s\n", __FILE__,__LINE__,__FUNCTION__); myFunction1
#else
#define CALL_MY_FUNCTION myFunction1
#endif

程序中用CALL_MY_FUNCTION替代myFunction1即可。

论坛徽章:
0
发表于 2007-05-08 22:30 |显示全部楼层
谢谢你的回复,使用宏是一个不错的选择,起码不需要对myFunction1的参数进行修改。

但是在有一些应用中,宏却无能为力。
很多时候,我们需要记录每一个对此函数调用的文件名,行号,为了在程序出错时(或者core dump)进行调试。使用宏能够实时的把每一次调用打印出来,但是不能体现出根细节的信息。比如当在函数myFunction1 中做某些“关键”操作时,比如操作hash table,删掉一个记录,或者增加一个记录,删除的时候,我们同时产生一个删除条目,用于记录是谁删除的该条记录(即调用函数所在文件和行号),以便于日后出现问题的时候能够很快的debug出来。

使用宏和能够很优雅的解决问题,同时也丧失了一些灵活性。

再次感谢你的回复~

原帖由 connet 于 2007-5-8 22:16 发表
这种方法用一个 宏就可以了, 可跟踪任何函数,不需要改函数定义。
void myFunction1(......)
#define DEBUG_MY_FUNCTION 1
#if DEBUG_MY_FUNCTION
#define CALL_MY_FUNCTION debug("called at %s:%d %s ...

论坛徽章:
0
发表于 2007-05-09 08:52 |显示全部楼层
不错

论坛徽章:
0
发表于 2007-05-09 09:20 |显示全部楼层
这个思路确实好,配合define,分别生成debug版和release版的函数,确实方便

  1. fun(arg)

  2. #ifdef debug
  3. #define Fun(arg)    Fun_debug(arg,__FILE__,__LINE__,__FUNCTION__)
  4. #else
  5. #define Fun(arg)    Fun_release(arg)
  6. #endif

  7. #define Fun_release(arg)    fun(arg);
  8. #define Fun_debug(arg,__FILE__,__LINE__,__FUNCTION__)   \
  9.          printf("%s,%s,%s",__FILE__,__LINE__,__FUNCTION__ );fun(arg);

复制代码

[ 本帖最后由 net_robber 于 2007-5-9 09:22 编辑 ]

论坛徽章:
0
发表于 2007-05-09 09:27 |显示全部楼层
gcc的__builtin_return_address有没有用?

论坛徽章:
0
发表于 2007-05-09 09:40 |显示全部楼层
楼上,偶没有用过这个,马上查一下,呵呵

论坛徽章:
0
发表于 2007-05-09 10:00 |显示全部楼层
那个返回的不是字符串啊

论坛徽章:
0
发表于 2007-05-09 10:23 |显示全部楼层

回复 9楼 net_robber 的帖子

嗯, 只是个地址值
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP