This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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 &regs->bx + n;
# else
	return &regs->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 &regs->bx;
			case 1: return &regs->cx;
			case 2: return &regs->dx;
			case 3: return &regs->si;
			case 4: return &regs->di;
			case 5: return &regs->bp;
#  else
			case 0: return &regs->rbx;
			case 1: return &regs->rcx;
			case 2: return &regs->rdx;
			case 3: return &regs->rsi;
			case 4: return &regs->rdi;
			case 5: return &regs->rbp;
#  endif				/* STAPCONF_X86_UNIREGS */
			default: BUG();
		}
# endif					/* CONFIG_IA32_EMULATION */
	switch (n) {
# if defined (STAPCONF_X86_UNIREGS)
		case 0: return &regs->di;
		case 1: return &regs->si;
		case 2: return &regs->dx;
		case 3: return &regs->r10;
		case 4: return &regs->r8;
		case 5: return &regs->r9;
# else
		case 0: return &regs->rdi;
		case 1: return &regs->rsi;
		case 2: return &regs->rdx;
		case 3: return &regs->r10;
		case 4: return &regs->r8;
		case 5: return &regs->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 &regs->ax;
# else
	return &regs->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 &regs->ax;
# else
	return &regs->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()
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]