summaryrefslogtreecommitdiff
path: root/strace.c
Commit message (Collapse)AuthorAge
* Make int3 example in comments more cut-n-pastableDenys Vlasenko2014-04-10
| | | | | | | | | I found that I use it quite often. Lets make it so that after cut-n-pasting it into a file, there is no need to edit the result (e.g. no need to remove C comment chars from every line. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Fix build with Bionic libcDmitry V. Levin2014-02-26
| | | | | | | | | | | | | | Add generic tests for fopen64 and fputs_unlocked functions to fix build with Bionic libc that does not provide them. * configure.ac (AC_CHECK_FUNCS): Add fopen64 and fputs_unlocked. * strace.c [_LARGEFILE64_SOURCE]: Use fopen instead of fopen64 if !HAVE_FOPEN64. Use fputs instead of fputs_unlocked if !HAVE_FPUTS_UNLOCKED. * vsprintf.c: Use fputs instead of fputs_unlocked if !HAVE_FPUTS_UNLOCKED. Reported-by: Elliott Hughes <enh@google.com>
* Stop using _LFS64_LARGEFILEDmitry V. Levin2013-11-12
| | | | | | | | | | | There is only one place left in the code where strace guesses whether libc provides LFS64 functions and structures. The most natural thing to do there is to check for _LARGEFILE64_SOURCE - the macro provided by glibc. Other libc implementations that provide nondegenerate LFS64 interfaces are expected to define this macro as well. * defs.h (_LFS64_LARGEFILE): Remove. * strace.c: Use _LARGEFILE64_SOURCE instead of _LFS64_LARGEFILE.
* powerpc: fix iflag build issue (static -> extern)Anton Blanchard2013-07-12
| | | | | Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* PTRACE_SEIZE can set ptrace options immediately, use this featureDenys Vlasenko2013-07-10
| | | | | | | | This eliminates some rare bugs, such as post-execve SIGTRAP generation when we attach to a process, and it manages to finish execve'ing before we set TRACEEXEC option to suppress that. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* If -o|logger is in use, exit trace loop if nprocs == 0.Denys Vlasenko2013-07-08
| | | | Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Exit trace loop if got ECHILD, not if nprocs == 0.Denys Vlasenko2013-07-08
| | | | | | | Comment gives a testcase which wasn't handled correctly by the old code. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Add paranoia check before passing a long to pid2tcb(int pid)Denys Vlasenko2013-07-04
| | | | Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* In debug output, show waitpid status with 6 hex digits, not 4Denys Vlasenko2013-07-02
| | | | | | | | | | This shows event byte values better (without variable offset): [wait(0x01057f) = 29491] WIFSTOPPED,sig=SIGTRAP,EVENT_FORK (1) [wait(0x80057f) = 29492] WIFSTOPPED,sig=SIGTRAP,EVENT_STOP (128) ^^ Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Replace suspicious popen_pid assignment with an obviously correct oneDenys Vlasenko2013-07-02
| | | | | | | | | | | | | | popen_pid = vfork() does work correctly, but for a subtle reason that wrong assignment of 0 happens in the child _first_, and _then_ correct value overwrites it in the parent. (And in a hyphothetical system where vfork = fork, popen_pid wouldn't be shared, so it will also be ok.) However, it's not necessary to be difficult. This change makes it so that assignment is done only in parent. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Convert trace() from returning int to returning voidDenys Vlasenko2013-07-01
| | | | | | | The cleanup sequence in error cases, and on normal code path was nearly the same, no point in duplicating it. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Remove ia64-specific printing of current address on signal deliveryDenys Vlasenko2013-07-01
| | | | | | The address is printed anyway by printleader() if -i is active. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Change upeek() to take pid, not full tcp.Denys Vlasenko2013-06-28
| | | | | | This will be used by next change. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* In -f mode, do not assume that new pid is stopped - handle exits tooDenys Vlasenko2013-06-26
| | | | Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Set strace_child only in the right branchDenys Vlasenko2013-06-26
| | | | | | | | | | "strace_child = pid" assignment was racing in NOMMU case because of vfork (no way to know which process would win). After this change, strace_child is set to nonzero only in one process after [v]fork. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Get rid of TCB_INUSE and TCB_STRACE_CHILDDenys Vlasenko2013-06-26
| | | | | | | | We can use tcb::pid == 0 as an indicator of free tcb, and we already have strace_child variable which holds pid of our child, if any. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Fix debug output of wait4 result (was reusing buf[] on unknown events)Denys Vlasenko2013-06-21
| | | | Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Show PTRACE_EVENT_STOP correctly in debug outputDenys Vlasenko2013-06-21
| | | | Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Panic a bit less when we see an unknown pidDenys Vlasenko2013-06-21
| | | | | | | | I stumbeld over this case when I used "exec stace ...". * strace.c (trace): Do not exit if we see an unknown pid in wait4. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* detach(): Reorganize code. Logic is the same.Denys Vlasenko2013-06-21
| | | | | | | * strace.c (detach): Use goto's instead of excessive nesting. Drop sigstop_expected and interrupt_done variables. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Eat pending SIGSTOP _before_ PTRACE_DETACH in detach()Denys Vlasenko2013-06-21
| | | | | | | * strace.c (detach): If TCB_IGNORE_ONE_SIGSTOP is set, di not PTRACE_DETACH - wait for SIGSTOP first. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* detach(): warn if we see ECHILD from waitpidDenys Vlasenko2013-06-20
| | | | | | | | | * strace.c (detach): Warn if we see ECHILD from waitpid. Explain in comments that we don't normally expect !WIFSTOPPED either, and also that PTRACE_CONT failure isn't expected (the "break" there is a "I'm confused, bailing out" code style).. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Improve error messages in detach()Denys Vlasenko2013-06-20
| | | | | | | * strace.c (detach): Change return type from int to void. Improve error meesages: show PID, tell exactly which operation fails. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Remove workarounds for ancient kernels lacking __WALLDenys Vlasenko2013-06-20
| | | | | | | | | | | __WALL is available and working at least since 2.4 kernels: 10 years ago. * strace (detach): Remove workarounds for ancient kernels lacking __WALL. Add missing EINTR check. (trace): Remove workarounds for ancient kernels lacking __WALL. Remove redundant double error printout. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* USE_SEIZE: fix detaching from stopped processesDenys Vlasenko2013-06-20
| | | | | | | | | | | | | | | V3: split SEIZE/!SEIZE code paths to reduce confusion. Extensively comment every possible case. Verified that all tests/detach* tests work in both SEIZE and !SEIZE cases. * strace.c (detach): If PTRACE_SEIZE API is in use, stop the tracee using PTRACE_INTERRUPT instead of sending it a SIGSTOP. In a subsequent waitpid loop, correctly wait and suppress SIGSTOP on detach if PTRACE_INTERRUPT wasn't used, or wait for any ptrace stop and detach without suppressing signals. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Cleanups. No logic changes.Denys Vlasenko2013-06-18
| | | | | | | | * defs.h: Define new ptrace constants unconditionally. * strace.c (detach): Fix comment. (trace): Remove now unnecessary "if USE_SEIZE". Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Do not suppress signal delivery messages with -qqDmitry V. Levin2013-05-28
| | | | | | | | | | | Current implementation of -qq does not allow suppressing exit status messages without suppressing signal delivery messages, which is not good. There is a traditional "-e signal=none" syntax that can be used to suppress all signal delivery messages. This partially reverts commit v4.7-222-g01997cf. * strace.c (trace): Do not suppress signal delivery messages with -qq. * strace.1: Update documentation about -qq option.
* NOMMU: do not hide startup syscalls unless in -D modeDmitry V. Levin2013-05-14
| | | | | | | | | | On NOMMU systems in "strace PROG" case, we have no way to attach to the tracee before it calls execve unless in -D mode. That is, the first execve call is very likely to be missed, and setting hide_log_until_execve just results to empty log. * strace.c (init) [NOMMU_SYSTEM]: Do not set hide_log_until_execve unless in -D mode.
* Make -D mode work when the Yama LSM is enabledDmitry V. Levin2013-05-14
| | | | | | | * strace.c [HAVE_PRCTL]: Include sys/prctl.h. (startup_child) [HAVE_PRCTL && PR_SET_PTRACER && PR_SET_PTRACER_ANY]: In -D mode, allow tracing the process that is going to become the tracee.
* Hide startup syscalls.Denys Vlasenko2013-05-14
| | | | | | | | | | | | | | | | | | | Tested with "./strace [-D] [-q] [-bexecve] env true", all cases seem to work. * defs.h: Declare new variable: bool hide_log_until_execve. * strace.c: Define hide_log_until_execve. Rename skip_startup_execve to skip_one_b_execve. (startup_child): Do not set skip_one_b_execve = 1 here. (init): If "strace PROG" case (as opposed to "strace -pPID"), set skip_one_b_execve and hide_log_until_execve to 1. (trace): Don't print signal messages if hide_log_until_execve == 1. * syscall.c (trace_syscall_entering): Skip syscall printing if hide_log_until_execve == 1. Reset hide_log_until_execve if we enter execve syscall. (trace_syscall_exiting): Skip syscall printing if hide_log_until_execve == 1. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
* Allow -q to be repeated for very quiet outputDaniel P. Berrange2013-05-13
| | | | | | | | | | | | | | Even with the -q flag specified, tracing output is still mixed with messages about signals and process exit status, which is often irrelevant. Allow the -q option to be repeated to force the suppression of signals / exit status info too. * defs.h: Change 'qflag' from 'bool' to 'unsigned int'. * strace.1: Document ability to repeat '-q' option. * strace.c: Allow '-q' to be repeated to quieten process exit status and signal messages. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
* Use 64-bit versions of stat, readdir and setrlimit functions when availableDmitry V. Levin2013-03-21
| | | | | | | | | | | | | strace already has a mechanism to use fopen64 for output when the 64-bit version of fopen is available on 32-bit architectures. Apply this mechanism for other three functions to make strace fully adopted for 64-bit types. * strace.c (struct_stat, stat_file, struct_dirent, read_dir, struct_rlimit, set_rlimit): New macros. (startup_attach): Use read_dir. (startup_child): Use struct_stat and stat_file. (main): Use struct_rlimit and set_rlimit.
* Remove variable tracing_paths and check in pathtrace_matchDenys Vlasenko2013-03-05
| | | | Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Use dynamically-sized selected[] array for -P PATHDenys Vlasenko2013-03-05
| | | | | | | | | | | While at it, added a small optimization of not remembering the path twice if it happens to be the same. text data bss dec hex filename 245111 680 10860 256651 3ea8b strace_old 245075 680 9804 255559 3e647 strace Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Make -b take SYSCALL param, document it in --help and in manpage.Denys Vlasenko2013-02-27
| | | | | | | | | | | | To not waste an option letter for just one trick, extend -b to take a parameter: "on which syscalls do you want to detach?". Currently supports only execve. While at it, fixed (by removing non-Linux and stale info) and extended manpage text about -f. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Mass replace error_msg("%s", "literal") -> error_msg("literal")Denys Vlasenko2013-02-26
| | | | | | | There is no need to print literal strings through "%s". Only untrusted strings such as filenames need that. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Assorted NOMMU fixesDenys Vlasenko2013-02-26
| | | | | | | | | | | | With -D, strdup'ing of pathname is necessary only on NOMMU. Don't set skip_startup_execve to 1 if NOMMU and not in daemonized mode (try "strace [-D] -b env echo HI" to see whether we detach on correct execve). Fix test_ptrace_FOO shortcuts on NOMMU to always assume success and _properly_ set all variables. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Shorten help text - no need to show deprecated option -FDenys Vlasenko2013-02-26
| | | | Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Create and use struct_sysent and struct_ioctlent typedefs.Denys Vlasenko2013-02-22
| | | | | | | | | | This is a preparatory mass replace patch with no code changes. The future change will need to typedef sysent to sysent0, which results in compile failures when "struct sysent" string gets mangled into "struct sysent0". Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Eliminate many SCNO_IS_VALID checksDenys Vlasenko2013-02-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | By adding tcp->s_ent pointer tot syscall table entry, we can replace sysent[tcp->scno] references by tcp->s_ent. More importantly, we may ensure that tcp->s_ent is always valid, regardless of tcp->scno value. This allows us to drop SCNO_IS_VALID(tcp->scno) checks before we access syscall table entry. We can optimize (qual_flags[tcp->scno] & QUAL_foo) checks with a similar technique. Resulting code shrink: text data bss dec hex filename 245975 700 19072 265747 40e13 strace.t3/strace 245703 700 19072 265475 40d03 strace.t4/strace * count.c (count_syscall): Use cheaper SCNO_IN_RANGE() check. * defs.h: Add "int qual_flg" and "const struct sysent *s_ent" to struct tcb. Remove "int u_nargs" from it. Add UNDEFINED_SCNO constant which will mark undefined scnos in tcp->qual_flg. * pathtrace.c (pathtrace_match): Drop SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. * process.c (sys_prctl): Use tcp->s_ent->nargs instead of tcp->u_nargs. (sys_waitid): Likewise. * strace.c (init): Add compile-time check that DEFAULT_QUAL_FLAGS constant is consistent with init code. * syscall.c (decode_socket_subcall): Use tcp->s_ent->nargs instead of tcp->u_nargs. Set tcp->qual_flg and tcp->s_ent. (decode_ipc_subcall): Likewise. (printargs): Use tcp->s_ent->nargs instead of tcp->u_nargs. (printargs_lu): Likewise. (printargs_ld): Likewise. (get_scno): [MIPS,ALPHA] Use cheaper SCNO_IN_RANGE() check. If !SCNO_IS_VALID, set tcp->s_ent and tcp->qual_flg to default values. (internal_fork): Use tcp->s_ent instead of sysent[tcp->scno]. (syscall_fixup_for_fork_exec): Remove SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. (get_syscall_args): Likewise. (get_error): Drop SCNO_IS_VALID check where it is redundant. (dumpio): Drop SCNO_IS_VALID check where it is redundant. Use tcp->s_ent instead of sysent[tcp->scno]. (trace_syscall_entering): Use (tcp->qual_flg & UNDEFINED_SCNO) instead of SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. Drop SCNO_IS_VALID check where it is redundant. Print undefined syscall name with undefined_scno_name(tcp). (trace_syscall_exiting): Likewise. * util.c (setbpt): Use tcp->s_ent instead of sysent[tcp->scno]. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Fix NOMMU + daemonized tracer SEGVDenys Vlasenko2013-02-19
| | | | | | | | | | | | | pathname[] was getting destroyed, execve of garbage pathname failing, and to top it off, the tracer's stack was also smashed and trecer segfaulted. * strace.c (exec_or_die): New function. (startup_child): Don't use pathname[] contents after vfork, make a malloced copy instead. Explain "NOMMU + -D bug" and how we work around it. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Make it possible to to do test builds for NOMMU architecturesDenys Vlasenko2013-02-19
| | | | | | | And while using it, I discovered that -D doesn't work too well on NOMMU. Added a comment about it. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* [X86] Use ptrace(PTRACE_GETREGSET, NT_PRSTATUS) to get registers.Denys Vlasenko2013-02-14
| | | | | | | | | | | | | | | | | | | | | | | | Unlike PTRACE_GETREGS, this new method detects 32-bit processes reliably, without checking segment register values which are undocumented and aren't part of any sort of API. While at it, also fixed x32 detection to use __X32_SYSCALL_BIT, as it should have been from the beginning. * defs.h: Declare os_release and KERNEL_VERSION. * strace.c: Make os_release non-static, remove KERNEL_VERSION define. * syscall.c: New struct i386_user_regs_struct, static union x86_regs_union and struct iovec x86_io. (printcall): Use i386_regs or x86_64_regs depending on x86_io.iov_len. (get_regs): On x86 and kernels 2.6.30+, use PTRACE_GETREGSET, on earlier kernels fall back to old method. (get_scno): [X86] Determine personality based on regset size on scno & __X32_SYSCALL_BIT. (syscall_fixup_on_sysenter): Use i386_regs or x86_64_regs depending on x86_io.iov_len. (get_syscall_args): Likewise. (get_error): Likewise. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Shortcut tests for fork/exec syscallsDenys Vlasenko2013-02-06
| | | | | | | | | | | | | | | | | | | | | This change should speed up strace by a tiny bit. More importantly, it makes it much more clear that fork and exec fixups are not necessary for any reasonably recent kernels. IOW: syscall_fixup_for_fork_exec() and its callees are all dead code. * defs.h: Declare new need_fork_exec_workarounds flag variable. * strace.c: Define need_fork_exec_workarounds flag variable. (test_ptrace_setoptions_followfork): Return 0/1 as success/fail indicator. (test_ptrace_setoptions_for_all): Likewise. (init): Set need_fork_exec_workarounds to TRUE if needed. * syscall.c: Rename internal_syscall() to syscall_fixup_for_fork_exec(). (trace_syscall_entering): Call syscall_fixup_for_fork_exec() only if need_fork_exec_workarounds == TRUE. (trace_syscall_exiting): Likewise. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Optimize out PTRACE_PEEKUSER with -iDenys Vlasenko2013-02-05
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | strace -i was fetching PC with a separate PEEKUSER despite having GETREGS data: ptrace(PTRACE_GETREGS, 22331, 0, 0x8087f00) = 0 ptrace(PTRACE_PEEKUSER, 22331, 4*EIP, [0x80dd7b7]) = 0 write(3, "[080dd7b7] ioctl(0, SNDCTL_TMR_T"..., 82) = 82 ptrace(PTRACE_SYSCALL, 22331, 0, SIG_0) = 0 Now it does this: ptrace(PTRACE_GETREGS, 22549, 0, 0x8087ea0) = 0 write(3, "[080dd7b7] ioctl(0, SNDCTL_TMR_T"..., 82) = 82 ptrace(PTRACE_SYSCALL, 22549, 0, SIG_0) = 0 Analogous improvement in sys_sigreturn() is also implemented. * defs.h: Declare extern struct pt_regs regs for SPARC[64] and ARM. Declare clear_regs(), get_regs() and get_regs_error flag variable. * strace.c (trace): Call get_regs(pid) as soon as we know the tcb and that it is stopped. * syscall.c (get_regs): New function. Used to fetch registers early, just after tracee has stopped. (printcall): Move it here from util.c. Use global regs.REG data, if available on the arch, instead of re-fetching it. (get_scno): Use global regs.REG data. (get_syscall_result): Likewise. * signal.c (sys_sigreturn): Likewise. * util.c (printcall): Moved to syscall.c. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Use perror_msg instead of perrorDmitry V. Levin2012-09-28
| | | | | | | * signal.c (sys_sigreturn): Use perror_msg instead of perror. * strace.c (tprintf, tprints, detach, startup_attach): Likewise. * syscall.c (get_scno): Likewise. * util.c (umoven, umovestr): Likewise.
* Trivial fixes, no code changes.Denys Vlasenko2012-09-13
| | | | | | | | * strace.c: Fix compiler warning message about tgkill - we don't use it. Fix indentation of preprocessor directives. (trace): Remove outdated comment. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
* Always check setreuid return codeDmitry V. Levin2012-08-24
| | | | * strace.c (startup_child): Check setreuid return code.
* Close pipe and wait for the pipe process terminationDmitry V. Levin2012-07-12
| | | | | | | | | In case of normal strace termination, when the trace output is redirected to a file or a pipe, close it and wait for the pipe process termination. * strace.c (main): Before normal exit, close shared_log when it differs from stderr, and wait for popen_pid termination.
* Enable usage of PTRACE_SEIZEDenys Vlasenko2012-07-10
| | | | | | | | | | * defs.h: Define USE_SEIZE to 1. Remove PTRACE_SEIZE_DEVEL and PTRACE_EVENT_STOP1. * strace.c (ptrace_attach_or_seize): Replace PTRACE_SEIZE_DEVEL with 0. (trace): Do not check for PTRACE_EVENT_STOP1. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>