Как проверить переменные функций пользовательского пространства в systemtap?

Я столкнулся с проблемой при проверке локальных переменных приложения пользовательского пространства в systemtap.

Я пишу test.c следующим образом:

#include <stdio.h>

int func(int *p, int val)
{
        printf("p=%p val=%d\n", p, val);
        return 1;
}

int main()
{
        int a = 7;
        func(&a, a);
        return 0;
}

и скомпилируйте его с помощью -g

# gcc -g -o test test.c

Systemtap может видеть переменную func(): p и val

# stap -L 'process("./test").function("func")'
process("/home/ryan/Public/test").function("func@/home/ryan/Public/test.c:3") $p:int* $val:int

Поэтому я использую этот stp для просмотра переменных:

# stap -e 'probe process("./test").function("func") {printf("%s(%p, %d)\n", probefunc(), $p, $val)}'

Но локальные переменные неверны в результате при выполнении тестовой программы, она показывает:

func(0x0, 0)

Я использую fedora19 с:

kernel-3.11.9-200.fc19.x86_64
systemtap-sdt-devel-2.3-1.fc19.x86_64
systemtap-2.3-1.fc19.x86_64
systemtap-client-2.3-1.fc19.x86_64
systemtap-devel-2.3-1.fc19.x86_64
systemtap-runtime-2.3-1.fc19.x86_64
gcc-4.8.2-7.fc19.x86_64

Может ли кто-нибудь встретить эту проблему или дать мне решение?


person Jincheng Miao    schedule 25.12.2013    source источник


Ответы (1)


Зонды .function определены так, чтобы срабатывать при входе в функцию. Если вы ищете значения локальных переменных, вам нужно использовать зонды .statement, идентифицирующие исходный файл:номер строки. В этом случае, однако, вы ищете параметры для функции (которая оказалась основана на локальных переменных другой функции). В этом случае подходит зонд .function.

Похоже, вы столкнулись с ошибкой GCC. В простом режиме -g (по иронии судьбы) отладочная информация dwarf иногда неточна для входящих параметров функции. Вместо этого попробуйте "gcc -g -O" или "gcc -g -O2". Поиск пролога Systemtap (stap -P) может помочь. См. также http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51358, https://sourceware.org/bugzilla/show_bug.cgi?id=13420

В случае, если «stap -P» не помогает, вам, возможно, придется прибегнуть к проверке на уровне операторов:

probe process("./test").statement("[email protected]:5") { println($$parms) }

(строка :5 относится к printf)

person fche    schedule 25.12.2013
comment
Спасибо, Фрэнк, ты прав, это ошибка gcc. С скомпилированной опцией '-O' я могу получить правильные значения локальной переменной. При использовании '-O2' локальная переменная int *p будет оптимизирована, поэтому семантическая проверка завершится неудачно. Но для stap -Pe 'probe process(./test).function(func) {printf(%s(%p, %d)\n, probefunc(), $p, $val)}' я все еще могу' не получил правильный ответ, я неправильно его использовал? - person Jincheng Miao; 26.12.2013
comment
Да, я могу получить правильный ответ с помощью оператора даже без оптимизации gcc. Это ошибка gcc, неправильное/отсутствующее местоположение для функции arg, -O0, как указано в заголовке ошибки. Итак, в настоящее время лучший способ проверить переменную функции пользовательского пространства — это использовать зонд оператора. - person Jincheng Miao; 27.12.2013