使用脚本或正则表达式向每个函数添加“ printf”

问题描述 投票:3回答:3

在正则表达式或脚本(例如,用python编写的脚本中,如何添加

printf("TRACING: %s is called\n", __PRETTY_FUNCTION__); 

在所有函数定义的输入处,例如

INT4
FunctionNameCouldBeAny (UINT4 ui)
{
    // insert here, at entry
    printf("TRACING: %s is called\n", __PRETTY_FUNCTION__); 
} 
  1. 对于一个文件xxx.c
  2. 对于目录*.c下的所有c文件/work_space/test/src

请注意,在同一文件中定义的函数可以共享相同的前缀,但不总是相同。

评论1:-finstrument-functions对我的gcc无效;否则,我必须提供__cyg_profile_func_enter()/exit()函数,并找到一种从二进制地址打印出名称的方法。我想知道正则表达式是否有更有效的方法。

python c regex trace
3个回答
1
投票

彻底完成这项工作将很困难。问题是在定义函数时就认识到了。可能有许多可能的布局,并且很难识别所有可能性。例如:

int x() { return 1; } int y(int z) { return z + 13; }

大多数特设系统即使检测并处理y,也不会检测到x。但这是糟糕的代码布局,您可能不会沉迷于此类代码布局。

您如何启动功能?

  1. static void function(int arg1) {
  2. static voidfunction(int arg1) {
  3. static voidfunction(int arg1){
  4. static voidfunction(int arg1){
  5. static voidfunction(int arg1){

等等根据所使用的符号,您需要编写多个不同的正则表达式。请注意,如果您不能在行首标记处应用“ {启发式功能-或结构/联合定义或数据初始化”(因为在包含以下内容的行的末尾使用{功能),它变得相当棘手。

您可能需要标记输入,并跟踪您是否在函数定义中。尽管我的示例使用了关键字,但是您只能使用用户定义的类型来使用函数:

Xyz *pqr(Abc def)
{

然后,当然,您可能编写了没有原型的旧代码:

Xyz *pqr(def)
Abc def;
{

所有这些都是在您涉及预处理器之前的,这确实会使事情迷惑:

#define BEGIN {
#define END }

Xyz *pqr(Abc def)
BEGIN
    ...
END

(据说,最初的Bourne shell源代码是使用类似于那些的宏编写的。]

因此,通常,您会开发一个临时系统来识别项目所使用的样式中列出的功能。人们希望您的项目足够系统化,可以有各种各样的选择,但是如果这是许多人已经维护了多年的旧代码,那么到处都有特殊情况。


0
投票

我有一个简单的解决方案,那就是强大的宏!如果您只想将它​​们应用于一小部分函数,​​而函数指针未调用它们

这是简单的解决方案:

1找到调用函数的定义和说明

2将它们重命名为其他名称,例如:myfunc到_myfunc,仅在这些函数中更改了名称,因此很容易改回来

3定义一个名称为myfunc的宏,其作用是:1)打印日志2)调用原始函数

您可以将所有这些函数的声明抓取到一个宏定义文件中,进行一些简单的文本工作(也许使用脚本lang帮助或文本编辑器宏帮助),但是此解决方案不适用于大量函数,并且不要不处理函数指针。

例如,您具有这样的功能:

int myfunc(int arg)
int myfunc(int arg){
    return 0;
}

将myfunc重命名为_myfunc并添加一个名为myfunc的宏

#define myfunc(arg)\
    print("print whatever you want!");\
    myfunc(arg);\
int _myfunc(int arg);
int _myfunc(int arg){
    return 0;
}

如果宏不够好,请用另一个函数包装

int myfunc(arg){
    print("print whatever you want!");
    return myfunc(arg);
}
int _myfunc(int arg);
int _myfunc(int arg){
    return 0;
}

0
投票

如果您想用printk调试Linux内核,并且想在运行时获得调用流程,那么我有一个非常基本的本地解决方案。

在记事本++中打开.c文件-> ctrl + H->查找内容:\ n {->替换为:\ n {printk \(“您的名字:%s:%d \\ n”,__func__, __LINE__ \); ->全部替换

注释内核父目录Makefile,如下所示:

+#KBUILD_CFLAGS + = $(调用cc-option,-Wdeclaration-after-statement,)

希望它能解决您的问题。

© www.soinside.com 2019 - 2024. All rights reserved.