基于gcc plugin机制,编译源码时在每个函数前插入一条指令,打印当前的调用栈,省去了修改源码的时间

基于gcc plugin机制,编译源码时在每个函数前插入一条指令,打印当前的调用栈,省去了修改源码的时间

在学习开源库时,想了解它的调用流程,可以使用valgrind的callgrind功能。这里介绍另一种方法,gcc有一种plugin机制,可以利用这种机制在编译源码时,在函数中插入call指令,调用自己的api调用,咱们在这个函数中调用libunwind获取调用栈信息.
可以参考 基于torch_dispatch机制生成Megatron-DeepSpeed调用关系图 生成整个工程的调用关系图

一.安装依赖

gcc --version
#gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
apt install gcc-11-plugin-dev
apt install libunwind-dev -y

二.gcc插件源码

cat > gcc_backtrace_plugin.c <<-'EOF'
#include <gcc-plugin.h>
#include <plugin-version.h>
#include <tree.h>
#include <context.h>
#include <tree-pass.h>
#include <function.h>
#include <gimple.h>
#include <gimple-iterator.h>
#include <basic-block.h>
#include <diagnostic.h>

int plugin_is_GPL_compatible;

namespace {
   
   
    const pass_data print_backtrace_pass_data = {
   
   
        GIMPLE_PASS,                           // 传递类型
        "insert_print_backtrace_pass",         // 传递名
        OPTGROUP_NONE,                         // 优化组
        TV_NONE,                               // 计时器变量
        PROP_gimple_any,                       // 所需属性
        0,                                     // 提供属性
        0,                                     // 清理属性
        0,                                     // 可见性标志
    };

    struct print_backtrace_pass : gimple_opt_pass {
   
   
        print_backtrace_pass(gcc::context *ctx)
            : gimple_opt_pass(print_backtrace_pass_data, ctx)
        {
   
   }

        unsigned int execute(function *fun) override;
    };
}

unsigned int print_backtrace_pass::execute(function *fun) {
   
   
    basic_block bb;
    gimple_stmt_iterator gsi;
    gimple *call_stmt;
    tree print_backtrace_fn = NULL;
    
    tree void_type = void_type_node;
    tree char_ptr_type = build_pointer_type(char_type_node);
    tree fntype = build_function_type(void_type
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hi20240217

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值