This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
utrace probe example
- From: David Smith <dsmith at redhat dot com>
- To: Systemtap List <systemtap at sources dot redhat dot com>
- Date: Thu, 08 May 2008 12:49:35 -0500
- Subject: utrace probe example
Here's a utrace probe example. This shows the promise (and the current
limitations) of utrace probes. It acts as a "mini" strace - "mini"
because it can only decode arguments for 3 system calls: open(), read(),
and close(). It does print the name (but not the arguments) of every
other system call.
Currently it handles i686 and x86_64 (32-bit executables or 64-bit
executables).
Right now it is set up to probe /bin/cat.
--
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)
%{
#include <linux/unistd.h>
/* Only works for x86/x86_64 */
static inline long *user_syscall_arg(struct task_struct *task,
struct pt_regs *regs, int n)
{
#ifdef CONFIG_X86_32
BUG_ON(n > 5);
# if defined (STAPCONF_X86_UNIREGS)
return ®s->bx + n;
# else
return ®s->ebx + n;
# endif /* STAPCONF_X86_UNIREGS */
#else
# ifdef CONFIG_IA32_EMULATION
if (test_tsk_thread_flag(task, TIF_IA32))
switch (n) {
# if defined (STAPCONF_X86_UNIREGS)
case 0: return ®s->bx;
case 1: return ®s->cx;
case 2: return ®s->dx;
case 3: return ®s->si;
case 4: return ®s->di;
case 5: return ®s->bp;
# else
case 0: return ®s->rbx;
case 1: return ®s->rcx;
case 2: return ®s->rdx;
case 3: return ®s->rsi;
case 4: return ®s->rdi;
case 5: return ®s->rbp;
# endif /* STAPCONF_X86_UNIREGS */
default: BUG();
}
# endif /* CONFIG_IA32_EMULATION */
switch (n) {
# if defined (STAPCONF_X86_UNIREGS)
case 0: return ®s->di;
case 1: return ®s->si;
case 2: return ®s->dx;
case 3: return ®s->r10;
case 4: return ®s->r8;
case 5: return ®s->r9;
# else
case 0: return ®s->rdi;
case 1: return ®s->rsi;
case 2: return ®s->rdx;
case 3: return ®s->r10;
case 4: return ®s->r8;
case 5: return ®s->r9;
# endif /* STAPCONF_X86_UNIREGS */
default: BUG();
}
#endif /* CONFIG_X86_32 */
return NULL;
}
/* Only works for x86/x86_64 */
static inline long *user_syscall_return_value(struct task_struct *task,
struct pt_regs *regs)
{
#ifdef CONFIG_X86_32
# if defined (STAPCONF_X86_UNIREGS)
return ®s->ax;
# else
return ®s->eax;
# endif /* STAPCONF_X86_UNIREGS */
#else
# ifdef CONFIG_IA32_EMULATION
if (test_tsk_thread_flag(task, TIF_IA32))
/*
* Sign-extend the value so (int)-EFOO becomes (long)-EFOO
* and will match correctly in comparisons.
*/
# if defined (STAPCONF_X86_UNIREGS)
regs->ax = (long) (int) regs->ax;
# else
regs->rax = (long) (int) regs->rax;
# endif /* STAPCONF_X86_UNIREGS */
# endif /* CONFIG_IA32_EMULATION */
# if defined (STAPCONF_X86_UNIREGS)
return ®s->ax;
# else
return ®s->rax;
# endif /* STAPCONF_X86_UNIREGS */
#endif /* CONFIG_X86_32 */
}
%}
function get_syscall_arg:long(n:long)
%{ /* pure */
if (THIS->n > 5 || THIS->n < 0) {
snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
"invalid getn_syscall_arg requested of %lld",
THIS->n);
CONTEXT->last_error = CONTEXT->error_buffer;
return;
}
THIS->__retvalue = (int64_t) (long) \
kread(user_syscall_arg(current, CONTEXT->regs, THIS->n));
CATCH_DEREF_FAULT();
%}
function get_syscall_return_value:long()
%{ /* pure */
THIS->__retvalue = (int64_t) (long) \
kread(user_syscall_return_value(current, CONTEXT->regs));
CATCH_DEREF_FAULT();
%}
function syscall_decode:string(syscall:long)
%{ /* pure */
char *name;
#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
const char * const x86_32[] = {
/* 0 */
"restart_syscall", "_exit", "fork", "read", "write",
/* 5 */
"open", "close", "waitpid", "creat", "link",
/* 10 */
"unlink", "execve", "chdir", "time", "mknod",
/* 15 */
"chmod", "lchown", "break", "oldstat", "lseek",
/* 20 */
"getpid", "mount", "oldumount", "setuid", "getuid",
/* 25 */
"stime", "ptrace", "alarm", "oldfstat", "pause",
/* 30 */
"utime", "stty", "gtty", "access", "nice",
/* 35 */
"ftime", "sync", "kill", "rename", "mkdir",
/* 40 */
"rmdir", "dup", "pipe", "times", "prof",
/* 45 */
"brk", "setgid", "getgid", "signal", "geteuid",
/* 50 */
"getegid", "acct", "umount", "lock", "ioctl",
/* 55 */
"fcntl", "mpx", "setpgid", "ulimit", "oldolduname",
/* 60 */
"umask", "chroot", "ustat", "dup2", "getppid",
/* 65 */
"getpgrp", "setsid", "sigaction", "siggetmask", "sigsetmask",
/* 70 */
"setreuid", "setregid", "sigsuspend", "sigpending", "sethostname",
/* 75 */
"setrlimit", "old_getrlimit", "getrusage", "gettimeofday", "settimeofday",
/* 80 */
"getgroups", "setgroups", "oldselect", "symlink", "oldlstat",
/* 85 */
"readlink", "uselib", "swapon", "reboot", "readdir",
/* 90 */
"old_mmap", "munmap", "truncate", "ftruncate", "fchmod",
/* 95 */
"fchown", "getpriority", "setpriority", "profil", "statfs",
/* 100 */
"fstatfs", "ioperm", "socketcall", "syslog", "setitimer",
/* 105 */
"getitimer", "stat", "lstat", "fstat", "olduname",
/* 110 */
"iopl", "vhangup", "idle", "vm86old", "wait4",
/* 115 */
"swapoff", "sysinfo", "ipc", "fsync", "sigreturn",
/* 120 */
"clone", "setdomainname", "uname", "modify_ldt", "adjtimex",
/* 125 */
"mprotect", "sigprocmask", "create_module", "init_module", "delete_module",
/* 130 */
"get_kernel_syms", "quotactl", "getpgid", "fchdir", "bdflush",
/* 135 */
"sysfs", "personality", "afs_syscall", "setfsuid", "setfsgid",
/* 140 */
"_llseek", "getdents", "select", "flock", "msync",
/* 145 */
"readv", "writev", "getsid", "fdatasync", "_sysctl",
/* 150 */
"mlock", "munlock", "mlockall", "munlockall", "sched_setparam",
/* 155 */
"sched_getparam", "sched_setscheduler", "sched_getscheduler", "sched_yield", "sched_get_priority_max",
/* 160 */
"sched_get_priority_min", "sched_rr_get_interval", "nanosleep", "mremap", "setresuid",
/* 165 */
"getresuid", "vm86", "query_module", "poll", "nfsservctl",
/* 170 */
"setresgid", "getresgid", "prctl", "rt_sigreturn", "rt_sigaction",
/* 175 */
"rt_sigprocmask", "rt_sigpending", "rt_sigtimedwait", "rt_sigqueueinfo", "rt_sigsuspend",
/* 180 */
"pread64", "pwrite64", "chown", "getcwd", "capget",
/* 185 */
"capset", "sigaltstack", "sendfile", "getpmsg", "putpmsg",
/* 190 */
"vfork", "getrlimit", "mmap2", "truncate64", "ftruncate64",
/* 195 */
"stat64", "lstat64", "fstat64", "lchown32", "getuid32",
/* 200 */
"getgid32", "geteuid32", "getegid32", "setreuid32", "setregid32",
/* 205 */
"getgroups32", "setgroups32", "fchown32", "setresuid32", "getresuid32",
/* 210 */
"setresgid32", "getresgid32", "chown32", "setuid32", "setgid32",
/* 215 */
"setfsuid32", "setfsgid32", "pivot_root", "mincore", "madvise",
/* 220 */
"getdents64", "fcntl64", "SYS_222", "security", "gettid",
/* 225 */
"readahead", "setxattr", "lsetxattr", "fsetxattr", "getxattr",
/* 230 */
"lgetxattr", "fgetxattr", "listxattr", "llistxattr", "flistxattr",
/* 235 */
"removexattr", "lremovexattr", "fremovexattr", "tkill", "sendfile64",
/* 240 */
"futex", "sched_setaffinity", "sched_getaffinity", "set_thread_area", "get_thread_area",
/* 245 */
"io_setup", "io_destroy", "io_getevents", "io_submit", "io_cancel",
/* 250 */
"fadvise64", "SYS_251", "exit_group", "lookup_dcookie", "epoll_create",
/* 255 */
"epoll_ctl", "epoll_wait", "remap_file_pages", "set_tid_address", "timer_create",
/* 260 */
"timer_settime", "timer_gettime", "timer_getoverrun", "timer_delete", "clock_settime",
/* 265 */
"clock_gettime", "clock_getres", "clock_nanosleep", "statfs64", "fstatfs64",
/* 270 */
"tgkill", "utimes", "fadvise64_64", "vserver", "mbind",
/* 275 */
"get_mempolicy", "set_mempolicy", "mq_open", "mq_unlink", "mq_timedsend",
/* 280 */
"mq_timedreceive", "mq_notify", "mq_getsetattr", "sys_kexec_load", "waitid",
/* 285 */
"SYS_285", "add_key", "request_key", "keyctl", "ioprio_set",
/* 290 */
"ioprio_get", "inotify_init", "inotify_add_watch", "inotify_rm_watch", "migrate_pages",
/* 295 */
"openat", "mkdirat", "mknodat", "fchownat", "futimesat",
/* 300 */
"fstatat64", "unlinkat", "renameat", "linkat", "symlinkat",
/* 305 */
"readlinkat", "fchmodat", "faccessat", "pselect6", "ppoll",
/* 310 */
"unshare", "set_robust_list", "get_robust_list", "splice", "sync_file_range",
/* 315 */
"tee", "vmsplice", "move_pages", "getcpu", "epoll_pwait",
/* 320 */
"utimensat", "signalfd", "timerfd", "eventfd", "SYS_324",
/* 325 */
"SYS_325", "SYS_326", "SYS_327", "SYS_328", "SYS_329",
/* 330 */
"SYS_330", "SYS_331", "SYS_332", "SYS_333", "SYS_334",
/* 335 */
"SYS_335", "SYS_336", "SYS_337", "SYS_338", "SYS_339",
/* 340 */
"SYS_340", "SYS_341", "SYS_342", "SYS_343", "SYS_344",
/* 345 */
"SYS_345", "SYS_346", "SYS_347", "SYS_348", "SYS_349",
/* 350 */
"SYS_350", "SYS_351", "SYS_352", "SYS_353", "SYS_354",
/* 355 */
"SYS_355", "SYS_356", "SYS_357", "SYS_358", "SYS_359",
/* 360 */
"SYS_360", "SYS_361", "SYS_362", "SYS_363", "SYS_364",
/* 365 */
"SYS_365", "SYS_366", "SYS_367", "SYS_368", "SYS_369",
/* 370 */
"SYS_370", "SYS_371", "SYS_372", "SYS_373", "SYS_374",
/* 375 */
"SYS_375", "SYS_376", "SYS_377", "SYS_378", "SYS_379",
/* 380 */
"SYS_380", "SYS_381", "SYS_382", "SYS_383", "SYS_384",
/* 385 */
"SYS_385", "SYS_386", "SYS_387", "SYS_388", "SYS_389",
/* 390 */
"SYS_390", "SYS_391", "SYS_392", "SYS_393", "SYS_394",
/* 395 */
"SYS_395", "SYS_396", "SYS_397", "SYS_398", "SYS_399",
/* 400 */
"socket_subcall", "socket", "bind", "connect", "listen",
/* 405 */
"accept", "getsockname", "getpeername", "socketpair", "send",
/* 410 */
"recv", "sendto", "recvfrom", "shutdown", "setsockopt",
/* 415 */
"getsockopt", "sendmsg", "recvmsg", "ipc_subcall", "semop",
/* 420 */
"semget", "semctl", "semtimedop", "ipc_subcall", "ipc_subcall",
/* 425 */
"ipc_subcall", "ipc_subcall", "ipc_subcall", "ipc_subcall", "msgsnd",
/* 430 */
"msgrcv", "msgget", "msgctl", "ipc_subcall", "ipc_subcall",
/* 435 */
"ipc_subcall", "ipc_subcall", "ipc_subcall", "ipc_subcall", "shmat",
/* 440 */
"shmdt", "shmget", "shmctl",
};
#endif /* CONFIG_X86_32 || CONFIG_IA32_EMULATION */
#ifdef CONFIG_X86_64
const char * const x86_64[] = {
/* 0 */
"read", "write", "open", "close", "stat",
/* 5 */
"fstat", "lstat", "poll", "lseek", "mmap",
/* 10 */
"mprotect", "munmap", "brk", "rt_sigaction", "rt_sigprocmask",
/* 15 */
"rt_sigreturn", "ioctl", "pread", "pwrite", "readv",
/* 20 */
"writev", "access", "pipe", "select", "sched_yield",
/* 25 */
"mremap", "msync", "mincore", "madvise", "shmget",
/* 30 */
"shmat", "shmctl", "dup", "dup2", "pause",
/* 35 */
"nanosleep", "getitimer", "alarm", "setitimer", "getpid",
/* 40 */
"sendfile", "socket", "connect", "accept", "sendto",
/* 45 */
"recvfrom", "sendmsg", "recvmsg", "shutdown", "bind",
/* 50 */
"listen", "getsockname", "getpeername", "socketpair", "setsockopt",
/* 55 */
"getsockopt", "clone", "fork", "vfork", "execve",
/* 60 */
"_exit", "wait4", "kill", "uname", "semget",
/* 65 */
"semop", "semctl", "shmdt", "msgget", "msgsnd",
/* 70 */
"msgrcv", "msgctl", "fcntl", "flock", "fsync",
/* 75 */
"fdatasync", "truncate", "ftruncate", "getdents", "getcwd",
/* 80 */
"chdir", "fchdir", "rename", "mkdir", "rmdir",
/* 85 */
"creat", "link", "unlink", "symlink", "readlink",
/* 90 */
"chmod", "fchmod", "chown", "fchown", "lchown",
/* 95 */
"umask", "gettimeofday", "getrlimit", "getrusage", "sysinfo",
/* 100 */
"times", "ptrace", "getuid", "syslog", "getgid",
/* 105 */
"setuid", "setgid", "geteuid", "getegid", "setpgid",
/* 110 */
"getppid", "getpgrp", "setsid", "setreuid", "setregid",
/* 115 */
"getgroups", "setgroups", "setresuid", "getresuid", "setresgid",
/* 120 */
"getresgid", "getpgid", "setfsuid", "setfsgid", "getsid",
/* 125 */
"capget", "capset", "rt_sigpending", "rt_sigtimedwait", "rt_sigqueueinfo",
/* 130 */
"rt_sigsuspend", "sigaltstack", "utime", "mknod", "uselib",
/* 135 */
"personality", "ustat", "statfs", "fstatfs", "sysfs",
/* 140 */
"getpriority", "setpriority", "sched_setparam", "sched_getparam", "sched_setscheduler",
/* 145 */
"sched_getscheduler", "sched_get_priority_max", "sched_get_priority_min", "sched_rr_get_interval", "mlock",
/* 150 */
"munlock", "mlockall", "munlockall", "vhangup", "modify_ldt",
/* 155 */
"pivot_root", "_sysctl", "prctl", "arch_prctl", "adjtimex",
/* 160 */
"setrlimit", "chroot", "sync", "acct", "settimeofday",
/* 165 */
"mount", "umount", "swapon", "swapoff", "reboot",
/* 170 */
"sethostname", "setdomainname", "iopl", "ioperm", "create_module",
/* 175 */
"init_module", "delete_module", "get_kernel_syms", "query_module", "quotactl",
/* 180 */
"nfsservctl", "getpmsg", "putpmsg", "afs_syscall", "tuxcall",
/* 185 */
"security", "gettid", "readahead", "setxattr", "lsetxattr",
/* 190 */
"fsetxattr", "getxattr", "lgetxattr", "fgetxattr", "listxattr",
/* 195 */
"llistxattr", "flistxattr", "removexattr", "lremovexattr", "fremovexattr",
/* 200 */
"tkill", "time", "futex", "sched_setaffinity", "sched_getaffinity",
/* 205 */
"set_thread_area", "io_setup", "io_destroy", "io_getevents", "io_submit",
/* 210 */
"io_cancel", "get_thread_area", "lookup_dcookie", "epoll_create", "epoll_ctl_old",
/* 215 */
"epoll_wait_old", "remap_file_pages", "getdents64", "set_tid_address", "restart_syscall",
/* 220 */
"semtimedop", "fadvise64", "timer_create", "timer_settime", "timer_gettime",
/* 225 */
"timer_getoverrun", "timer_delete", "clock_settime", "clock_gettime", "clock_getres",
/* 230 */
"clock_nanosleep", "exit_group", "epoll_wait", "epoll_ctl", "tgkill",
/* 235 */
"utimes", "vserver", "mbind", "set_mempolicy", "get_mempolicy",
/* 240 */
"mq_open", "mq_unlink", "mq_timedsend", "mq_timedreceive", "mq_notify",
/* 245 */
"mq_getsetattr", "kexec_load", "waitid", "add_key", "request_key",
/* 250 */
"keyctl", "ioprio_set", "ioprio_get", "inotify_init", "inotify_add_watch",
/* 255 */
"inotify_rm_watch", "migrate_pages", "openat", "mkdirat", "mknodat",
/* 260 */
"fchownat", "futimesat", "newfstatat", "unlinkat", "renameat",
/* 265 */
"linkat", "symlinkat", "readlinkat", "fchmodat", "faccessat",
/* 270 */
"pselect6", "ppoll", "unshare", "set_robust_list", "get_robust_list",
/* 275 */
"splice", "sync_file_range", "tee", "vmsplice", "move_pages",
/* 280 */
"utimensat", "epoll_pwait", "signalfd", "timerfd", "eventfd",
};
#endif /* CONFIG_X86_64 */
#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
# if defined(CONFIG_IA32_EMULATION)
if (test_tsk_thread_flag(current, TIF_IA32)) {
# endif /* CONFIG_IA32_EMULATION */
if (THIS->syscall < 0
|| THIS->syscall > (sizeof(x86_32)/sizeof(x86_32[0]))) {
snprintf (CONTEXT->error_buffer,
sizeof(CONTEXT->error_buffer),
"invalid syscall number %lld",
THIS->syscall);
CONTEXT->last_error = CONTEXT->error_buffer;
}
else {
strlcpy(THIS->__retvalue, x86_32[THIS->syscall],
MAXSTRINGLEN);
}
# if defined(CONFIG_IA32_EMULATION)
return;
}
# endif /* CONFIG_IA32_EMULATION */
#endif /* CONFIG_X86_32 || CONFIG_IA32_EMULATION */
#ifdef CONFIG_X86_64
if (THIS->syscall < 0
|| THIS->syscall > (sizeof(x86_64)/sizeof(x86_64[0]))) {
snprintf (CONTEXT->error_buffer,
sizeof(CONTEXT->error_buffer),
"invalid syscall number %lld",
THIS->syscall);
CONTEXT->last_error = CONTEXT->error_buffer;
}
else {
strlcpy(THIS->__retvalue, x86_64[THIS->syscall],
MAXSTRINGLEN);
}
#endif
%}
function open_parse_flags_and_mode:string(flags:long, mode:long)
%{ /* pure */
#define HANDLE_FLAG(flag) \
if ((THIS->flags & (flag)) == (flag)) { \
if (strlen(THIS->__retvalue) > 0) \
strlcat(THIS->__retvalue, "|" #flag, MAXSTRINGLEN); \
else \
strlcat(THIS->__retvalue, #flag, MAXSTRINGLEN); \
}
strlcpy(THIS->__retvalue, "", MAXSTRINGLEN);
HANDLE_FLAG(O_RDONLY);
HANDLE_FLAG(O_WRONLY);
HANDLE_FLAG(O_RDWR);
#ifdef O_ACCMODE
HANDLE_FLAG(O_ACCMODE);
#endif
HANDLE_FLAG(O_CREAT);
HANDLE_FLAG(O_EXCL);
HANDLE_FLAG(O_NOCTTY);
HANDLE_FLAG(O_TRUNC);
HANDLE_FLAG(O_APPEND);
HANDLE_FLAG(O_NONBLOCK);
#ifdef O_SYNC
HANDLE_FLAG(O_SYNC);
#endif
#ifdef O_ASYNC
HANDLE_FLAG(O_ASYNC);
#endif
#ifdef O_DSYNC
HANDLE_FLAG(O_DSYNC);
#endif
#ifdef O_RSYNC
HANDLE_FLAG(O_RSYNC);
#endif
#ifdef O_NDELAY
HANDLE_FLAG(O_NDELAY);
#endif
#ifdef O_PRIV
HANDLE_FLAG(O_PRIV);
#endif
#ifdef O_DIRECT
HANDLE_FLAG(O_DIRECT);
#endif
#ifdef O_LARGEFILE
HANDLE_FLAG(O_LARGEFILE);
#endif
#ifdef O_DIRECTORY
HANDLE_FLAG(O_DIRECTORY);
#endif
#ifdef O_NOFOLLOW
HANDLE_FLAG(O_NOFOLLOW);
#endif
#ifdef O_NOATIME
HANDLE_FLAG(O_NOATIME);
#endif
#ifdef FNDELAY
HANDLE_FLAG(FNDELAY);
#endif
#ifdef FAPPEND
HANDLE_FLAG(FAPPEND);
#endif
#ifdef FMARK
HANDLE_FLAG(FMARK);
#endif
#ifdef FDEFER
HANDLE_FLAG(FDEFER);
#endif
#ifdef FASYNC
HANDLE_FLAG(FASYNC);
#endif
#ifdef FSHLOCK
HANDLE_FLAG(FSHLOCK);
#endif
#ifdef FEXLOCK
HANDLE_FLAG(FEXLOCK);
#endif
#ifdef FCREAT
HANDLE_FLAG(FCREAT);
#endif
#ifdef FTRUNC
HANDLE_FLAG(FTRUNC);
#endif
#ifdef FEXCL
HANDLE_FLAG(FEXCL);
#endif
#ifdef FNBIO
HANDLE_FLAG(FNBIO);
#endif
#ifdef FSYNC
HANDLE_FLAG(FSYNC);
#endif
#ifdef FNOCTTY
HANDLE_FLAG(FNOCTTY);
#endif
#ifdef O_SHLOCK
HANDLE_FLAG(O_SHLOCK);
#endif
#ifdef O_EXLOCK
HANDLE_FLAG(O_EXLOCK);
#endif
#undef HANDLE_FLAG
// If O_CREAT was specified, handle mode
if ((THIS->flags & O_CREAT) == O_CREAT) {
char modebuf[100];
snprintf(modebuf, sizeof(modebuf), ", %#lo",
(unsigned long)THIS->mode);
strlcat(THIS->__retvalue, modebuf, MAXSTRINGLEN);
}
%}
%(arch == "x86_64" %?
function ia32:long()
%{ /* pure */
if (test_tsk_thread_flag(current, TIF_IA32))
THIS->__retvalue = 1;
else
THIS->__retvalue = 0;
%}
%)
global output
probe process("/bin/cat").exec { printf("cat starting...\n") }
probe process("/bin/cat").syscall {
output = 1
# __NR_read:
%( arch == "i686" %?
if ($syscall == 3)
%: %( arch == "x86_64" %?
if ((ia32() && $syscall == 3) || (!ia32() && $syscall == 0))
%) %)
{
printf("read(%d, %p, %d)", get_syscall_arg(0),
get_syscall_arg(1), get_syscall_arg(2))
output = 2
}
# __NR_open:
%(arch == "i686" %?
else if ($syscall == 5)
%: %(arch == "x86_64" %?
else if ((ia32() && $syscall == 5) || (!ia32() && $syscall == 2))
%) %)
{
printf("open(\"%s\", %s)", user_string(get_syscall_arg(0)),
open_parse_flags_and_mode(get_syscall_arg(1),
get_syscall_arg(2)))
output = 2
}
# __NR_close:
%(arch == "i686" %?
else if ($syscall == 6)
%: %(arch == "x86_64" %?
else if ((ia32() && $syscall == 6) || (!ia32() && $syscall == 3))
%) %)
{
printf("close(%d)", get_syscall_arg(0))
output = 2
}
# default
else {
printf("syscall %d: %s(?)", $syscall, syscall_decode($syscall))
}
}
probe process("/bin/cat").syscall.return {
if (output == 1)
printf(" = %#x\n", get_syscall_return_value())
else
printf(" = %d\n", get_syscall_return_value())
}
probe process("/bin/cat").death {
printf("done...\n")
exit()
}