]> granicus.if.org Git - strace/commitdiff
Delay get_regs invocation
authorDmitry V. Levin <ldv@altlinux.org>
Tue, 11 Apr 2017 04:04:37 +0000 (04:04 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 11 Apr 2017 04:04:37 +0000 (04:04 +0000)
strace used to call get_regs on every stop of a tracee, including cases
when the result is going to be discarded.  Prepare to change this lavish
practice by delaying get_regs invocation until its result is actually
needed.

* defs.h (get_regs): Remove.
* strace.c (trace): Do not call get_regs.
* syscall.c (get_regs): Add static qualifier.
(trace_syscall_exiting, print_pc, get_scno): Call get_regs.

defs.h
strace.c
syscall.c

diff --git a/defs.h b/defs.h
index 39d5693d7eedcb2bdc2d14aa45ee0ecc3e28b44b..54f641747d8175c322e502bb28a85562aabe91ec 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -412,7 +412,6 @@ extern void count_syscall(struct tcb *, const struct timeval *);
 extern void call_summary(FILE *);
 
 extern void clear_regs(void);
-extern void get_regs(pid_t pid);
 extern int get_scno(struct tcb *);
 extern kernel_ulong_t get_rt_sigframe_addr(struct tcb *);
 
index 6adb2c9f3cf4b4521aa985f9986dbf0ed2e7899e..2933a78009f2a8174d687dd42f1f042ab9e89731 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -2299,8 +2299,6 @@ trace(void)
        }
 
        clear_regs();
-       if (WIFSTOPPED(status))
-               get_regs(pid);
 
        event = (unsigned int) status >> 16;
 
index 8cfc3852811bc74ec33bc2caa4c7770438c2de8a..89491abb797299e2ab53ea9bbc17c8cdde13f259 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -559,6 +559,7 @@ clear_regs(void)
        get_regs_error = -1;
 }
 
+static void get_regs(pid_t pid);
 static int get_syscall_args(struct tcb *);
 static int get_syscall_result(struct tcb *);
 static int arch_get_scno(struct tcb *tcp);
@@ -766,6 +767,7 @@ trace_syscall_exiting(struct tcb *tcp)
        }
 #endif
 
+       get_regs(tcp->pid);
 #if SUPPORTED_PERSONALITIES > 1
        update_personality(tcp, tcp->currpers);
 #endif
@@ -1065,6 +1067,7 @@ print_pc(struct tcb *tcp)
 #else
 # error Neither ARCH_PC_REG nor ARCH_PC_PEEK_ADDR is defined
 #endif
+       get_regs(tcp->pid);
        if (get_regs_error || ARCH_GET_PC)
                tprints(current_wordsize == 4 ? "[????????] "
                                              : "[????????????????] ");
@@ -1150,7 +1153,7 @@ ptrace_setregs(pid_t pid)
 
 #endif /* ARCH_REGS_FOR_GETREGSET || ARCH_REGS_FOR_GETREGS */
 
-void
+static void
 get_regs(pid_t pid)
 {
 #undef USE_GET_SYSCALL_RESULT_REGS
@@ -1225,6 +1228,8 @@ free_sysent_buf(void *ptr)
 int
 get_scno(struct tcb *tcp)
 {
+       get_regs(tcp->pid);
+
        if (get_regs_error)
                return -1;