Commit Graph

317 Commits

Author SHA1 Message Date
Denys Vlasenko
eec8d5d6b0 [X86] Use ptrace(PTRACE_GETREGSET, NT_PRSTATUS) to get registers.
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>
2013-02-14 03:29:48 +01:00
Denys Vlasenko
8d4ca0c8cd Shortcut tests for fork/exec syscalls
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>
2013-02-06 13:18:42 +01:00
Denys Vlasenko
ce7d953ebe Optimize out PTRACE_PEEKUSER with -i
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>
2013-02-05 16:36:13 +01:00
9a71bcdab2 Use perror_msg instead of perror
* 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.
2012-09-28 01:13:10 +00:00
Denys Vlasenko
978fbc901c Trivial fixes, no code changes.
* 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>
2012-09-13 10:28:43 +02:00
508279c94f Always check setreuid return code
* strace.c (startup_child): Check setreuid return code.
2012-08-24 17:56:53 +00:00
cf53436f73 Close pipe and wait for the pipe process termination
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.
2012-07-12 20:54:46 +00:00
Denys Vlasenko
26bc0606d9 Enable usage of PTRACE_SEIZE
* 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>
2012-07-10 16:36:32 +02:00
Denys Vlasenko
c59b3f13fb Remove outdated comment about suspending new tracees
We no longer track parent/child relationship between tracees.
Therefore, we no longer suspend new tracee until parent is seen
exiting form [v]fork/clone. The comment is obsolete.

* strace.c (trace): Remove outdated comment.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-05-15 15:35:52 +02:00
0dbc80de89 Fix kernel release string parsing
* strace.c (get_os_release): Handle "X.Y-something" utsname.release
strings properly.

Reported-by: Bryce Gibson <bryce@gibson-consulting.com.au>
2012-05-14 23:42:10 +00:00
Denys Vlasenko
6e4f3c1fa4 Add custom (faster) vfprintf implementation (disabled by default)
* defs.h: Declare strace_vfprintf either as a alias to vfprintf
or as a bona fide function. USE_CUSTOM_PRINTF define controls whether
we use strace_vfprintf. By default, we don't.
* strace.c (tprintf): Call strace_vfprintf instead of vfprintf.
* vsprintf.c: New file, implements strace_vfprintf.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-04-16 18:22:19 +02:00
Denys Vlasenko
142aee0a59 Trivial speed optimization
* strace.c (tprints): Use fputs_unlocked instead of fputs.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-04-16 18:10:15 +02:00
Mike Frysinger
7ff5ed9325 Fix indefinite hang on no-mmu systems
The ptrace setoptions code will fork a child which goes to sleep and
expects the parent to continue on to do tests.  Unfortunately, this
does not work on no-mmu systems as fork() is actually vfork() and any
vforked children will hang the parent until it exits or execs.

We might be able to make this test work on no-mmu systems with a bit
of work, but easier to just disable this for the release so it works
now.

* strace.c (test_ptrace_setoptions_for_all): Return if strace_vforked.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
2012-04-05 14:53:49 +00:00
Denys Vlasenko
df790130ff Remove unreachable code
* strace.c (process_opt_p_list): Remove unreachable code.
2012-03-26 13:41:56 +02:00
Denys Vlasenko
c5ccfa450b Tweak help text and manpage (added -In to manpage)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-26 13:10:50 +02:00
ccee169ab6 Robustify parsing of numbers from strings
* defs.h (string_to_uint): New prototype.
* util.c (string_to_uint): New function.
* strace.c (error_opt_arg): New function.
(process_opt_p_list): Use string_to_uint instead of atoi.
Terminate in case of invalid process id.
(init): Use string_to_uint instead of atoi.
Use error_opt_arg in case of invalid option argument.
* syscall.c (qual_syscall, qual_signal, qual_desc): Use string_to_uint
instead of atoi.
2012-03-25 21:49:48 +00:00
Denys Vlasenko
6764f8f2f0 Simplify current tcp switching and current column handling
Instead of using "static FILE *outf and static unsigned int curcol"
to cache current outfile and its position, we can simply
remember current tcb and use its ->outf and ->curcol.
This allows to drop numerous "tcp->curcol = curcol" ops in trace().

Turns out we can't drop "static FILE *outf", but now its role is
a bit clearer: it newer changes after init, stays == stderr or
opened to shared log (which may be the same thing if neither -o
nor -ff was specified). Let's rename it then.

   text	   data	    bss	    dec	    hex	filename
 236953	    704	  18944	 256601	  3ea59	strace.before.prev.commit
 236905	    704	  18944	 256553	  3ea29	strace.before
 236869	    704	  18944	 256517	  3ea05	strace

* strace.c: Replace curcol static variable by struct tcb *current_tcp.
Rename static FILE *outf to shared_log (since it no longer caches tcp->outf).
(ptrace_restart): Use current_tcp->curcol instead of curcol.
(tprintf): Check current_tcp != NULL instead of outf != NULL.
Use current_tcp->outf instead of outf, current_tcp->curcol instead of curcol.
(tprints): Likewise.
(line_ended): Likewise.
(printleader): Switch current tcb by "current_tcp = tcp" istead of
assignments to outf and curcol.
(droptcb): Set current_tcp to NULL if we dropped it.
(startup_child): Rename outf to shared_log.
(init): Likewise.
(cleanup): Likewise.
(trace): Simplify current tcp switching and current column handling.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-22 09:56:20 +01:00
Denys Vlasenko
8511f2a1f0 Make threaded execve handling code more reabable and somewhat simpler
* strace.c (droptcb): Remove outfname check in "outfname && followfork >= 2" -
with recent changes, followfork >= 2 check guarantees that outfile
was specified, and _is already opened_.
(trace): Move tcb existence check before threaded execve handling.
This allows to remove tcp != NULL checks in threaded execve handling.
Rewrite threaded execve handling code to be less indented,
keeping the same logic.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-22 09:35:51 +01:00
Denys Vlasenko
b5e0908a17 Show "+++ exited..." with -C
* strace.c (trace): Show "+++ exited..." with -C too.
Save tcp->curcol after PTRACE_LISTEN failure too, just in case.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-21 14:27:40 +01:00
Denys Vlasenko
a44f9696e4 Replace reprinting decision logic
After this change, we no longer need to decide when we need
to set TCB_REPRINT, and when we don't: it's never needed :)

Well, almost. That pesky pid-changing execve needs special treatment.
If not it, it'd be possible to nuke TCB_REPRINT...

While at it, fix a case of mishandled -C.

* strace.c (printleader): Do not set TCB_REPRINT.
(trace): Set TCB_REPRINT only for execve with changing pid.
Fix mishandling of -C.
* syscall.c (trace_syscall_entering): Do not clear TCB_REPRINT.
(trace_syscall_exiting): Replace reprinting decision logic.
Remove call to printargs(): it is known to just return 0 here.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-21 11:06:20 +01:00
Denys Vlasenko
235067525c Report some ptrace failures; nuke tcp->ptrace_errno
Report some (not all) ptrace errors, namely,
errors on ptrace restart operations.

Before: 10533 sendto(-1, 0x804895e, 17, 0, NULL, 0 <unfinished ...>
After:  10533 sendto(-1, 0x804895e, 17, 0, NULL, 0 <ptrace(SYSCALL):No such process>

This tells user that strace failed to let sendto syscall
to be entered - process was dead at that point of time.
It is (marginally) better than to always say "<unfinished ...>"

While at it, patch removes tcp->ptrace_errno.
I added it many months ago, and it looks that after all
it is not needed for ptrace error detection: I failed to execute
a single existing code path which is accessible
through that variable only.

* defs.h: Remove struct tcp::ptrace_errno field.
* strace.c (ptrace_restart): Emit message to log on error.
(printleader): Remove "if (printing_tcp->ptrace_errno)..." code.
(trace): Remove !tcp->ptrace_errno check, it's always true.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-21 10:32:49 +01:00
Denys Vlasenko
852f98a382 Make ptrace_restart() static. No code changes
* defs.h: Remove ptrace_restart() declaration.
* strace.c (ptrace_restart): Move its definition here.
* util.c (ptrace_restart): Remove its definition.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-20 16:27:39 +01:00
Denys Vlasenko
3e3490acf7 Indentation and whitespace fixes. No code changes.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-17 01:27:37 +01:00
Denys Vlasenko
9c3861d317 Remove another "interrupt to quit" message
* strace.c (startup_attach): Remove another "interrupt to quit" message.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-16 15:21:49 +01:00
Denys Vlasenko
3db3b26101 Fix "strace -oFILE -ff -p<nonexistant_pid>" behavior
* strace.c (newoutf): Set tcp->outf in non-ff mode too.
(alloctcb): This define is removed.
(alloc_tcb): Renamed to alloctcb. Does not set tcp->outf anymore.
Lost 'command_options_parsed' flag parameter.
(startup_attach): Do not say "interrupt to quit" in attach message -
^C does not work in all cases, we mislead users.
Call newoutf(tcp) after successful attach.
(startup_child): Call newoutf(tcp) after successful attach.
(trace): Call newoutf(tcp) when we picked up already attached child.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-16 15:15:14 +01:00
Denys Vlasenko
800ec8ffde Make alloc_tcb and droptcb static. No code changes.
The change is trivial. Diff is large because it is confused
by function definitions being moved around.

* defs.h: Remove declarations of alloc_tcb and droptcb.
* strace.c: Make alloc_tcb and droptcb static.
Shuffle functions around to make compiler happy.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-16 15:11:34 +01:00
Denys Vlasenko
a6d91ded3f Tidy up includes and copyright notices, fix indentation
The files not mentioned in changelog below had only
copyright notices fixes and indentation fixes.

* defs.h: Include <stdint.h> and <inttypes.h>.
* file.c: Do not include <inttypes.h>.
Move struct kernel_dirent declaration below top include block.
* block.c: Do not include <stdint.h> and <inttypes.h>.
* quota.c: Likewise.
* desc.c: Likewise.
* signal.c: Likewise.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-16 12:02:22 +01:00
Denys Vlasenko
a509054aee Simplify SIGCHLD handler setting
* strace.c (init): Set SIGCHLD to SIG_DFL earlier.
(startup_child): Do not bother restoring SIGCHLD handler.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 17:27:49 +01:00
Denys Vlasenko
2c4fb905fe When reporting signals, use short signal names (SIGfoo) instead of strerror
* defs.h: Remove strsignal declaration.
* signal.c: Better check for SI_FROMUSER define.
* strace.c (strerror): Remove this function.
(trace): Use short signal names (SIGfoo) instead of strerror.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 17:24:49 +01:00
Denys Vlasenko
6e0bfd11ac Fix lame kernel version checking code
The code "os_release[0] >= '3'" is not good for any
finer-grained checks such as "kernel >= 3.2.1".
Let's proactively fix it.

* strace.c: Change os_release from string to integer.
(get_os_release): Parse uname.release to KERNEL_VERSION
representation.
(init): Convert kernel version check to KERNEL_VERSION.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 14:36:28 +01:00
Denys Vlasenko
61e7aad9fa Experimental support for "detach on execve" feature
* strace.c: Define new detach_on_execve, skip_startup_execve bool variables.
(init): Set detach_on_execve on -b, set skip_startup_execve if
"strace PROG" form is used.
(trace): Detach from process if -b and we see PTRACE_EVENT_EXEC event.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 13:44:17 +01:00
Denys Vlasenko
3e084ac349 Simple fixes.
* strace.c (usage): Document -d; document that -F is deprecated.
(droptcb): Print "<detached ...>" correctly for non-ff mode too.
(detach): Suppress a warning.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 13:39:05 +01:00
Denys Vlasenko
bcde70adbc Remove extra include directives. No code changes.
* defs.h: Include <signal.h> unconditionally.
Other files were doing it unconditionally, so no harm done.
* bjm.c: Remove system includes which are already included by defs.h.
* pathtrace.c: Likewise.
* process.c: Likewise.
* signal.c: Likewise.
* strace.c: Likewise.
* stream.c: Likewise.
* syscall.c: Likewise.
* system.c: Likewise.
* util.c: Likewise.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 12:56:25 +01:00
Denys Vlasenko
a50d2a87a1 Tidy up order of includes; make bool variables explicit.
Bool variables are more compact in data and (on x86) on code too:

   text	   data	    bss	    dec	    hex	filename
 237950	    676	  19044	 257670	  3ee86	strace.before
 237838	    676	  19012	 257526	  3edf6	strace

* defs.h: Group library includes at the top of the file.
Rename dtime to Tflag, debug to debug_flag.
Change debug_flag,Tflag,qflag,not_failing_only,show_fd_path,tracing_paths
variable declarations from int to bool.
* strace.c: Change corresponding definitions. Do the same for static
variables iflag,rflag,print_pid_pfx.
Rename dtime to Tflag, debug to debug_flag.
* syscall.c: Rename dtime to Tflag, debug to debug_flag.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 12:49:52 +01:00
Denys Vlasenko
67559ad260 Less ugly debug display of ptrace events
* strace.c (trace): Less ugly debug display of ptrace events.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-13 12:05:27 +01:00
Denys Vlasenko
7de265d88a Fix logging for "strace -o FILE -ff test/threaded_execve" test case
Our logic which was deciding whether to print "<unfinished ...>"
thingy wasn't working properly for -ff case.

* defs.h: Group log generation-related declarations together.
Add a large comment which explains how it works.
Add declaration of line_ended() function.
* strace.c (line_ended): New function which sets up internal data
to indicate that previous line was finished.
(printleader): Change logic to fix log generation in -ff mode.
(newoutf): Make check for -ff mode consistent with other places.
(droptcb): Print "<detached ...>" if last line for this tcp wasn't finished.
(cleanup): Remove code to print "<unfinished ...>", printleader()
or detach() will do it instead.
(trace): Remove code to print "<unfinished ...>".
Add code which finishes threaded execve's incomplete line
with " <pid changed to PID ...>" message. Replace printing_tcp = NULL
followed by fflush() by line_ended() call.
* process.c (sys_exit): Call line_ended() to indicate that we finished priting.
* syscall.c (trace_syscall_exiting): Set printing_tcp to current tcp.
Call line_ended() to indicate that we finished priting.
Remove call to fflush(), it is done by line_ended() now.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-13 11:44:31 +01:00
Denys Vlasenko
328bf250bd Treat -ff without -o FILE as single -f
* strace.c (init): Treat -ff without -o FILE as single -f.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-12 23:34:13 +01:00
Denys Vlasenko
558e5127fb Style fix. No code changes
* strace.c (process_opt_p_list): Style fix.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-12 23:32:16 +01:00
Denys Vlasenko
ecc8b97c9b Reduce stack usage by ~0.5k
main() uses ~0.5k of stack for local variables and such. When we enter
main tracing loop, most of these variables are no longer used.
But they still take up stack for the entire life of strace.
We can avoid this wastage if we move init code into a separate function.
(Need to be careful and not allow automatic inlining).

* strace.c (init): New function. Most of pre-existing code of
main is now living here.
(main): Call init() to do initialization.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-12 23:05:25 +01:00
Denys Vlasenko
2e856a1c92 Preparatory cosmetic changes for the next commit
* strace.c (tprintf): Move function up in the source file. No code changes.
(tprints): Likewise.
(printleader): Likewise.
(tabto): Likewise.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-12 23:02:26 +01:00
Denys Vlasenko
37ab4b79de Trivial simplification
* strace.c (detach): Use waitpid instead of wait4.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-09 15:34:16 +01:00
Denys Vlasenko
f20250266e Don't consider PROG to be our child in "strace -D PROG" case
TCB_STRACE_CHILD is used for the case when "strace PROG" is ^C-ed
or something like that. strace should not just exit - it should
do something with its child (such as signal it too).

In -D case, PROG is not really a child of _strace_, it is a child
of strace's parent. It's ok to handle it exactly as an attached process.

While we are at it, remove nonsensical special-casing of TCB_STRACE_CHILD
in printing of "<unfinished ...>" message.

* strace.c (startup_attach): Don't set TCB_STRACE_CHILD if -D.
(trace): Print "<unfinished ...>" on error regardless of TCB_STRACE_CHILD.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-09 15:29:45 +01:00
Denys Vlasenko
75fe85c2ee Fix the case where we try to detach unattached processes
Before this change:
$ strace -D -p1
strace: -D and -p are mutually exclusive options
Process 1 detached  <==== WRONG! (and we try to SIGSTOP it!!!)

* defs.h: Change the meaning of TCB_ATTACHED: now it means "this tracee
is attached to us". Add TCB_STRACE_CHILD: "this tracee is our child".
* strace.c (kill_save_errno): Move up. No code changes.
(process_opt_p_list): Don't set TCB_ATTACHED on new tcb.
(startup_attach): Change how we work with TCB_ATTACHED.
Set TCB_STRACE_CHILD on -D.
(startup_child): Use kill_save_errno instead of kill.
Set TCB_ATTACHED and TCB_STRACE_CHILD on attached strace child.
If we are in -D case, don't set TCB_ATTACHED (we aren't attached yet).
(detach): do not do PTRACE_DETACH if TCB_ATTACHED is not set.
(cleanup): Check TCB_STRACE_CHILD instead of TCB_ATTACHED.
(trace): Likewise.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-09 15:15:24 +01:00
Denys Vlasenko
97c503fa2e Call PTRACE_CONT with addr=0
* strace.c (trace): Call PTRACE_CONT with addr=0.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-09 15:11:21 +01:00
Denys Vlasenko
fd88338067 Fix PID prefix printing in "strace -oLOG -ff -p1 -p2 -p3" case
In this case we were printing PIDs to LOG.* files
even though it is not necessary.

The fix is in the addition of "&& followfork < 2" condition.

* strace.c: Remove pflag_seen variable, add print_pid_pfx one.
(process_opt_p_list): Do not pflag_seen++.
(main): Use "nprocs != 0" condition instead of "pflag_seen != 0".
Set print_pid_pfx before entering main tracing loop.
(printleader): Use print_pid_pfx to decide whether to print pid prefix.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-09 13:03:41 +01:00
Denys Vlasenko
e8172b79e3 Allow -p PID to take comma or whitespace-separated list of PIDs
* defs.h: Clarify meaning of TCB_ATTACHED. No code changes.
* strace.c (process_opt_p_list): New function.
(main): Call process_opt_p_list to process -p PIDs argument.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-09 13:01:04 +01:00
Denys Vlasenko
4c65c44478 Trivial tweaks to error messages
* strace.c (test_ptrace_setoptions_followfork): Use kill_save_errno
instead of kill.
(trace): Use perror_msg instead of perror.
* count.c (set_sortby): Use error_msg_and_die instead of fprintf.
* syscall.c (qualify): Likewise.
* util.c (ptrace_restart): Expand error message.
(umoven): Likewise.
(umovestr): Likewise.
(upeek): Use perror_msg instead of sprintf + perror.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-08 11:54:10 +01:00
Denys Vlasenko
1945ccc3fb Assorted trivial optimizations
text	   data	    bss	    dec	    hex	filename
 236448	    672	  19044	 256164	  3e8a4	strace.before
 236360	    672	  19044	 256076	  3e84c	strace

* file.c (sprintmode): Use smaller static buffer, eliminate strlen call.
(sprinttime): Use smaller static buffer.
(printstat_sparc64): Coalesce two printing calls into one.
(printstat_powerpc32): Likewise.
(printcompat_statfs6): Likewise.
(sys_utime): Do not fetch personality_wordsize[current_personality]
repeatedly - cache it in local variable instead.
* process.c (printargv): Likewise.
* resource.c (sprintrlim): Return const char*, not char*. This allows
to eliminate sprintf(buf, "RLIM_INFINITY"). Use smaller static buffer.
(sprintrlim64): Likewise.
* strace.c (strerror): Use smaller static buffer.
(strsignal): Likewise.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-02-27 14:37:48 +01:00
e83e157021 Compress blank lines
Suppress repeated empty lines left after automated code removal.
This change was made by filtering every source code file through
"cat -s".
2012-02-25 15:41:21 +00:00
Denys Vlasenko
1a3cf10c30 Build fixes after non-Linux code removal
* configure.ac: Remove calls to proc-based ptrace checks.
* proc.c: Remove, it's empty now.
* Makefile.am: Remove reference to proc.c.
* net.c: Remove trailing newlines.
* quota.c: Likewise
* resource.c: Likewise
* strace.c: Likewise
* stream.c: Likewise
* time.c: Likewise

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-02-25 02:54:34 +01:00
Denys Vlasenko
8470374cba Cleanup after non-Linux code removal.
Conditions such as defined(LINUX) are always true now,
defined(FREEBSD) etc are always false.
When if directive has them as subexpressions, it can be simplified.
Another trivial changes here are fixes for directive indentation.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-02-25 02:38:52 +01:00
Denys Vlasenko
ed720fda5d Automated removal of non-Linux code
This change is generated by running every source through the following command:

unifdef -DLINUX -Dlinux -USUNOS4 -USVR4 -UUNIXWARE -UFREEBSD
-USUNOS4_KERNEL_ARCH_KLUDGE -UHAVE_MP_PROCFS
-UHAVE_POLLABLE_PROCFS -UHAVE_PR_SYSCALL -UUSE_PROCFS file.c

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-02-25 02:24:03 +01:00
6c38156b6e Avoid potential core file clobbering on exit
* strace.c (main): Set RLIMIT_CORE to zero before terminating itself
with a deadly signal.
This fixes Debian bug #656398.
2012-02-22 00:15:27 +00:00
9aa25abb2e Remove initialization of native_scno field for most of syscalls
The native_scno field is not so much used in the code than before.
In many cases sys_func is checked instead, and for most of syscall
entries there is no need to initialize native_scno.

* linux/i386/syscallent.h: Remove native_scno initialization for
_exit, read, write, waitpid, execve, wait4, sysfs, readv, writev,
pread64, pwrite64, exit_group, waitid, send, recv, sendto and
recvfrom syscall entries.
* linux/syscall.h: Do not define no longer used SYS_waitid and
SYS_sub_* constants.
[IA64]: Do not define SYS_waitpid and SYS32_* constants.
* defs.h: Do not define no longer used  __NR_exit_group constant.
* strace.c [USE_PROCFS] (proc_open): Use sys_func to check for execve.
2012-02-20 00:36:01 +00:00
Denys Vlasenko
cdab1becb0 Trivial changes to help text. No code changes.
* strace.c (usage): Tweak help text: remove unpaired closing brackets,
make -V and -h sit on separate lines (hard to see them otherwise).

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-02-03 12:17:57 +01:00
Denys Vlasenko
4f3df078b2 Simple optimizations
text	   data	    bss	    dec	    hex	filename
 239474	    672	  20484	 260630	  3fa16	strace.before
 239234	    668	  19044	 258946	  3f382	strace

* file.c (sprint_open_modes): Reduce static buffer size.
Simplify separator printing.
* signal.c (sprintsigmask): Reduce static buffer size.
Simplify separator printing and printing of almost full masks.
Use stpcpy instead of sprintf and strcpy+strlen.
* strace.c (startup_child): Don't strchr() for ':' twice in a row.
* util.c (sprintflags): Exit loop early if possible.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-29 22:38:35 +01:00
Denys Vlasenko
3521884c91 Trivial optimization
* strace.c (cleanup): Read 'interrupted' volatile variable only once.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-29 21:17:56 +01:00
Denys Vlasenko
b51581e8f0 Make interactive-ness directly controllable via command line option
Defaults are often ok, but when they are not, people get confused.
"Why can't I kill strace?" and "Why strace dies on ^C when I want
to _tracee_ to die instead?" are typical complaints.

* strace.c: Replace 'interactive' variable with 'opt_intr' variable.
Define INTR_foo constants for its possible values.
Define 'interactive' as a macro.
(usage): Document -I n option.
(main): Parse -I n option, modify signal handling to accomidate new
-I 1 and -I 4 modes.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-29 16:53:03 +01:00
Denys Vlasenko
6703816060 Suppress compiler warning
* strace.c (trace): Frame potentially unused label with ifdef/endif.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-29 16:46:46 +01:00
Denys Vlasenko
a3559250d4 On Ctrl-C induced detach, send SIGINT to child tracee, not SIGTERM.
* strace.c (interrupt): Remember signal number.
(cleanup): If we exiting due to signal, send that signal to child tracee.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-29 16:43:51 +01:00
Denys Vlasenko
31fa8a22b1 Add experimental code to use PTRACE_SEIZE, disabled by default
All new code is predicated on "ifdef USE_SEIZE". If it is not defined,
behavior is not changed.

If USE_SEIZE is enabled and run-time check shows that PTRACE_SEIZE works, then:
- All attaching is done with PTRACE_SEIZE + PTRACE_INTERRUPT.
  This means that we no longer generate (and possibly race with) SIGSTOP.
- PTRACE_EVENT_STOP will be generated if tracee is group-stopped.
  When we detect it, we issue PTRACE_LISTEN instead of PTRACE_SYSCALL.
  This leaves tracee stopped. This fixes the inability to SIGSTOP or ^Z
  a straced process.

* defs.h: Add commented-out "define USE_SEIZE 1" and define PTRACE_SEIZE
and related constants.
* strace.c: New variable post_attach_sigstop shows whether we age going
to expect SIGSTOP on attach (IOW: are we going to use PTRACE_SEIZE).
(ptrace_attach_or_seize): New function. Uses PTRACE_ATTACH or
PTRACE_SEIZE + PTRACE_INTERRUPT to attach to given pid.
(startup_attach): Use ptrace_attach_or_seize() instead of ptrace(PTRACE_ATTACH).
(startup_child): Conditionally use alternative attach method using PTRACE_SEIZE.
(test_ptrace_setoptions_followfork): More robust parameters to PTRACE_TRACEME.
(test_ptrace_seize): New function to test whether PTRACE_SEIZE works.
(main): Call test_ptrace_seize() while initializing.
(trace): If PTRACE_EVENT_STOP is seen, restart using PTRACE_LISTEN in order
to not let tracee run.
* process.c: Decode PTRACE_SEIZE, PTRACE_INTERRUPT, PTRACE_LISTEN.
* util.c (ptrace_restart): Add "LISTEN" to a possible error message.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-29 02:01:44 +01:00
Denys Vlasenko
000b601439 Fix a case of broken output if last seen syscall was exit
* defs.h: Rename tcp_last to printing_tcp. Explain what it means.
Remove printtrailer() function.
* process.c (sys_exit): Convert printtrailer() call to "printing_tcp = NULL".
* strace.c: Add new variable printing_tcp.
(cleanup): Convert printtrailer() call to "printing_tcp = NULL".
(trace): Likewise.
(trace): Fix checks for incomplete line - it was working wrongly if last syscall was exit.
(printleader): Set printing_tcp.
(printtrailer): Remove this function.
* syscall.c: Remove tcp_last variable.
(trace_syscall_entering): Don't set printing_tcp, printleader call now does it.
(trace_syscall_exiting): Convert printtrailer() call to "printing_tcp = NULL".

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-28 01:25:03 +01:00
Denys Vlasenko
f7db5dd876 Fix handling of test/threaded_execve.c testcase
Since 3.0, Linux has a way to identify which thread execve'ed.
This patch makes use of it in order to properly dispose
of disappeared ("superseded") thread leader,
and replace it with execve'ed thread.

Before this patch, strace was "leaking" thread which exec'ed.
It was thinking that it still runs. It would look like this:

18460 pause( <unfinished ...>     <=== thread leader
18466 execve("/proc/self/exe", ["exe", "exe"], [/* 47 vars */] <unfinished ...>
18465 +++ exited with 0 +++       <=== exits from other threads
18460 <... pause resumed> )             = 0

The last line is wrong: it's not pause resumed, it's execve resumed.
If thread leader would do exit instead of pause, it is much worse:
strace panics because it thinks it sees return from exit syscall!

And strace isn't aware 18466 (exec'ed thread) is gone.
It still thinks it's executes execve syscall.

* strace.c: New variable "static char *os_release".
(get_os_release): New static function.
(main): Call get_os_release to retrieve Linux version.
(trace): If we see PTRACE_EVENT_EXEC, retrieve old pid, and if it
differs from new one, free one of tcbs and print correct messages.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-28 01:16:02 +01:00
Denys Vlasenko
eebb04d4ae Make pid2tcb static
* defs.h: Remove pid2tcb declaration.
* strace.c (pid2tcb): Make this function static.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-27 15:24:48 +01:00
Denys Vlasenko
cfad543087 Per Dmitry's request, remove paranoid check in verror_msg()
* strace.c (verror_msg): Remove redundant check for msg != NULL.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-24 12:48:02 +01:00
Denys Vlasenko
846ecb9b44 More robust error check for vasprintf
* strace.c (verror_msg): More robust error check for vasprintf.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-24 11:50:05 +01:00
Denys Vlasenko
837399af4f Slightly more compact handling of argv[]
text	   data	    bss	    dec	    hex	filename
 238274	    672	  20484	 259430	  3f566	strace.before
 238226	    672	  20484	 259382	  3f536	strace

* strace.c (main): Slightly more compact handling of argv[]

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-24 11:50:04 +01:00
Denys Vlasenko
aa6ec415c1 Trivial optimization
* strace.c: Set default interactive = 1 statically instead
of doing it in main().

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-24 11:50:04 +01:00
Denys Vlasenko
a677da5e3f Allocate -o OUTFILE buffer only if needed
text	   data	    bss	    dec	    hex	filename
 238258	    668	  28676	 267602	  41552	strace.before
 238274	    668	  20484	 259426	  3f562	strace

* strace.c (main): Allocate -o OUTFILE buffer only if needed:
unused buffer in bss is not entirely free.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-24 11:50:04 +01:00
Denys Vlasenko
82bb78c149 Use single fprintf in verror_msg()
This change partially reverts commit 44d0532.

In code before commit 44d0532, single fprintf was used on purpose:
we want to send entire message as one write() call. Since stderr
is unbuffered, separate fprintf's to it always result in separate
writes, they are not coalesced. If we aren't the only program
which writes to this particular stderr, this may result
in interleaved messages.

Since this function is not performance critical, I guess
it's ok to make it less efficient.

* strace.c (verror_msg): Attempt to print the message in single
write operation. Use separate fprintfs as a fallback if malloc fails.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-01-24 10:17:18 +01:00
Denys Vlasenko
023b7700de Get rid of TCB_SIGTRAPPED
On attempts to block or set SIGTRAP handler,
for example, using sigaction syscall, we generate
an additional SIGSTOP.

This change gets rid of this SIGSTOP sending/ignoring.
It appears to work just fine.

It also works if I force strace to not use PTRACE_O_TRACESYSGOOD,
which means strace stops will be marked with SIGTRAP,
not (SIGTRAP | 0x80) - I wondered maybe that's when
this hack is needed.

So, why we even have TCB_SIGTRAPPED? No one knows. It predates
version control: this code was present in the initial commit,
in 1999. No adequate comments, either.

Moreover, TCB_SIGTRAPPED is not set in sys_rt_sigaction
and sys_sigprocmask syscalls - the ones which are most usually
used to implement signal blocking, it is only set in obsolete
sys_signal, sys_sigaction, sys_sigsetmask, and in some dead
non-Linux code.

I think whatever bug it was fixing is gone long ago -
at least as long as sys_rt_sigaction is used by glibc.
Again, since glibc (and uclibc) uses sys_rt_sigaction
and sys_sigprocmask, modified code paths are not used
by most programs anyway.

* defs.h: Remove definition of TCB_SIGTRAPPED.
* signal.c (sys_sigvec): Don't set TCB_SIGTRAPPED and don't send SIGSTOP.
(sys_sigsetmask): Likewise.
(sys_sigaction): Likewise.
(sys_signal): Likewise.
* strace.c (trace): Remove code which executes if TCB_SIGTRAPPED is set.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-18 16:30:47 +01:00
Denys Vlasenko
5e09d77500 When we write log, flush output buffers in a few more cases
I observed a case when signal delivery message was buffered
by stdio until it was flushed along with the next syscall
entry message.

* strace.c (trace): Flush output buffers in a few more cases.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-18 16:20:56 +01:00
Denys Vlasenko
f1e6903703 Do not detach from tracee which experienced ptrace error.
Before this patch, if a thread got nuked by exit in another thread
and we happened to poke it at the same time, we print "????(" thingy
and detach the thread. Since we removed "detach before death" logic,
this no longer matches the behavior of other threads.
Before patch:
[pid  1780] exit_group(1)               = ?
[pid  1778] ????( <unfinished ...>
Process 1778 detached
[pid  5860] +++ exited with 1 +++
After:
[pid 17765] exit_group(1)               = ?
[pid 21680] ????( <unfinished ...>
[pid 17791] +++ exited with 1 +++
[pid 21680] +++ exited with 1 +++

* strace (trace): Do not detach from tracee which experienced ptrace error.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-04 15:15:26 +01:00
Denys Vlasenko
4c1963836f Remove sig parameter from detach()
* strace.c (detach): Drop sig parameter - it is zero in all calls.
(cleanup): Don't pass sig = 0 to detach() call.
(detach): Ditto.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-04 15:11:09 +01:00
a5a839a920 Enhance personality switching
On syscall entry, save current personality in the tcb structure
along with scno.
On syscall exit, restore current personality from the tcb structure.
* defs.h (struct tcb) [SUPPORTED_PERSONALITIES > 1]: Add currpers
field.
* strace.c (alloc_tcb) [SUPPORTED_PERSONALITIES > 1]: Initialize
tcp->currpers.
* syscall.c (update_personality) [SUPPORTED_PERSONALITIES > 1]: New
function.
(get_scno, trace_syscall_exiting): Use it.

Reported-by: Michael A Fetterman <mafetter@nvidia.com>
2011-12-23 00:50:49 +00:00
436d892212 strace.c (trace): Fix compilation warning 2011-11-29 00:15:59 +00:00
Denys Vlasenko
f88837a666 Do post-attach initialization earlier; fix "we ignore SIGSTOP on NOMMU" bug
We set ptrace options when we see post-attach SIGSTOP.
This is wrong: it's better to set them right away on the very first
stop (whichever it will be). It also will make adding SEIZE support easier,
since SEIZE has no post-attach SIGSTOP.

We do it by adding a new bit, TCB_IGNORE_ONE_SIGSTOP, and treating
TCB_STARTUP and TCB_IGNORE_ONE_SIGSTOP as two slightly different things.

* defs.h: Add a new flag bit, TCB_IGNORE_ONE_SIGSTOP.
* process.c (internal_fork): Set TCB_IGNORE_ONE_SIGSTOP on a newly added child.
* strace.c (startup_attach): Set TCB_IGNORE_ONE_SIGSTOP after attach.
Fix a case when "strace -p PID" found PID dead but sone other of its threads
still alive.
(startup_child): Set TCB_IGNORE_ONE_SIGSTOP after attach, _if needed_.
This fixes a bogus case where we can ignore a _real_ SIGSTOP on NOMMU.
(detach): Perform anti-SIGSTOP dance only if TCB_IGNORE_ONE_SIGSTOP is set,
not if TCB_STARTUP is set.
(trace): Set TCB_IGNORE_ONE_SIGSTOP after attach.
Clear TCB_STARTUP and initialize tracee on the very first tracee stop.
Clear TCB_IGNORE_ONE_SIGSTOP when SIGSTOP is seen.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-09-05 14:05:46 +02:00
Denys Vlasenko
d116a73386 Get rid of TCB_ATTACH_DONE
* defs.h: Remove TCB_ATTACH_DONE constant.
* strace.c (startup_attach): Use TCB_STARTUP instead of TCB_ATTACH_DONE
to distinquish attached from not-yet-attached threads.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-09-05 14:01:33 +02:00
Denys Vlasenko
381dbc2292 Set TCB_STARTUP only _after_ we attached.
This fixes logic in detach() which thinks that TCB_STARTUP
means that we are already attached, but did not see SIGSTOP yet.
This also allows to get rid of TCB_ATTACH_DONE flag.

* process.c (internal_fork): Set TCB_STARTUP after attach.
* strace.c (startup_attach): Likewise.
(startup_child): Likewise.
(alloc_tcb): Do not set TCB_STARTUP on tcb allocation - we are
not attached yet.
(trace): Set TCB_STARTUP when we detech an auto-attached child.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-09-05 13:59:39 +02:00
Denys Vlasenko
6cda73ff9c Simple optimizations in trace()
* strace.c (trace): Calculate WSTOPSIG(status) once,
unify code paths to ptrace(PTRACE_SYSCALL).

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-09-02 16:23:53 +02:00
Denys Vlasenko
014ca3a53c Trivial fixes on error paths
* strace.c (startup_attach): Emit message on fork() failure.
(startup_child): Remove non-informative comment.
* util.c (ptrace_restart): use perror_msg() on error instead of fprintf().

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-09-02 16:19:30 +02:00
Denys Vlasenko
ab034fbf09 Reformat setuid-ing code in startup_child()
New code does the same as old one, but is more readable (I hope).

* strace.c (startup_child): Reformat setuid-ing code.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-09-01 10:27:42 +02:00
Denys Vlasenko
2e968c0bb7 Minor tweaks in startup_child(). Logic isn't changed (but code is)
* strace.c (startup_attach): Tweak comment.
(startup_child): Move common code out of ifdef.
Indent nested ifdefs. Tweak comments. Remove two
unnecessary calls to getpid().

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-09-01 10:23:09 +02:00
Denys Vlasenko
60fe8c139c Use tprints with literal strings, it may be faster than tprintf
* bjm.c: Replace tprintf("str") with tprints("str").
* block.c: Likewise.
* desc.c: Likewise.
* file.c: Likewise.
* io.c: Likewise.
* ipc.c: Likewise.
* mem.c: Likewise.
* net.c: Likewise.
* proc.c: Likewise.
* process.c: Likewise.
* quota.c: Likewise.
* resource.c: Likewise.
* scsi.c: Likewise.
* signal.c: Likewise.
* sock.c: Likewise.
* strace.c: Likewise.
* stream.c: Likewise.
* syscall.c: Likewise.
* system.c: Likewise.
* term.c: Likewise.
* time.c: Likewise.
* util.c: Likewise.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-09-01 10:00:28 +02:00
Denys Vlasenko
5940e65939 Fix "format not a string literal" warning caused by tprintf(str)
* defs.h: Declare tprints().
* strace.c: Define tprints().
(tabto): Use tprints(str), since tprintf(str) was throwing a warning.
* desc.c: Use tprints(str) instead of tprintf("%s", str).
* file.c: Likewise.
* io.c: Likewise.
* net.c: Likewise.
* process.c: Likewise.
* signal.c: Likewise.
* syscall.c: Likewise.
* util.c: Likewise.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-09-01 09:55:05 +02:00
Denys Vlasenko
1d46ba57a8 Make out-of-memory handling more uniform
This fixes one real bug in dumpstr().

* defs.h: Declare die_out_of_memory().
* strace.c (die_out_of_memory): New function.
(strace_popen): If allocation fails, call die_out_of_memory().
(main): Likewise.
(expand_tcbtab): Likewise.
(rebuild_pollv): Likewise.
* count.c (count_syscall): Likewise.
(call_summary_pers): Likewise.
* desc.c (decode_select): Likewise.
* file.c (sys_getdents): Likewise.
(sys_getdents64): Likewise.
(sys_getdirentries): Likewise.
* pathtrace.c (pathtrace_match): Likewise.
* syscall.c (qualify): Likewise.
* util.c (printstr): Likewise.
(dumpiov): Likewise.
(dumpstr): Likewise.
(fixvfork): Likewise.
* mem.c (sys_mincore): Don't check free() parameter for NULL.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-31 14:00:02 +02:00
a673f3fa62 Do not include <limits.h>
* strace.c: Do not include <limits.h> explicitly, it is already included
implicitly by <sys/param.h>.
2011-08-30 16:07:01 +00:00
Denys Vlasenko
102ec49354 Optimize tabto()
tabto is used in many lines of strace output.
On glibc, tprintf("%*s", col - curcol, "") is noticeably slow
compared to tprintf("                 "). Use the latter.
Observed ~15% reduction of time spent in userspace.

* defs.h: Drop extern declaration of acolumn. Make tabto()
take no parameters.
* process.c (sys_exit): Call tabto() with no parameters.
* syscall.c (trace_syscall_exiting): Call tabto() with no parameters.
* strace.c: Make acolumn static, add static char *acolumn_spaces.
(main): Allocate acolumn_spaces as a string of spaces.
(printleader): Call tabto() with no parameters.
(tabto): Use simpler method to print lots of spaces.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-25 01:27:59 +02:00
Denys Vlasenko
06602d99b7 Rename some functions, delete unused one. No code changes
* defs.h: Rename get_scno_on_sysenter() to get_scno();
delete force_result() declaration.
* strace.c (proc_open): Rename get_scno_on_sysenter() to get_scno().
* syscall.c: Rename get_scno_on_sysenter() to get_scno().
Rename get_scno_on_sysexit() to get_syscall_result().
Delete unused force_result().

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-24 17:53:52 +02:00
Denys Vlasenko
9a36ae5e88 get_scno is an unholy mess, make it less horrible
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>
2011-08-24 16:47:32 +02:00
Denys Vlasenko
b88f96129f Straighten up confused comments/messages about post-execve SIGTRAP handling
* 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>
2011-08-23 12:53:02 +02:00
Denys Vlasenko
2ecba32d52 Optimize out dummy PC printing on signal delivery
* strace.c (trace): Optimize out dummy PC printing on signal delivery.
While at it, tweak comments.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-23 12:53:02 +02:00
Denys Vlasenko
0890c8a403 Cosmetic improvement in ifdefs. No code changes
* strace.c (proc_open): Change ifdefs so that braces are properly paired.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-23 12:53:02 +02:00
Denys Vlasenko
8dc0c8c5ef Exclude tcp->pfd from non-procfs systems
* defs.h: Make struct tcb::pfd fields conditional on USE_PROCFS.
* strace.c (alloc_tcb): Use tcp->pfd only if USE_PROCFS.
(droptcb): Likewise.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-23 12:53:01 +02:00
Denys Vlasenko
cfd364b011 Small optimizations related to memory allocation
* strace (expand_tcbtab): Shorten "out of memory" message.
(rebuild_pollv): Remove unnecessary NULL check before free().
* util.c (dumpstr): Add a comment about likely bug.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-23 12:53:01 +02:00
Denys Vlasenko
5d64581e10 Improve code readability by avoiding assignments inside if()
* desc.c (decode_select): Move assignment out of if() condition.
* file.c (sprinttime): Likewise.
(sys_getdirentries): Likewise.
* io.c (sys_ioctl): Likewise.
* strace.c (test_ptrace_setoptions_followfork): Likewise.
(main): Likewise.
(proc_open): Likewise.
(detach): Likewise.
(proc_poll): Likewise.
(trace): Likewise.
* syscall.c (qualify): Likewise.
(sys_indir): Likewise.
* test/procpollable.c (main): Likewise.
* test/sfd.c (main): Likewise.
* time.c (printtv_bitness): Likewise.
(sprinttv): Likewise.
(print_timespec): Likewise.
(void sprint_timespec): Likewise.
(printitv_bitness): Likewise.
* util.c (dumpstr): Likewise.
(umovestr): Likewise.
(fixvfork): Likewise.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-23 12:53:01 +02:00
04f8b4860f Fix PTRACE_SETOPTIONS tests
* strace.c [LINUX] (kill_save_errno): New function.
(test_ptrace_setoptions_followfork): Change return type to void.
Fix and harden error handling.  Use kill_save_errno() to avoid errno
clobbering.  Treat EIO from ptrace() the same way as EINVAL.
(test_ptrace_setoptions_for_all): Use kill_save_errno() to avoid errno
clobbering.  Treat EIO from ptrace() the same way as EINVAL.
(main): Update use of test_ptrace_setoptions_followfork().
2011-08-23 12:53:00 +02:00
Denys Vlasenko
44f87efc67 Remove tcp->parent and TCB_CLONE_THREAD.
tcp->parent is used for only two things:
(1) to send signal on detach via tgkill (need to know tgid).
Solution: use tkill, it needs only tid.
(2) to optimize out ptrace options setting for new tracees.
Not a big deal if we drop this optimization: "set options" op is fast,
doing it just one extra time once per each tracee is hardly measurable.

TCB_CLONE_THREAD is a misnomer. It used only to flag sibling we attached to
in startup_attach. This is used to prevent infinite recursive rescanning
of /proc/PID/task.
Despite the name, there is no guarantee it is set only on non-leader:
if one would run "strace -f -p THREAD_ID" and THREAD_ID is *not*
a thread leader, strace will happily attach to it and all siblings
and will think that THREAD_ID is the leader! Which is a bug, but
since we no longer detach when we think tracee is going to die,
this bug no longer matters, because we do not use the knowledge
about thread group leaders for anything. (We used it to delay
leader's exit).

IOW: after this patch strace has no need to know about threads, parents
and children, and so on. Therefore it does not track that information.
It treats all tracees as independent entities. Overall,
this simplifies code a lot.

* defs.h: Add TCB_ATTACH_DONE flag, remove TCB_CLONE_THREAD flag
and struct tcb::parent field.
* process.c (internal_fork): Don't set tcpchild->parent.
* strace.c (startup_attach): Use TCB_ATTACH_DONE flag instead of
TCB_CLONE_THREAD to avoid attach attempts on already-attached threads.
Unlike TCB_CLONE_THREAD, TCB_ATTACH_DONE bit is used only temporarily,
and only in this function. We clear it on every tcb before we return.
(detach): Use tkill instead of tgkill.
(trace): Set ptrace options on new tracees unconditionally,
not only when tcp->parent == NULL.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-17 15:18:21 +02:00
Denys Vlasenko
833fb13cef Remove TCB_SUSPENDED constant and related code.
Since we no longer suspend waitpid'ing tracees, we have only one case when
we suspend tracee: when we pick up a new tracee created by clone/fork/vfork.

Background: on some other OSes, attach to child is done this way:
get fork's result (pid), loop ptrace(PTRACE_ATTACH) until you hook up
new process/thread. This is ugly and not safe, but what matters for us
is that it doesn't require suspending. Suspending is required
on Linux only, because on Linux attach to child is done differently.

On Linux, we use two methods of catching new tracee:
adding CLONE_THREAD bit to syscall (if needed, we change
[v]fork into clone before that), or using ptrace options.
In both cases, it may be so that new tracee appears before one which
created it returns from syscall. In this case, current code
suspends new tracee until its creator returns. Only then
strace can determine who is its parent (it needs child's pid for this,
which is visible in parent's [v]fork/clone result).
This is inherently racy. For example, what if SIGKILL kills
creator after it succeeded creating child, but before it returns?
Looks like we will have child suspended forever.

But after previous commit, we DO NOT NEED parent<->child link for anything.
Therefore we do not need suspending too. Bingo!

This patch removes suspending code. Now new tracees will be continued
right away. Next patch will remove tcp->parent member.

* defs.h: Remove TCB_SUSPENDED constant
* process.c (handle_new_child): Delete this function.
  (internal_fork): Do not call handle_new_child on syscall exit.
* strace.c (handle_ptrace_event): Delete this function.
  (trace): Do not suspend new child; remove all handling
  of now impossible TCB_SUSPENDED condition.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-17 11:30:56 +02:00
Denys Vlasenko
19cdada5b4 Do not detach when we think tracee is going to die.
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>
2011-08-17 10:45:32 +02:00