#include <stdio.h>
int count = 0;
void f() {
count++;
}
int main() {
for (int i=0; i<10000; i++) f();
return count;
}
[maciek@pc loop]$ gdb loop GNU gdb (GDB) Fedora 7.9.1-19.fc22 Reading symbols from loop...done. (gdb) set $i=0 (gdb) b f Breakpoint 1 at 0x40058a: file loop.c, line 10. (gdb) comm >silent >set $i=$i+1 >c >end
(gdb) b loop.c:11 Breakpoint 2 at 0x4005e9: file loop.c, line 11. (gdb) comm >silent >print $i >c >end
(gdb) r $1 = 10000 [Inferior 1 (process 4576) exited with code 020]
global i
probe process("loop").function("f") {i++}
probe process("loop").function("main").return {
printf("%d vs %d\n", i, $return);
delete i;
}
[maciek@pc loop]$ sudo stap loop.stp -c ./loop 10000 vs 10000
response process_path_request(const request& req) {
json j = json::parse(req.data);
auto arr = j["path"];
if (!arr.is_array()) {
return {400, "application/javascript", "{error:'invalid data'}"};
}
std::vector<point> points;
for (auto& el : arr) {
if (!el.is_array() || el.size() != 2) {
return {400, "application/javascript", "{error:'invalid data'}"};
}
double lat = el[0], lon = el[1];
points.emplace_back(spat2xy(lat, lon, ZOOM));
}
std::ostringstream bytes;
cairo_render_path(points, bytes);
return {200, "image/png", bytes.str()};
}
global last_timestamp;
probe process("gis_server").function("process_path_request") {
last_timestamp = gettimeofday_us();
}
probe process("gis_server").statement("*@gis_server.cpp:72") {
d = gettimeofday_us() - last_timestamp;
last_timestamp = gettimeofday_us();
printf("1: %d\n", d);
}
probe process("gis_server").statement("*@gis_server.cpp:86") {
d = gettimeofday_us() - last_timestamp;
last_timestamp = gettimeofday_us();
printf("2: %d\n", d);
}
probe process("gis_server").function("process_path_request").return {
d = gettimeofday_us() - last_timestamp;
last_timestamp = gettimeofday_us();
printf("3: %d\n", d);
}
[maciek@pc exec_time_server]$ sudo stap time.stp -c ./gis_server 100 1: 390 2: 550 3: 31750
global times
global mincount = 100 # training data for 100 samples
global note_percent = 250 # report above 250% change
function check(t) {
if (@count(times[ppfunc()]) >= mincount &&
t >= @max(times[ppfunc()]) * note_percent / 100)
{
printf("function %s well over max time (%d vs %d)\n",
ppfunc(), t, @max(times[ppfunc()]))
}
times[ppfunc()] <<< t
}
probe process("gis_server").function("*@gis_server.cpp").return {
check(gettimeofday_us() - @entry(gettimeofday_us()))
}
[maciek@pc server]$ sudo stap fntimes.stp &
[maciek@pc server]$ for i in {1..110}; do ./gis_server $i; done
[maciek@pc server]$ ./gis_server 10000 function cairo_render_path well over max time (1162531 vs 49436) function process_path_request well over max time (1277363 vs 51414) function main well over max time (1359476 vs 52736) [maciek@pc server]$
probe process("ls").function("*").call {
printf("%s -> %s\n", thread_indent(1), probefunc())
}
probe process("ls").function("*").return {
printf("%s <- %s\n", thread_indent(-1), probefunc())
}
[maciek@pc call_graph]$ sudo stap ls_call_graph.stp -c ls
0 ls(2430): -> _start
25 ls(2430): -> __libc_csu_init
31 ls(2430): -> _init
36 ls(2430): <- __libc_csu_init
40 ls(2430): -> frame_dummy
45 ls(2430): -> register_tm_clones
49 ls(2430): <- __libc_csu_init
52 ls(2430): <- __libc_csu_init
55 ls(2430): <- 0x3073e2068f
59 ls(2430): -> main
63 ls(2430): -> set_program_name
71 ls(2430): <- main
85 ls(2430): -> atexit
90 ls(2430): <- main
106 ls(2430): -> human_options
...
int main() {
ManProcessor c;
std::string line;
while (std::getline(std::cin, line)) {
c.process(line.c_str());
}
}
class ManProcessor {
std::unique_ptr<ManProcessorState> state;
public:
ManProcessor() : state(new IdleState()) {
}
void process(const char* line) {
state->process(*this, line);
}
void setState(ManProcessorState* state) {
this->state.reset(state);
}
};
// ...
void ChapterState::process(ManProcessor& context, const char* line) {
if (std::regex_match(line, std::regex("^[ \t]+[-].*")))
context.setState(new OptionState());
else if (std::regex_match(line, std::regex("^.+$")))
context.setState(new ParagraphState());
}
// ...
probe process("man_state").function("ManProcessor::setState") {
printf("| %s\n", usymname(ustack(1)));
}
[maciek@pc state_machine]$ sudo -E stap state.stp | c++filt & [3] 31614 [maciek@pc state_machine]$ man ls | head -n 20 | ./man_state | IdleState::process(ManProcessor&, char const*) | ChapterState::process(ManProcessor&, char const*) | ParagraphState::process(ManProcessor&, char const*) | ChapterState::process(ManProcessor&, char const*) | ParagraphState::process(ManProcessor&, char const*) | ChapterState::process(ManProcessor&, char const*) | ParagraphState::process(ManProcessor&, char const*) | ChapterState::process(ManProcessor&, char const*) | ParagraphState::process(ManProcessor&, char const*) | ChapterState::process(ManProcessor&, char const*) | OptionState::process(ManProcessor&, char const*) | ChapterState::process(ManProcessor&, char const*)
probe process("man_state").function("*State::process") {
printf(". %s\n", user_string($line));
}
[maciek@pc state_machine]$ sudo -E stap state.stp | c++filt & [3] 31614 [maciek@pc state_machine]$ man ls | head -n 20 | ./man_state . LS(1) . . NAME | IdleState::process(ManProcessor&, char const*) . ls - list directory contents | ChapterState::process(ManProcessor&, char const*) . | ParagraphState::process(ManProcessor&, char const*) . SYNOPSIS | ChapterState::process(ManProcessor&, char const*) . ls [OPTION]... [FILE]...
global cores, core0, core1, core2, core3, names, tasks
probe timer.profile {
tid = tid();
tasks[tid] = execname();
names[tid] = pid2execname(pid());
if (cpu() == 0) core0[tid]++;
if (cpu() == 1) core1[tid]++;
if (cpu() == 2) core2[tid]++;
if (cpu() == 3) core3[tid]++;
cores[tid]++;
}
probe end {
printf("\n %5s %20s %20s %8s %8s %8s %8s\n", "TID", "process",
"task", "core0", "core1", "core2", "core3")
foreach(t in names) {
sum = cores[t]
printf(" %5d %20s %20s, %8s %8s %8s %8s\n", t, names[t], tasks[t],
percent(core0[t], sum), percent(core1[t], sum),
percent(core2[t], sum), percent(core3[t], sum)
);
}
printf("\n");
}
[maciek@pc cpu_core_usage]$ sudo stap proc_cpu4_thread.stp
^C
TID process task core0 core1 core2 core3
0 swapper/1, 41.34% 12.61% 5.5% 40.98%
31610 stapio stapio, 100.0% 0.0% 0.0% 0.0%
73 kswapd0 kswapd0, 0.0% 0.0% 100.0% 0.0%
26953 stapio stapio, 0.0% 0.0% 100.0% 0.0%
2973 Xorg Xorg, 0.0% 83.33% 16.66% 0.0%
18766 gnome-shell gnome-shell, 0.0% 0.0% 6.55% 93.44%
18871 gnome-shell gdbus, 0.0% 100.0% 0.0% 0.0%
17630 firefox DOM Worker, 28.57% 0.0% 71.42% 0.0%
17605 firefox JS Helper, 100.0% 0.0% 0.0% 0.0%
4305 ruby-mri utils.rb:162, 100.0% 0.0% 0.0% 0.0%
15 ksoftirqd/1 ksoftirqd/1, 0.0% 100.0% 0.0% 0.0%
17640 firefox DOM Worker, 0.0% 0.0% 0.0% 100.0%
7 rcu_sched rcu_sched, 0.0% 50.0% 0.0% 50.0%
24063 kworker/u16:0 kworker/u16:0, 0.0% 33.33% 66.66% 0.0%
9 rcuos/0 rcuos/0, 0.0% 0.0% 100.0% 0.0%
1 systemd systemd, 0.0% 0.0% 100.0% 0.0%
751 systemd-login systemd-logind, 0.0% 0.0% 0.0% 100.0%
23764 kworker/2:3 kworker/2:3, 0.0% 0.0% 100.0% 0.0%
757 irqbalance irqbalance, 0.0% 0.0% 100.0% 0.0%
probe process("/usr/lib64/libpthread.so.0").function("pthread_mutex_init").return {
uaddr = &$mutex->__data->__lock
lock_names[uaddr] = usymfileline(ustack(1));
}
probe syscall.futex.return {
if (target() != pid()) next;
if (($op & ~(FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME)) != FUTEX_WAIT) next
elapsed = gettimeofday_us() - @entry(gettimeofday_us())
lock_waits[$uaddr] <<< elapsed
}
probe end {
foreach (lock in lock_names) {
printf ("%s[%x] lock contended %d times, %d avg us\n",
lock_names[lock], lock, @count(lock_waits[lock]),
@avg(lock_waits[lock]))
print(@hist_log(lock_waits[lock]));
}
}
[maciek@pc futex2]$ sudo stap -v futex.stp -d ./test1 -c ./test1 test1.cpp:8[6124c0] lock contended 95 times, 37467 avg us value |-------------------------------------------------- count 256 | 0 512 |@ 1 1024 | 0 2048 |@@ 2 4096 |@@@@@@@ 7 8192 |@@@@@@@@@@@@@@ 14 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 32 32768 |@@@@@@@@@@@@@@@ 15 65536 |@@@@@@@@@@@@@@@@@@@@@@@@ 24 131072 | 0 net_socket.cpp:4[7ffff0014aa0] lock contended 4 times, 1512 avg us value |-------------------------------------------------- count 256 | 0 512 |@@ 2 1024 |@ 1 2048 |@ 1 4096 | 0 voice_manager.cpp:4[7ffff0014ad0] lock contended 93 times, 56146 avg us ...
function test:long(addr:long) %{
char buffer[100];
long a = strncpy_from_user(buffer, (char*)STAP_ARG_addr, 100);
char *substr = strnstr(buffer, "stap sucks", 100);
if (substr != NULL) {
long b = copy_to_user(
((char*)STAP_ARG_addr)+(substr+5-&buffer[0]),"rocks", 5);
}
%}
probe syscall.write {
if (isinstr(user_string($buf), "stap sucks")) {
test($buf);
}
}
[maciek@pc sys_write]$ echo "I think that stap sucks" I think that stap rocks
[maciek@pc sys_write]$ history | tail -2 1123 echo "I think that stap rocks" 1124 history | tail -2
[maciek@pc sys_write]$ vim tmp
stap sucks ~ ~ ~ ~ ~ :wq
[maciek@pc sys_write]$ cat tmp stap rocks
Use a spacebar or arrow keys to navigate