Не удалось выделить глобальную переменную 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

Думаю достаточно, т.к. на моем тестовом сервере памяти всего 2Гб, а скрипт systemtap хорошо работает на другом сервере


person user2366736    schedule 21.05.2015    source источник
comment
мое ядро ​​Linux 2.6.18-308.el5, Linux CentOS 5.5, версия systemstap 1.8/0.152 исходники не-git   -  person user2366736    schedule 21.05.2015


Ответы (1)


К сожалению, это предполагаемое поведение, см. мое обсуждение здесь: https://sourceware.org/ml/systemtap/2015-q1/msg00033.html

Проблема в том, что SystemTap выделяет ассоциативные массивы одновременно (для предотвращения сбоев выделения в будущем) и попроцессорно (для предотвращения блокировок), а это значит, что bt потребуется (2 * MAXSTRINGLEN + sizeof(statistic)) * MAXMAPENTRIES * NR_CPU =~ 2 Гб, если NR_CPU == 128.

Уменьшите MAXSTRINGLEN (в вашем случае установлено значение 4k) или размер массива bt:

global bt[128];
person myaut    schedule 21.05.2015
comment
Я использую ваш метод и запускаю скрипт. Я вижу результат профиля, но по-прежнему появляется ошибка ПРЕДУПРЕЖДЕНИЕ: нет или плохой кадр отладки hdr ПРЕДУПРЕЖДЕНИЕ: нет таблицы двоичного поиска для кадра отладки, выполняется медленный линейный поиск для xt_length ОШИБКА: пропущено слишком много зондов, проверьте MAXSKIPPED или повторите попытку с помощью stap - т для более подробной информации. - person user2366736; 21.05.2015
comment
Это другая ошибка и проблема с размотчиком DWARF. Попробуйте свежее ядро ​​со свежей отладочной информацией... - person myaut; 21.05.2015