systemtap全局变量分配失败

时间:2015-05-21 07:36:28

标签: linux linux-kernel systemtap

我想使用systemtap来提取我的linux生产服务器的详细信息。我的systemtap脚本是

global bt;
global quit = 0

probe begin {
    printf("start profiling...\n")
}
probe timer.profile {
    if (pid() == target()) {
        if (!quit) 
        {
            bt[backtrace(), ubacktrace()] <<< 1
        } 
        else 
        {

            foreach ([sys, usr] in bt- limit 1000) 
            {
                print_stack(sys)
                print_ustack(usr)
                printf("\t%d\n", @count(bt[sys, usr]))
            }
            exit()
        }
    }
}

probe timer.s(20) {
    quit = 1
}

当我开始使用命令

运行此脚本时
sudo stap --ldd -d $program_name --all-modules                  \
    -D MAXMAPENTRIES=10240 -D MAXACTION=20000 -D MAXTRACE=40    \
    -D MAXSTRINGLEN=4096 -D MAXBACKTRACE=40 -x $program_pid     \
    profile.stp  --vp 00001 > profile.out

失败,并打印出错误:

ERROR: error allocating hash
ERROR: global variable 'bt' allocation failed
WARNING: /usr/bin/staprun exited with status: 1

我的生产服务器内存信息是

             total       used       free     shared    buffers     cached
Mem:         16008      15639        368          0         80       3090
-/+ buffers/cache:      12468       3539

我认为这已经足够了,因为在我的测试服务器中,只有2G内存,而systemtap脚本可以很好地运行另一台服务器

1 个答案:

答案 0 :(得分:1)

不幸的是,这是预期的行为,请参阅我在此处的讨论:https://sourceware.org/ml/systemtap/2015-q1/msg00033.html

问题是SystemTap一次分配关联数组(以防止将来分配失败)和基于每个cpu(防止锁定),这意味着bt将需要(2 * MAXSTRINGLEN + sizeof(statistic)) * MAXMAPENTRIES * NR_CPU =〜如果NR_CPU == 128,则为2 Gb。

减少MAXSTRINGLEN(在您的情况下设置为4k)或bt数组的大小:

global bt[128];