例如,有来源:
void my_special_debugging_function(const char* function_name, const char* file_name, int line_number);
void func1() {
func3();
func4();
}
void foo() {
func1();
if(qqq) {
func2();
};
func3();
func4();
for(...) {
func5();
}
}
它应编译为:
void my_special_debugging_function(const char* function_name, const char* file_name, int line_number);
void func1() {
my_special_debugging_function("func1", "prog.c", 3);
func3();
my_special_debugging_function("func1", "prog.c", 4);
func4();
my_special_debugging_function("func1", "prog.c", 5);
}
void foo() {
my_special_debugging_function("foo", "prog.c", 8);
func1();
my_special_debugging_function("foo", "prog.c", 9);
if(qqq) {
my_special_debugging_function("foo", "prog.c", 10);
func2();
my_special_debugging_function("foo", "prog.c", 11);
};
my_special_debugging_function("foo", "prog.c", 12);
func3();
my_special_debugging_function("foo", "prog.c", 13);
func4();
my_special_debugging_function("foo", "prog.c", 14);
for(...) {
my_special_debugging_function("foo", "prog.c", 15);
func5();
my_special_debugging_function("foo", "prog.c", 16);
}
my_special_debugging_function("foo", "prog.c", 17);
}
当然,my_special_debugging_function应该能够使用backtrace
函数。
gcc可以选择吗?或者是否有工具在源代码级别执行此操作? (例如,用我的功能生成其他C源)
@related How to "interleave" C/C++ souce with my string (only inside functions at appropriate places)?
答案 0 :(得分:4)
请参阅GCC文档中的-finstrument-functions
。您可能希望在调试功能中使用dladdr()
,这可能还需要与-Wl,-export-dynamic
进行链接。
答案 1 :(得分:2)
如果您使用的是gcc版本> = 4.5,您可以write a gcc plugin以您喜欢的方式处理AST。但该解决方案将取决于编译器。
您还可以obtain AST from eclipse CDT并从该输入重新生成C代码。
答案 2 :(得分:0)
如其他答案所述,I don't think that there is any way to tell GCC to do that, without preprocessor tricks and edits to the source code. – nategoose
答案 3 :(得分:-1)
您可以使用aspectc ++轻松完成。从 aspectc.org 获取此编译器这是一个符合您要求的简单方面。 Trace.ah
#ifndef __trace_ah__
#define __trace_ah__
#include <cstdio>
#include <iostream>
using namespace std;
template <int I> struct ArgPrinter
{
template <class JP> static inline void work (JP &tjp) {
ArgPrinter<I - 1>::work (tjp);
cout << *tjp.template arg<I - 1> () << " ";
}
};
template <> struct ArgPrinter<0>
{
template <class JP> static inline void work (JP &tjp) {}
};
aspect trace {
int depth=-1;
pointcut virtual methods() = "% ...::%(...)";
template <class JP> void print_args (JP &tjp)
{
ArgPrinter<JP::ARGS>::work (tjp);
}
advice execution (methods()) : before ()
{
depth++;
cout << "Enter -> " << JoinPoint::signature() <<" Depth:"<<depth<< " ARGS " << JoinPoint::ARGS <<" (";
tjp->arg(0);
print_args (*tjp);
cout<<")"<<endl;
cout<< "console--"<<endl;
}
advice execution("% ...::%(...)" && !"void ...::%(...)") : after()
{
cout<< "--console"<<endl;
JoinPoint::Result res = *tjp->result();
cout << "Exit <- " << tjp->signature()<< " Depth: "<<depth<< " RET " << res<<endl;
depth--;
}
advice execution("void ...::%(...)") : after()
{
cout<< "--console"<<endl;
cout << "Exit <- " << tjp->signature()<< " Depth: "<<depth<< " RET void"<<endl;
depth--;
}
};
#endif
使用ac ++编译器在项目中编译此方面,然后运行程序。然后你应该在控制台中看到跟踪。 快乐的追踪!