IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an
email to Administrator. User accounts are meant only to access repo
and report issues and/or generate pull requests.
This is a purpose-specific Git hosting for
BaseALT
projects. Thank you for your understanding!
Только зарегистрированные пользователи имеют доступ к сервису!
Для получения аккаунта, обратитесь к администратору.
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 patches will try to improve this situation.
This change duplicates get_scno into identical get_scno_on_sysenter,
get_scno_on_sysexit functions. Call them in syscall enter and syscall
exit, correspondingly.
* defs.h: Rename get_scno to get_scno_on_sysenter; declare it only
if USE_PROCFS.
* strace.c (proc_open): Call get_scno_on_sysenter instead of get_scno.
* syscall.c (get_scno): Split into two (so far identical) functions
get_scno_on_sysenter and get_scno_on_sysexit.
(trace_syscall_entering): Call get_scno_on_sysenter instead of get_scno.
(trace_syscall_exiting): Call get_scno_on_sysexit instead of get_scno.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* syscall.c [LINUX] (syscall_enter): Move tcp->u_nargs initialization
from arch-specific ifdefs to common code. Always cache tcp->u_nargs in
a local variable and use it in for() loops.
[IA64, AVR32] Rewrite tcp->u_arg[] initialization using a loop.
Loops of the form "for (i = 0; i < tcp->u_nargs; i++) ..."
need to fetch tcp->u_nargs from memory on every iteration
if "..." part has a function call (gcc doesn't know that
tcp->u_nargs won't change). This can be sped up
by putting tcp->u_nargs in a local variable, which might
go into a CPU register.
* syscall.c (decode_subcall): Cache tcp->u_nargs in a local variable
as for() loop limit value.
(syscall_enter): Likewise.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Usage -1 as argument count in syscallent tables
necessitates the check for it, a-la:
if (sysent[tcp->scno].nargs != -1)
tcp->u_nargs = sysent[tcp->scno].nargs;
else
tcp->u_nargs = MAX_ARGS;
which is stupid: we waste cycles checking something which
is constant and known at compile time.
* defs.h: Make struct sysent::nargs unsigned.
* freebsd/i386/syscallent.h: Replace nargs of -1 with MA.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* svr4/syscallent.h: Likewise.
* freebsd/syscalls.pl: Likewise in generator script.
* syscallent.sh: Likewise in generator script.
* syscall.c: Add define MA MAX_ARGS / undef MA around includes
of syscallent[N].h.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Syscall enter happens before syscall exit. Having functions
in opposite order in the source is confusing.
* syscall.c: Move trace_syscall_exiting below trace_syscall_entering.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Before this patch, the following:
open("qwerty", O_RDONLY) = -1 ENOENT
write(2, "wc: qwerty: No such file or dire"..., 38) = 38
was shown totally wrongly with -z:
open("qwerty", O_RDONLY) = 38
(yes, that's right, write syscall is lost!)
Now it is shown "less wrongly" as:
open("qwerty", O_RDONLY <unfinished ...>
write(2, "wc: qwerty: No such file or dire"..., 38) = 38
* syscall.c (trace_syscall_exiting): Use common TCB_INSYSCALL clearing
via "goto ret". This fixes totally broken display of -z, but even now
it is not working as intended. Add a comment about that.
(trace_syscall_entering): Use common TCB_INSYSCALL setting
via "goto ret".
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* defs.h: Explain TCB_INSYSCALL and TCB_WAITEXECVE bits in detail.
* strace.c (choose_pfd): Use entering/exiting macros instead of direct check
for TCB_INSYSCALL.
* syscall.c (get_scno): Use entering/exiting macros instead of direct check
for TCB_INSYSCALL. Fix comments about post-execve SIGTRAP.
(syscall_fixup): Use entering/exiting instead of direct check
for TCB_INSYSCALL. Add a comment what "not a syscall entry" message
usually means. Change wrong "stray syscall exit" messages into
"not a syscall entry" ones.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* defs.h (count_syscall): Change return type from int to void.
* count.c (count_syscall): Change return type from int to void.
* syscall.c (trace_syscall_exiting): Change code around call
to count_syscall accordingly.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* syscall.c (internal_syscall): Call internal_exec only if
SUNOS4 || (LINUX && TCB_WAITEXECVE).
* process.c (internal_exec): Define this function only if
SUNOS4 || (LINUX && TCB_WAITEXECVE).
(printwaitn): Don't check wordsize if SUPPORTED_PERSONALITIES == 1.
* signal.c (sys_kill): Likewise.
* syscall.c (is_negated_errno): Likewise.
(trace_syscall_exiting): Fold a tprintf into tprintfs which follow it.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Trivial shuffling of data tables puts them all in one file,
allowing gcc to see their sizes and eliminate variables
which store these sizes.
Surprisingly, in C mode gcc does not optimize out static const int
variables. Help it by using enums instead.
* defs.h: Stop exporting ioctlent{0,1,2}, nioctlents{0,1,2},
signalent{0,1,2}, nsignals{0,1,2}.
* ioctl.c: Remove definitions of ioctlent{,0,1,2} and nioctlents{,0,1,2}.
* signal.c: Remove definitions of signalent{,0,1,2} and nsignals{,0,1,2}.
* syscall.c: Move above definitions to this file. Make them static const
or enums if suitable.
* defs.h (set_personality): Change return type to void.
* syscall.c (set_personality): Change return type to void.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* syscall.c (get_scno): For POWERPC64 and X86-64, variable currpers
is declared static. But its old data is never used. Convert it
to ordinary local variable.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* defs.h: Add/reformat comments.
* signal.c: Remove wrong comment. Add warning directive
when we detect that NSIG is undefined. Add comment about
NSIG on ARM. Fix typo in comment.
(signame): Reformat code a bit without changes to logic.
Shorten static buffer.
(sys_rt_sigprocmask): Remove stray empty line.
* syscall.c: Add warning directive when we detect that
NSIG is undefined. Add comment about NSIG on ARM.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Current code plays some ungodly tricks, trying to not detach
thread group leader until all threads exit.
Also, it detaches from a tracee when signal delivery is detected
which will cause tracee to exit.
This operation is racy (not to mention the determination
whether signal is set to SIG_DFL is a horrible hack):
after we determined that this signal is indeed fatal
but before we detach and let process die,
*other thread* may set a handler to this signal, and
we will leak the process, falsely displaying it as killed!
I need to look in the past to figure out why we even do it.
First guess is that it's a workaround for old kernel bugs:
kernel used to deliver exit notifications to the tracer,
not to real parent. These workarounds are ancient
(internal_exit is from 1995).
The patch deletes the hacks. We no longer need tcp->nclone_threads,
TCB_EXITING and TCB_GROUP_EXITING. We also lose a few rather
ugly functions.
I also added a new message: "+++ exited with EXITCODE +++"
which shows exact moment strace got exit notification.
It is analogous to existing "+++ killed by SIG +++" message.
* defs.h: Delete struct tcb::nclone_threads field,
TCB_EXITING and TCB_GROUP_EXITING constants,
declarations of sigishandled() and internal_exit().
* process.c (internal_exit): Delete this function.
(handle_new_child): Don't ++tcp->nclone_threads.
* signal.c (parse_sigset_t): Delete this function.
(sigishandled): Delete this function.
* strace.c (startup_attach): Don't tcbtab[tcbi]->nclone_threads++.
(droptcb): Don't delay dropping if tcp->nclone_threads > 0,
don't drop parent if its nclone_threads reached 0:
just drop (only) this tcb unconditionally.
(detach): don't drop parent.
(handle_group_exit): Delete this function.
(handle_ptrace_event): Instead of handle_group_exit, just drop tcb;
do not panic if we see WIFEXITED from an attached pid;
print "+++ exited with EXITCODE +++" for every WIFEXITED pid.
* syscall.c (internal_syscall): Do not treat sys_exit specially -
don't call internal_exit on it.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* syscall.c (syscall_enter) [BFIN]: Make register no array "static const".
[SH]: Make register no array "const", pre-multiply it by 4.
[SH64]: Make register no array "const".
[X86_64]: Make register no array "const", pre-multiply it by 8.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
syscall_enter has many long (>80 columns) lines.
It is aggravated by the fact that it has a lot of {} blocks
which are not necessary (the code is the same without them).
This patch removes {}s and deindents affected lines.
While at it, it indents ifdefs so that nesting is easier to track,
and adds a few spaces in the expressions, such as
"tcp->u_nargs*sizeof..." -> "tcp->u_nargs * sizeof...".
There is no actual changes to the code here.
* syscall.c (syscall_enter): Remove unnecessary {} blocks.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
strace used to suspend waitpid until there is a child
for waitpid'ing process to collect status from.
Apparently, it was done because in some very old kernels
(circa 2002 or even earlier) there were ptrace bugs which
were making waitpid in real parent to not see children.
This kernel bug is fixed long ago. This change removes the workaround.
test/wait_must_be_interruptible.c is a test program which
illustrates why without this change strace changes
programs's behavior.
* defs.h: Delete waitpid and nclone_waiting members from from struct tcb.
Remove declaration of internal_wait().
* process.c (internal_wait): Remove this function.
* strace.c (alloc_tcb): Do not set tcp->nclone_waiting.
(resume): Remove this function.
(resume_from_tcp): Remove this function.
(detach): Do not call resume_from_tcp().
(handle_group_exit): Do not call resume_from_tcp().
* syscall.c (internal_syscall): Do not call internal_wait().
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* syscall.c [I386] (syscall_enter): Do not call umoven
to fetch zero bytes. This is just an optimization.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* pathtrace.c: New file, implements matching syscall arguments to
user-specified file paths.
* Makefile.am (strace_SOURCES): Add pathtrace.c.
* defs.h (TCB_FILTERED, filtered): New defines.
(getfdpath, pathtrace_select, pathtrace_match, show_fd_path,
tracing_paths): New declarations.
* strace.c (show_fd_path, tracing_paths): New global variables.
(usage, main): Implement handling of -y and -P options.
* strace.1: Add descriptions of -y and -P options.
* syscall.c (trace_syscall_entering): Add path matching logic to the
print/noprint decision and set the TCB_FILTERED bit appropriately.
(trace_syscall_exiting): Use filtered() macro that checks the
TCB_FILTERED bit to determine print/noprint status.
* util.c (printfd): Use getfdpath().
* defs.h (SYSCALL_NEVER_FAILS): New syscall flag.
* linux/dummy.h: Change redirection for sys_get[ug]id, sys_gete[ug]id
and setfs[ug]id.
* linux/*/syscallent.h: Set SYSCALL_NEVER_FAILS flag for get[ug]id,
gete[ug]id and setfs[ug]id syscalls.
* process.c [LINUX] (sys_getuid, sys_setfsuid): New functions.
* syscall.c (NF): New shorthand macro for use in syscallent.h files.
(get_error): Check SYSCALL_NEVER_FAILS flag.
Reported by Марк Коренберг <socketpair@gmail.com>.
* syscall.c (qualify_one, qual_syscall, qual_signal, qual_fault,
qual_desc): Take just a bitflag argument instead of pointer to the whole
qual_options structure.
(struct qual_options): Update prototype of "qualify" field.
(qualify): Update use of qualify_one and qual_options->qualify.
Fix regression introduced by commit v4.5.20-19-g30145dd:
if -e option is used with only one value in qualifier statement,
e.g. 'strace -e trace=open ls', syscall information would not be
printed properly.
* syscall.c (qualify): Remove faulty optimization.
Signed-off-by: Wang Chao <wang.chao@cn.fujitsu.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
* defs.h (struct xlat): Add const qualifier to the field of
type "char *".
(set_sortby, qualify, printnum, printnum_int): Add const qualifier to
arguments of type "char *".
* count.c (set_sortby): Add const qualifier to the argument and
automatic variable of type "char *".
* desc.c (decode_select): Add const qualifier to automatic variables of
type "char *".
* ioctlsort.c (struct ioctlent): Add const qualifier to fields of
type "char *".
(main): Add const qualifier to argv.
* process.c (printargv): Add const qualifier to the argument and
automatic variable of type "char *".
(printargc) Add const qualifier to argument of type "char *".
* signal.c (sprintsigmask, parse_sigset_t): Add const qualifier to
arguments of type "char *".
* strace.c (progname): Add const qualifier.
(detach): Add const qualifier to automatic variable of type "char *".
* stream.c (struct strbuf): Add const qualifier to the field of
type "char *".
* syscall.c (struct qual_options): Add const qualifier to fields of
type "char *".
(qual_syscall, qual_fault, qual_desc, lookup_class): Add const qualifier
to arguments of type "char *".
(qual_signal): Add const qualifier to the argument of type "char *",
avoid modification of constant argument.
(qualify): Likewise.
* util.c (printflags): Add const qualifier to automatic variable of
type "char *".
(printnum, printnum_int): Add const qualifier to arguments of
type "char *".
* defs.h (cflag_t): New enum.
* strace.1: Document -C option.
* strace.c (cflag): Update type.
(main): Handle -C option.
(trace): Update use of cflag.
* count.c (count_syscall): Move clearing of TCB_INSYSCALL to ...
* syscall.c (trace_syscall): ... here. Update use of cflag.
Based on patch by Adrien Kunysz.
The current sparc/linux code uses asm/reg.h, but recent Linux kernels
dropped that header completely. So switch over to the ptrace headers
as those should stick around indefinitely as part of the ABI.
* defs.h [LINUXSPARC] (U_REG_G1, U_REG_O0, U_REG_O1): Define.
* process.c: Drop asm/regs.h include.
[SPARC || SPARC64] (change_syscall): Change struct regs to struct pt_regs.
* signal.c: Drop asm/regs.h include.
(m_siginfo_t): Unify [SPARC || SPARC64] and [MIPS].
[SPARC || SPARC64] (sys_sigreturn): Change struct regs to struct pt_regs.
* syscall.c: Drop asm/regs.h include.
[SPARC || SPARC64] (internal_syscall, get_scno, get_error, force_result,
syscall_enter): Change struct regs to struct pt_regs.
* util.c: Drop asm/regs.h include.
(_hack_syscall5, _ptrace): Delete.
[SPARC || SPARC64] (getpc, printcall, arg_setup_state): Change
struct regs to struct pt_regs.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* configure.ac (AC_CHECK_FUNCS): Add fork.
* strace.c (strace_vforked): Define.
(startup_child): Do not raise SIGSTOP if vforked.
(trace): Skip first exec when starting up after vforked.
* syscall.c [BFIN] (get_scno): Drop waitexec checks.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Correct spacing to fix warnings reported by
git diff --check 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>