Currently, get_scno does *much* more than "get syscall no".
It checks for post-execve SIGTRAP. It checks for changes
in personality. It retrieves params on entry and registers on exit.
Worse still, it is different in different architectures: for example,
for AVR32 regs are fetched in get_scno(), while for e.g. I386
it is done in syscall_enter().
Another problem is that get_scno() is called on both syscall entry and
syscall exit, which is stupid: we don't need to know scno on syscall
exit, it is already known from last syscall entry and stored in
tcp->scno! In essence, get_scno() does two completely different things
on syscall entry and on exit, they are just mixed into one bottle, like
shampoo and conditioner.
The following 5 patches try to improve this situation.
1. Duplicate get_scno into identical get_scno_on_sysenter,
get_scno_on_sysexit functions. Call them in syscall enter and syscall
exit, correspondingly.
2. Remove if (entering(tcp)) / if (exiting(tcp)) conditionals from both
functions, since now we know that they are always true or false there.
3. Remove scno retrieval code in get_scno_on_sysexit, since we don't
save it anyway. This is the first real logic change which should make
strace faster: for example, on x64 ORIG_EAX is no longer read in each
syscall exit.
4. Another speedup: on x86, EAX read on syscall entry is also not
necessary if we know that post-execve SIGTRAP is disabled by
PTRACE_O_TRACEEXEC ptrace option. This patch (a) moves EAX retrieval
from syscall_fixup to get_scno_on_sysexit, and (b) perform EAX retrieval
in syscall_fixup only if we are in syscall entry and PTRACE_O_TRACEEXEC
option is not on.
5. Move post-execve SIGTRAP from get_scno_on_sysenter (multitude of
places on many architectures) to a single location in
trace_syscall_entering. This loosens the logic for some arches, since
many of them had additional checks such as scno == 0. So maybe this last
patch is not 100% safe. (However, on non-ancient Linux kernels we should
never have post-execve SIGTRAP in the first place, by virtue of using
PTRACE_O_TRACEEXEC.)
Patches 3 and 4 have the following effects: patch 3 removes one ptrace
call on syscall exit:
ptrace(PTRACE_SYSCALL, PID, 0x1, SIG_0) = 0
--- {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=PID, si_status=SIGTRAP,
si_utime=0, si_stime=0} (Child exited) ---
wait4(-1, [{WIFSTOPPED(s) && WSTOPSIG(s) == 133}], __WALL, NULL) = PID
-ptrace(PTRACE_PEEKUSER, PID, 4*ORIG_EAX, [0xb]) = 0
ptrace(PTRACE_PEEKUSER, PID, 4*EAX, [0]) = 0
write(3, ") = 0\n", 6) = 6
and patch 4 drops another one on syscall entry:
write(3, ", {B38400 opost isig icanon echo ...}) = 0\n", 43) = 43
ptrace(PTRACE_SYSCALL, PID, 0x1, SIG_0) = 0
--- {si_signo=SIGCHLD, si_code=CLD_TRAPPED, si_pid=PID, si_status=SIGTRAP,
si_utime=0, si_stime=0} (Child exited) ---
wait4(-1, [{WIFSTOPPED(s) && WSTOPSIG(s) == 133}], __WALL, NULL) = PID
ptrace(PTRACE_PEEKUSER, PID, 4*ORIG_EAX, [0x36]) = 0
-ptrace(PTRACE_PEEKUSER, PID, 4*EAX, [0xffffffda]) = 0
ptrace(PTRACE_PEEKUSER, PID, 4*EBX, [0x1]) = 0
ptrace(PTRACE_PEEKUSER, PID, 4*ECX, [0x5401]) = 0
ptrace(PTRACE_PEEKUSER, PID, 4*EDX, [0xbfda3f80]) = 0
write(3, "ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or
TCGETS", 71) = 71
Further progress can be achieved by moving some (most/all?) code from
syscall_enter to get_scno_on_sysenter, and renaming get_scno_on_sysenter/exit
to better reflect on their actual operations.
--
vda
------------------------------------------------------------------------------
uberSVN's rich system and user administration capabilities and model
configuration take the hassle out of deploying and managing Subversion and
the tools developers use with it. Learn more about uberSVN and get a free
download at: http://p.sf.net/sfu/wandisco-dev2dev
_______________________________________________
Strace-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel