From: Denys Vlasenko Date: Wed, 24 Aug 2011 14:59:23 +0000 (+0200) Subject: Speed up x86 by avoiding EAX read on syscall entry X-Git-Tag: v4.7~294 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=18beb98fadbe43c3947cbdcc90d4f72d3a720b78;p=strace Speed up x86 by avoiding EAX read on syscall entry on x86, EAX read on syscall entry is 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. * syscall.c (get_scno_on_sysexit): On I386 and X86_64, read eax/rax which contain syscall return value. (syscall_fixup): On I386 and X86_64, read eax/rax only on syscall enter and only if PTRACE_O_TRACEEXEC is not in effect. Signed-off-by: Denys Vlasenko --- diff --git a/syscall.c b/syscall.c index a6f47af4..fc502bf2 100644 --- a/syscall.c +++ b/syscall.c @@ -1307,7 +1307,11 @@ get_scno_on_sysexit(struct tcb *tcp) return -1; # elif defined(BFIN) # elif defined (I386) + if (upeek(tcp, 4*EAX, &eax) < 0) + return -1; # elif defined (X86_64) + if (upeek(tcp, 8*RAX, &rax) < 0) + return -1; # elif defined(IA64) # define IA64_PSR_IS ((long)1 << 34) if (upeek(tcp, PT_CR_IPSR, &psr) >= 0) @@ -1468,22 +1472,30 @@ syscall_fixup(struct tcb *tcp) #ifdef LINUX /* A common case of "not a syscall entry" is post-execve SIGTRAP */ #if defined (I386) - if (upeek(tcp, 4*EAX, &eax) < 0) - return -1; - if (eax != -ENOSYS && entering(tcp)) { - if (debug) - fprintf(stderr, "not a syscall entry (eax = %ld)\n", eax); - return 0; + /* With PTRACE_O_TRACEEXEC, post-execve SIGTRAP is disabled. + * Every extra ptrace call is expensive, so check EAX + * on syscall entry only if PTRACE_O_TRACEEXEC is not enabled: + */ + if (entering(tcp) && !(ptrace_setoptions & PTRACE_O_TRACEEXEC)) { + if (upeek(tcp, 4*EAX, &eax) < 0) + return -1; + if (eax != -ENOSYS) { + if (debug) + fprintf(stderr, "not a syscall entry (eax = %ld)\n", eax); + return 0; + } } #elif defined (X86_64) - if (upeek(tcp, 8*RAX, &rax) < 0) - return -1; - if (current_personality == 1) - rax = (long int)(int)rax; /* sign extend from 32 bits */ - if (rax != -ENOSYS && entering(tcp)) { - if (debug) - fprintf(stderr, "not a syscall entry (rax = %ld)\n", rax); - return 0; + if (entering(tcp) && !(ptrace_setoptions & PTRACE_O_TRACEEXEC)) { + if (upeek(tcp, 8*RAX, &rax) < 0) + return -1; + if (current_personality == 1) + rax = (long int)(int)rax; /* sign extend from 32 bits */ + if (rax != -ENOSYS && entering(tcp)) { + if (debug) + fprintf(stderr, "not a syscall entry (rax = %ld)\n", rax); + return 0; + } } #elif defined (S390) || defined (S390X) if (upeek(tcp, PT_GPR2, &gpr2) < 0)