Sindbad~EG File Manager
#!/usr/bin/stap
// configuration options
global follow_fork = 0 // -Gfollow_fork=1 means trace descendant processes too
global count = 0 // -Gcount=1 means summarize time and calls for each library call */
global report_line%
global report_line_returnval%
global func_time%
global func_time_total%
global func_calls%
global calls_nonreturn
probe begin
{
// list of calls that never .return
calls_nonreturn["__libc_start_main"]=1
}
function filter_p()
{
// from strace.stp
if (target() == 0) return 0;
if (!follow_fork && pid() != target()) return 1;
if (follow_fork && !target_set_pid(pid())) return 1;
return 0;
}
function arg:string (arg1:long) {
if (arg1 < 255)
return sprintf("%d", arg1)
else
return sprintf("%#lx", arg1)
}
function report (rl)
{
printf("%s", report_line[rl])
rll = strlen(report_line[rl])
n_tabs = ((64 - rll) / 8)
if (rll % 8 == 0)
n_tabs -= 1
if (rll <= 64)
for (i=0; i < n_tabs; i++)
{
printf("\t")
}
}
probe process.plt, process.library("*").plt
{
if (filter_p()) next;
if (strlen($$name) == 0) next;
if ($$name in calls_nonreturn)
next
if (count) // -Gcount=1
{
func_calls[$$name] <<< 1
func_time[$$name]=gettimeofday_us()
next
}
%( arch == "x86_64" %?
outline = sprintf("%s (%s, %s, %s, %s)", $$name, arg(register("rdi")), arg(register("rsi")), arg(register("rdx")), arg(register("rcx")))
%)
%( arch == "i386" %?
outline = sprintf("%s[%d] %s (%s, %s, %s, %s)", execname(), tid(), $$name, arg(register("edi")), arg(register("esi")), arg(register("edx")), arg(register("ecx")))
%)
report_line[$$name] = outline
}
probe process.plt.return, process.library("*").plt.return
{
if (filter_p()) next;
if (strlen($$name) == 0) next;
// cache cumulative time spent in each call
if (count)
{
now = gettimeofday_us()
then = func_time[$$name]
func_time_total[$$name] += now-then
delete func_time[$$name]
next
}
report_line_returnval[$$name] = arg(retval)
foreach (rl in report_line) {
first_key = rl
break
}
// if we have nested calls then wait for the return of the first call
if ($$name == first_key)
{
foreach (rl in report_line)
{
report (rl)
printf ("=%s\n", report_line_returnval[rl])
}
delete report_line
delete report_line_returnval
}
}
probe end
{
if (count)
{
cumulative_time = 0
printf ("%% time seconds calls\n")
printf ( "------ --------- -------\n")
foreach (ttt in func_time_total)
{
cumulative_time += func_time_total[ttt]
}
foreach (ttt in func_time_total)
{
percent = (func_time_total[ttt] * 100) / cumulative_time
if (percent > 0)
{
printf("%5d%% ", percent)
printf("%14d ", func_time_total[ttt]%1000000)
printf("%10d ", @count(func_calls[ttt]))
printf(" %s\n",ttt)
}
}
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists