В этой статье не планирую ставить никакого задания. Просто буду собирать полезные сценарии из интернета и возможно - описывать свои. А так же вставлю ссылки на полезные статьи по исследованию и описанию работы некоторых функций glibc, для дальнейшей возможности обследования их через systemtap.
Сценарий 1
Интересный скрипт, позволяющий остановить выполнение программы в нужном месте и запустить gdb
#!/bin/stap -g
global gdbRunning = 0;
probe process(@1).mark(@2)
{
raise(%{ SIGSTOP %});
gdbCmd = sprintf("cgdb -- -q -ex 'thread find %d' %s %d", tid(), @1, pid());
if (gdbRunning == 0)
{
gdbRunning = 1;
printf("STOP PID %d TID %d [%s]\n", pid(), tid(), gdbCmd);
system(gdbCmd);
}
else
{
printf("STOP PID %d TID %d\n", pid(), tid());
}
}
в качестве первого параметра задается имя программы или библиотеки или PID, в качестве второго параметра имя функции, место файла. Из нового в синтаксисе использования systemtap, это использование команды raise Взято отсюда: http://stackoverflow.com/questions/20492308/can-a-process-be-stopped-via-a-systemtap-probe-so-gdb-can-be-attached
Статья о malloc
Статья детальная, но на английском: https://developers.redhat.com/blog/2014/10/02/understanding-malloc-behavior-using-systemtap-userspace-probes/ полное название: Understanding malloc behavior using Systemtap userspace probes
Сценарий 2
Исследование захватов Mutex в User Space
#! /usr/bin/env stap
# This script tries to identify contended user-space locks by hooking
# into the futex system call.
global FUTEX_WAIT = 0 /*, FUTEX_WAKE = 1 */
global FUTEX_PRIVATE_FLAG = 128 /* linux 2.6.22+ */
global FUTEX_CLOCK_REALTIME = 256 /* linux 2.6.29+ */
global lock_waits # long-lived stats on (tid,lock) blockage elapsed time
global process_names # long-lived pid-to-execname mapping
probe syscall.futex.return {
if (($op & ~(FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME)) != FUTEX_WAIT) next
process_names[pid()] = execname()
elapsed = gettimeofday_us() - @entry(gettimeofday_us())
lock_waits[pid(), $uaddr] <<< elapsed
}
probe end {
foreach ([pid+, lock] in lock_waits)
printf ("%s[%d] lock %p contended %d times, %d avg us\n",
process_names[pid], pid, lock, @count(lock_waits[pid,lock]),
@avg(lock_waits[pid,lock]))
}
Взято отсюда https://sourceware.org/systemtap/SystemTap_Beginners_Guide/futexcontentionsect.html
Как распечатать содержимое передаваемое в функции не только в виде указатилей, но и провести разименовывание типов
Ранее уже опиминались опрделения для pretty printing
$$vars
Expands to a character string that is equivalent to sprintf("parm1=%x ... parmN=%x var1=%x ... varN=%x",
parm1, ..., parmN, var1, ..., varN) for each variable in scope at the probe point. Some values may be printed as “=?” if their run-time location cannot be found.
$$locals
Expands to a subset of $$vars containing only the local variables.
$$parms
Expands to a subset of $$vars containing only the function parameters.
$$return
Is available in return probes only. It expands to a string that is equivalent to sprintf("return=%x", $return) if the probed function has a return value, or else an empty string.
если вызвать stap -e 'probe kernel.function("vfs_read") {printf("%s\n", $$parms); exit(); }'
то получим file=0xffff8800b40d4c80 buf=0x7fff634403e0 count=0x2004 pos=0xffff8800af96df48
, что не дает прдеставления, а что же содерат указатели. Если в конце pretty print определения добавить $$, то можно получить и содержимое указателей:
stap -e 'probe kernel.function("vfs_read") {printf("%s\n", $$parms$$); exit(); }'
получаем
file={.f_u={.fu_list={.next=0xffff8801336ca0e8, .prev=0xffff88012ded0840}, .fu_rcuhead={.next=0xffff8801336ca0e8, .func=0xffff88012ded0840}}, .f_path={.mnt=0xffff880132fc97c0, .dentry=0xffff88001a889cc0}, .f_op=0xffffffffa06f64c0, .f_lock={.raw_lock={.slock=196611}}, .f_count={.counter=2}, .f_flags=34818, .f_mode=31, .f_pos=0, .f_owner={.lock={.raw_lock={.lock=16777216}}, .pid=0x0, .pid_type=0, .uid=0, .euid=0, .signum=0}, .f_cred=0xffff880130129a80, .f_ra={.start=0, .size=0, .async_size=0, .ra_pages=32, .
Так уже лучше.
Взято отсюда: https://sourceware.org/systemtap/SystemTap_Beginners_Guide/targetvariables.html