C 如何验证函数X()是从函数Y()而不是从函数Z()调用的?

C 如何验证函数X()是从函数Y()而不是从函数Z()调用的?,c,gcc,assembly,lynxos,C,Gcc,Assembly,Lynxos,你能给我举个例子来验证函数X()是从函数Y()而不是从函数Z()调用的吗 使用C语言还是汇编语言 提前谢谢 更新日期:2015年3月2日 假设内核源代码有这么多的驱动程序调用同一个函数,比如SPI(串行Phepheral接口)和GPIO(通用输入输出)的驱动程序源代码调用同一个函数,比如“bzero()” 空隙b0(空隙*s,尺寸n) 我要测试SPI和GPIO驱动程序(驱动程序代码不能修改)。为此,我编写了测试驱动程序。我只能调用从测试驱动程序公开的函数 uint8\u t SPI\u rea

你能给我举个例子来验证函数X()是从函数Y()而不是从函数Z()调用的吗

使用C语言还是汇编语言

提前谢谢

更新日期:2015年3月2日

  • 假设内核源代码有这么多的驱动程序调用同一个函数,比如SPI(串行Phepheral接口)和GPIO(通用输入输出)的驱动程序源代码调用同一个函数,比如“bzero()”

    空隙b0(空隙*s,尺寸n)

  • 我要测试SPI和GPIO驱动程序(驱动程序代码不能修改)。为此,我编写了测试驱动程序。我只能调用从测试驱动程序公开的函数

    uint8\u t SPI\u read\u write(uint8\u t byte\u out,char*s)//函数1 { bzero(s,sizeof(struct_global1)); 返回字节_in; }

    uint8\u t GPIO\u读写(uint8\u t byte\u out,char*s)//函数2 { bzero(s,sizeof(struct_global2)); 返回字节_in; }

    int main()//测试驱动程序 { SPI_read_write(arg1,arg2);//当我从测试驱动程序调用此函数时,它将调用bzero
    }

  • finction SPI_read_write()和GPIO_read_write()函数都调用“bzero”函数。 我需要确保“bzero”仅在SPI_read_write()函数的任何实例中被调用

  • 更新日期:2017年4月15日 我弄不清楚哪一行?某些函数fun1()可以从其他函数的N个数调用。如何确定调用fun1()的函数


    可能与堆栈、链接寄存器有关

    无法确定调用函数的函数的名称。这完全是设计的,因为函数旨在提供一个抽象,封装独立于调用站点的计算或活动。因此,如果您想知道哪个函数正在调用您的函数,则调用者需要提供此信息

    C99兼容编译器提供了一种确定当前函数名称的方法,可用于传递给目标函数,如下所示:

    #define X() x(__func__)
    
    void x(const char* caller) {
        printf("x() is called from %s()\n", caller);
    }
    void y() {
        X();
    }
    void z() {
        X();
    }
    
    上面的照片

    x() is called from y()
    x() is called from z()
    
    #包括
    #包括
    void打印功能(void*p){
    char-cmd[128];
    文件*fp;
    snprintf(cmd,sizeof(cmd),“addr2line-e%s-f%p”,“print\u caller”,p);
    fp=popen(cmd,“r”);
    if(fp){
    char-buf[128];
    while(fgets(buf、sizeof(buf)、fp)){
    printf(“%s”,buf);
    }
    }
    }
    void Y()
    {
    打印函数(内置返回地址(0));
    }
    void X()
    {
    Y();
    }
    int main()
    {
    X();
    返回0;
    }
    $gcc-g-o print\u caller print\u caller.c
    $/打印\u呼叫方
    X
    /主叫人:24
    

    我还建议您查看手册页,该手册页可以让您更深入地了解如何查看在进入当前函数之前调用的函数

    使其成为与
    X
    相同的翻译单元中的静态函数。如果
    Y
    也在那里,你就不走运了。但坦率地说,我认为这是(字面上)一个问题,你可以使用调试器来检查它,例如,Code::blocks中的内置调试器。使用\uUuBuiltin\uReturn\uAddress检查它?确实是一个XY问题。如果调用链很重要(间接调用呢?),那么代码会被设计破坏。你必须知道每个函数的地址,然后沿着堆栈走下去检查堆栈帧。GNU对它有什么特殊的要求?您使用的是
    \uuu func\uu
    ,它是C99及更高版本中预定义的标识符。也就是说,没有什么可以阻止用户编写
    void Z(void){X(“Y”)}
    ,它对调用
    Y
    @JonathanLeffler的函数撒了谎。非常感谢您的评论。谢谢。在这里,您正在编写自己的函数。你想怎么打就怎么打。那么,在这种情况下,我可以放一个调试消息,看看哪个函数调用了哪个函数?对吗?实际上..在我的情况下,我不能修改任何函数。这是经验法则。我可以调用函数X()或函数Y(),但不允许编辑。
     #include <execinfo.h>
     #include <stdio.h>
    
     void print_function(void *p) {
        char cmd[128];
        FILE *fp;
        snprintf(cmd, sizeof(cmd), "addr2line -e %s -f %p", "print_caller", p);
        fp = popen(cmd, "r");
        if (fp) {
            char buf[128];
            while (fgets(buf, sizeof(buf), fp)) {
               printf("%s", buf);
            }
        }
     }
    
     void Y() 
    {
        print_function(__builtin_return_address(0));
    }
    
    void X()
    {
        Y();
    }
    
    int main()
    {
       X();
       return 0;
    }
    
     $ gcc -g -o print_caller print_caller.c
     $ ./print_caller
     X
     /home/viswesn/print_caller.c:24