Catching up on my mail-backlog, see ChangeLog for details
This commit is contained in:
parent
5a777663d5
commit
9ce1a63eb2
2
CREDITS
2
CREDITS
@ -34,3 +34,5 @@ porting to new systems:
|
||||
Ulrich Drepper <drepper@cygnus.com>
|
||||
Nate Eldredge <nate@cartsys.com>
|
||||
Jakub Jelinek <jj@ultra.linux.cz>
|
||||
John Hughes <john@Calva.COM>
|
||||
Richard Braakman <dark@xs4all.nl>
|
||||
|
21
ChangeLog
21
ChangeLog
@ -1,7 +1,28 @@
|
||||
Mon Aug 30 00:53:57 CEST 1999 Wichert Akkerman <wakkerma@debian.org>
|
||||
|
||||
* Merge patch from Daniel Jacobowitz: KERN_JAVA_* and KERN_SECURELVL aren't
|
||||
defined for all kernelversions
|
||||
* Add strace-graph
|
||||
|
||||
Thu Aug 19 13:10:15 CEST 1999 Jakub Jelinek <jj@ultra.linux.cz>
|
||||
|
||||
* linux/sparc/syscall.h: Declare create_module/init_module.
|
||||
* configure.in: Allow compilation in a different directory
|
||||
than the source one.
|
||||
* signal.c: Use asm/reg.h and struct regs instead of pt_regs
|
||||
so that we don't depend on asm/ptrace.h which clashes with
|
||||
glibc sys/ptrace.h.
|
||||
* util.c: Likewise.
|
||||
* syscall.c: Likewise.
|
||||
|
||||
Wed Aug 4 18:01:50 CEST 1999 Wichert Akkerman <wakkerma@debian.org>
|
||||
|
||||
* Syscall 94 on Linux alpha is sys_poll
|
||||
|
||||
Sun Jul 25 14:38:33 CEST 1999 Wichert Akkerman <wakkerma@debian.org>
|
||||
|
||||
* Merge in UnixWare patches from John Hughes <john@Calva.COM>
|
||||
|
||||
Thu Jul 15 23:00:32 CEST 1999 Wichert Akkerman <wakkerma@debian.org>
|
||||
|
||||
* Merge patch from Maciej W. Rozycki <macro@ds2.pg.gda.pl>:
|
||||
|
@ -59,6 +59,7 @@ strace: $(OBJ)
|
||||
|
||||
install: all
|
||||
$(INSTALL_PROGRAM) strace $(bindir)/strace
|
||||
$(INSTALL_PROGRAM) strace-graph $(bindir)/strace-graph
|
||||
$(INSTALL_DATA) $(srcdir)/strace.1 $(man1dir)/strace$(man1ext)
|
||||
|
||||
clean: clean-local
|
||||
|
10
README-svr4
10
README-svr4
@ -9,4 +9,12 @@ lot of processes at once.
|
||||
|
||||
There is no thread support but it wouldn't be very difficult to add it.
|
||||
|
||||
Rick Sladkey <jrs@world.std.com>
|
||||
There is currently no configure-support yet for UnixWare system. To compile
|
||||
on UnixWare 2.1 you need to add the following to config.h yourself:
|
||||
|
||||
#define SVR4_MP 1
|
||||
#define UNIXWARE 2
|
||||
#define HAVE_POLLABLE_PROCFS 1
|
||||
|
||||
Wichert Akkerman <wakkerma@debian.org>
|
||||
|
||||
|
1
TODO
1
TODO
@ -5,6 +5,7 @@ replace printargs with something that reads a configuration-file
|
||||
rename functions that are used for general things:
|
||||
sys_chdir -> general_1stringarg
|
||||
generate syscallent.h from the kernel sources
|
||||
add IPv6 support
|
||||
|
||||
|
||||
-- old entries from jrs
|
||||
|
@ -125,9 +125,12 @@ AC_TYPE_GETGROUPS
|
||||
AC_HEADER_MAJOR
|
||||
AC_SIG_ATOMIC_T
|
||||
AC_CHECK_LIB(nsl, main)
|
||||
AC_CHECK_FUNCS(sigaction strerror strsignal pread sys_siglist _sys_siglist getdents mctl putpmsg prctl sendmsg)
|
||||
AC_CHECK_FUNCS(sigaction strerror strsignal pread sys_siglist _sys_siglist getdents mctl putpmsg prctl sendmsg inet_ntop)
|
||||
AC_CHECK_HEADERS(sys/reg.h sys/filio.h sys/acl.h sys/asynch.h sys/door.h sys/stream.h sys/tiuser.h sys/sysconfig.h asm/sigcontext.h ioctls.h sys/ioctl.h sys/ptrace.h termio.h)
|
||||
AC_DECL_SYS_ERRLIST
|
||||
AC_DECL_SYS_SIGLIST
|
||||
AC_DECL__SYS_SIGLIST
|
||||
if test ! -d $osarch; then
|
||||
mkdir -p $osarch
|
||||
fi
|
||||
AC_OUTPUT(Makefile $osarch/Makefile)
|
||||
|
44
defs.h
44
defs.h
@ -77,6 +77,9 @@
|
||||
|
||||
#ifdef SVR4
|
||||
#include <sys/procfs.h>
|
||||
#ifdef SVR4_MP
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
#else /* !SVR4 */
|
||||
#if defined(LINUXSPARC) && defined(__GLIBC__)
|
||||
#include <sys/ptrace.h>
|
||||
@ -131,6 +134,41 @@ extern int ptrace();
|
||||
#define SUPPORTED_PERSONALITIES 2
|
||||
#endif /* LINUXSPARC */
|
||||
|
||||
|
||||
#ifdef SVR4
|
||||
#ifdef SVR4_MP
|
||||
extern int mp_ioctl (int f, int c, void *a, int s);
|
||||
#define IOCTL(f,c,a) mp_ioctl (f, c, a, sizeof *a)
|
||||
#define IOCTL_STATUS(t) \
|
||||
pread (t->pfd_stat, &t->status, sizeof t->status, 0)
|
||||
#define IOCTL_WSTOP(t) \
|
||||
(IOCTL (t->pfd, PCWSTOP, NULL) < 0 ? -1 : \
|
||||
IOCTL_STATUS (t))
|
||||
#define PR_WHY pr_lwp.pr_why
|
||||
#define PR_WHAT pr_lwp.pr_what
|
||||
#define PR_REG pr_lwp.pr_context.uc_mcontext.gregs
|
||||
#define PR_FLAGS pr_lwp.pr_flags
|
||||
#define PIOCSTIP PCSTOP
|
||||
#define PIOCSET PCSET
|
||||
#define PIOCRESET PCRESET
|
||||
#define PIOCSTRACE PCSTRACE
|
||||
#define PIOCSFAULT PCSFAULT
|
||||
#define PIOCWSTOP PCWSTOP
|
||||
#define PIOCSTOP PCSTOP
|
||||
#define PIOCSENTRY PCSENTRY
|
||||
#define PIOCSEXIT PCSEXIT
|
||||
#define PIOCRUN PCRUN
|
||||
#else
|
||||
#define IOCTL ioctl
|
||||
#define IOCTL_STATUS(t) ioctl (t->pfd, PIOCSTATUS, &t->status)
|
||||
#define IOCTL_WSTOP(t) ioctl (t->pfd, PIOCWSTOP, &t->status)
|
||||
#define PR_WHY pr_why
|
||||
#define PR_WHAT pr_what
|
||||
#define PR_REG pr_reg
|
||||
#define PR_FLAGS pr_flags
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Trace Control Block */
|
||||
struct tcb {
|
||||
short flags; /* See below for TCB_ values */
|
||||
@ -154,8 +192,14 @@ struct tcb {
|
||||
long inst[2]; /* Instructions on above */
|
||||
int pfd; /* proc file descriptor */
|
||||
#ifdef SVR4
|
||||
#ifdef SVR4_MP
|
||||
int pfd_stat;
|
||||
int pfd_as;
|
||||
pstatus_t status;
|
||||
#else
|
||||
prstatus_t status; /* procfs status structure */
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
/* TCB flags */
|
||||
|
10
io.c
10
io.c
@ -152,9 +152,14 @@ struct tcb *tcp;
|
||||
tprintf("%#lx", tcp->u_arg[1]);
|
||||
else
|
||||
printstr(tcp, tcp->u_arg[1], tcp->u_rval);
|
||||
#if UNIXWARE
|
||||
/* off_t is signed int */
|
||||
tprintf(", %lu, %ld", tcp->u_arg[2], tcp->u_arg[3]);
|
||||
#else
|
||||
tprintf(", %lu, %llu", tcp->u_arg[2],
|
||||
(((unsigned long long) tcp->u_arg[4]) << 32
|
||||
| tcp->u_arg[3]));
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -166,9 +171,14 @@ struct tcb *tcp;
|
||||
if (entering(tcp)) {
|
||||
tprintf("%ld, ", tcp->u_arg[0]);
|
||||
printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
|
||||
#if UNIXWARE
|
||||
/* off_t is signed int */
|
||||
tprintf(", %lu, %ld", tcp->u_arg[2], tcp->u_arg[3]);
|
||||
#else
|
||||
tprintf(", %lu, %llu", tcp->u_arg[2],
|
||||
(((unsigned long long) tcp->u_arg[4]) << 32
|
||||
| tcp->u_arg[3]));
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
2
ioctl.c
2
ioctl.c
@ -108,8 +108,10 @@ long code, arg;
|
||||
#endif /* !LINUX */
|
||||
return sock_ioctl(tcp, code, arg);
|
||||
#ifdef SVR4
|
||||
#ifndef SVR4_MP
|
||||
case 'q':
|
||||
return proc_ioctl(tcp, code, arg);
|
||||
#endif
|
||||
#endif /* SVR4 */
|
||||
#ifdef HAVE_SYS_STREAM_H
|
||||
case 'S':
|
||||
|
@ -99,6 +99,7 @@ int sys_sigaltstack(), sys_rt_sigprocmask(), sys_rt_sigaction();
|
||||
int sys_rt_sigpending(), sys_rt_sigsuspend(), sys_rt_sigqueueinfo();
|
||||
int sys_rt_sigtimedwait(), sys_prctl(), sys_poll();
|
||||
int sys_sendfile(), sys_query_module(), sys_capget(), sys_capset();
|
||||
int sys_create_module(), sys_init_module();
|
||||
|
||||
int sys_umask(); /* XXX */
|
||||
|
||||
|
17
net.c
17
net.c
@ -311,6 +311,10 @@ long addr;
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) &sa;
|
||||
struct sockaddr_un sau;
|
||||
#ifdef HAVE_INET_NTOP
|
||||
struct sockaddr_in6 sa6;
|
||||
char string_addr[100];
|
||||
#endif
|
||||
#ifdef LINUX
|
||||
struct sockaddr_ipx sipx;
|
||||
#endif
|
||||
@ -340,6 +344,19 @@ long addr;
|
||||
tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}",
|
||||
ntohs(sin->sin_port), inet_ntoa(sin->sin_addr));
|
||||
break;
|
||||
#ifdef HAVE_INET_NTOP
|
||||
case AF_INET6:
|
||||
if (umove(tcp, addr, &sa6) < 0)
|
||||
tprintf("{sin6_family=AF_INET6, ...}");
|
||||
else
|
||||
{
|
||||
tprintf("{sin6_family=AF_INET6, ");
|
||||
inet_ntop(AF_INET6, &sa6.sin6_addr, string_addr, sizeof(string_addr));
|
||||
tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=htonl(%u)",
|
||||
ntohs(sa6.sin6_port), string_addr, ntohl(sa6.sin6_flowinfo));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(AF_IPX) && defined(linux)
|
||||
case AF_IPX:
|
||||
if (umove(tcp, addr, &sipx)<0)
|
||||
|
2
proc.c
2
proc.c
@ -30,6 +30,7 @@
|
||||
#include "defs.h"
|
||||
|
||||
#ifdef SVR4
|
||||
#ifndef SVR4_MP
|
||||
|
||||
static struct xlat proc_status_flags[] = {
|
||||
{ PR_STOPPED, "PR_STOPPED" },
|
||||
@ -182,5 +183,6 @@ int code, arg;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SVR4_MP */
|
||||
#endif /* SVR4 */
|
||||
|
||||
|
11
signal.c
11
signal.c
@ -54,8 +54,9 @@
|
||||
#ifdef HAVE_ASM_SIGCONTEXT_H
|
||||
#include <asm/sigcontext.h>
|
||||
#ifdef SPARC
|
||||
#include <asm/reg.h>
|
||||
typedef struct {
|
||||
struct pt_regs si_regs;
|
||||
struct regs si_regs;
|
||||
int si_mask;
|
||||
} m_siginfo_t;
|
||||
#endif
|
||||
@ -227,6 +228,7 @@ int sig;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef UNIXWARE
|
||||
static void
|
||||
long_to_sigset(l, s)
|
||||
long l;
|
||||
@ -235,6 +237,7 @@ sigset_t *s;
|
||||
sigemptyset(s);
|
||||
*(long *)s = l;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
copy_sigset_len(tcp, addr, s, len)
|
||||
@ -778,18 +781,16 @@ struct tcb *tcp;
|
||||
#else
|
||||
#ifdef SPARC
|
||||
long i1;
|
||||
struct pt_regs regs;
|
||||
struct regs regs;
|
||||
m_siginfo_t si;
|
||||
|
||||
if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) {
|
||||
perror("sigreturn: PTRACE_GETREGS ");
|
||||
return 0;
|
||||
}
|
||||
memmove (®s.u_regs [1], ®s.u_regs [0],
|
||||
sizeof (regs.u_regs) - sizeof (regs.u_regs [0]));
|
||||
if(entering(tcp)) {
|
||||
tcp->u_arg[0] = 0;
|
||||
i1 = regs.u_regs[UREG_I1];
|
||||
i1 = regs.r_o1;
|
||||
if(umove(tcp, i1, &si) < 0) {
|
||||
perror("sigreturn: umove ");
|
||||
return 0;
|
||||
|
317
strace-graph
Executable file
317
strace-graph
Executable file
@ -0,0 +1,317 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# This script processes strace -f output. It displays a graph of invoked
|
||||
# subprocesses, and is useful for finding out what complex commands do.
|
||||
|
||||
# You will probably want to invoke strace with -q as well, and with
|
||||
# -s 100 to get complete filenames.
|
||||
|
||||
# The script can also handle the output with strace -t, -tt, or -ttt.
|
||||
# It will add elapsed time for each process in that case.
|
||||
|
||||
# This script is Copyright (C) 1998 by Richard Braakman <dark@xs4all.nl>.
|
||||
# It is distributed under the GNU General Public License version 2 or,
|
||||
# at your option, any later version published by the Free Software Foundation.
|
||||
|
||||
my %unfinished;
|
||||
|
||||
# Scales for strace slowdown. Make configurable!
|
||||
my $scale_factor = 3.5;
|
||||
|
||||
while (<>) {
|
||||
my ($pid, $call, $args, $result, $time);
|
||||
chop;
|
||||
|
||||
s/^(\d+)\s+//;
|
||||
$pid = $1;
|
||||
|
||||
if (s/^(\d\d):(\d\d):(\d\d)(?:\.(\d\d\d\d\d\d))? //) {
|
||||
$time = $1 * 3600 + $2 * 60 + $3;
|
||||
if (defined $4) {
|
||||
$time = $time + $4 / 1000000;
|
||||
$floatform = 1;
|
||||
}
|
||||
} elsif (s/^(\d+)\.(\d\d\d\d\d\d) //) {
|
||||
$time = $1 + ($2 / 1000000);
|
||||
$floatform = 1;
|
||||
}
|
||||
|
||||
if (s/ <unfinished ...>$//) {
|
||||
$unfinished{$pid} = $_;
|
||||
next;
|
||||
}
|
||||
|
||||
if (s/^<... \S+ resumed> //) {
|
||||
unless (exists $unfinished{$pid}) {
|
||||
print STDERR "$0: $ARGV: cannot find start of resumed call on line $.";
|
||||
next;
|
||||
}
|
||||
$_ = $unfinished{$pid} . $_;
|
||||
delete $unfinished{$pid};
|
||||
}
|
||||
|
||||
if (/^--- SIG(\S+) \(.*\) ---$/) {
|
||||
# $pid received signal $1
|
||||
# currently we don't do anything with this
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^\+\+\+ killed by SIG(\S+) \+\+\+$/) {
|
||||
# $pid received signal $1
|
||||
handle_killed($pid, $time);
|
||||
next;
|
||||
}
|
||||
|
||||
($call, $args, $result) = /(\S+)\((.*)\)\s+= (.*)$/;
|
||||
unless (defined $result) {
|
||||
print STDERR "$0: $ARGV: $.: cannot parse line.\n";
|
||||
next;
|
||||
}
|
||||
|
||||
handle_trace($pid, $call, $args, $result, $time);
|
||||
}
|
||||
|
||||
display_trace();
|
||||
|
||||
exit 0;
|
||||
|
||||
sub parse_str {
|
||||
my ($in) = @_;
|
||||
my $result = "";
|
||||
|
||||
while (1) {
|
||||
if ($in =~ s/^\\(.)//) {
|
||||
$result .= $1;
|
||||
} elsif ($in =~ s/^\"//) {
|
||||
if ($in =~ s/^\.\.\.//) {
|
||||
return ("$result...", $in);
|
||||
}
|
||||
return ($result, $in);
|
||||
} elsif ($in =~ s/([^\\\"]*)//) {
|
||||
$result .= $1;
|
||||
} else {
|
||||
return (undef, $in);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_one {
|
||||
my ($in) = @_;
|
||||
|
||||
if ($in =~ s/^\"//) {
|
||||
($tmp, $in) = parse_str($in);
|
||||
if (not defined $tmp) {
|
||||
print STDERR "$0: $ARGV: $.: cannot parse string.\n";
|
||||
return (undef, $in);
|
||||
}
|
||||
return ($tmp, $in);
|
||||
} elsif ($in =~ s/^0x(\x+)//) {
|
||||
return (hex $1, $in);
|
||||
} elsif ($in =~ s/^(\d+)//) {
|
||||
return (int $1, $in);
|
||||
} else {
|
||||
print STDERR "$0: $ARGV: $.: unrecognized element.\n";
|
||||
return (undef, $in);
|
||||
}
|
||||
}
|
||||
|
||||
sub parseargs {
|
||||
my ($in) = @_;
|
||||
my @args = ();
|
||||
my $tmp;
|
||||
|
||||
while (length $in) {
|
||||
if ($in =~ s/^\[//) {
|
||||
my @subarr = ();
|
||||
if ($in =~ s,^/\* (\d+) vars \*/\],,) {
|
||||
push @args, $1;
|
||||
} else {
|
||||
while ($in !~ s/^\]//) {
|
||||
($tmp, $in) = parse_one($in);
|
||||
defined $tmp or return undef;
|
||||
push @subarr, $tmp;
|
||||
unless ($in =~ /^\]/ or $in =~ s/^, //) {
|
||||
print STDERR "$0: $ARGV: $.: missing comma in array.\n";
|
||||
return undef;
|
||||
}
|
||||
if ($in =~ s/^\.\.\.//) {
|
||||
push @subarr, "...";
|
||||
}
|
||||
}
|
||||
push @args, \@subarr;
|
||||
}
|
||||
} elsif ($in =~ s/^\{//) {
|
||||
my %subhash = ();
|
||||
while ($in !~ s/^\}//) {
|
||||
my $key;
|
||||
unless ($in =~ s/^(\w+)=//) {
|
||||
print STDERR "$0: $ARGV: $.: struct field expected.\n";
|
||||
return undef;
|
||||
}
|
||||
$key = $1;
|
||||
($tmp, $in) = parse_one($in);
|
||||
defined $tmp or return undef;
|
||||
$subhash{$key} = $tmp;
|
||||
unless ($in =~ s/, //) {
|
||||
print STDERR "$0: $ARGV: $.: missing comma in struct.\n";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
push @args, \%subhash;
|
||||
} else {
|
||||
($tmp, $in) = parse_one($in);
|
||||
defined $tmp or return undef;
|
||||
push @args, $tmp;
|
||||
}
|
||||
unless (length($in) == 0 or $in =~ s/^, //) {
|
||||
print STDERR "$0: $ARGV: $.: missing comma.\n";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
return @args;
|
||||
}
|
||||
|
||||
|
||||
my $depth = "";
|
||||
|
||||
# process info, indexed by pid.
|
||||
# fields:
|
||||
# parent pid number
|
||||
# seq forks and execs for this pid, in sequence (array)
|
||||
|
||||
# filename and argv (from latest exec)
|
||||
# basename (derived from filename)
|
||||
# argv[0] is modified to add the basename if it differs from the 0th argument.
|
||||
|
||||
my %pr;
|
||||
|
||||
sub handle_trace {
|
||||
my ($pid, $call, $args, $result, $time) = @_;
|
||||
my $p;
|
||||
|
||||
if (defined $time and not defined $pr{$pid}{start}) {
|
||||
$pr{$pid}{start} = $time;
|
||||
}
|
||||
|
||||
if ($call eq 'execve') {
|
||||
return if $result != 0;
|
||||
|
||||
my ($filename, $argv) = parseargs($args);
|
||||
($basename) = $filename =~ m/([^\/]*)$/;
|
||||
if ($basename ne $$argv[0]) {
|
||||
$$argv[0] = "$basename($$argv[0])";
|
||||
}
|
||||
my $seq = $pr{$pid}{seq};
|
||||
$seq = [] if not defined $seq;
|
||||
|
||||
push @$seq, ['EXEC', $filename, $argv];
|
||||
|
||||
$pr{$pid}{seq} = $seq;
|
||||
} elsif ($call eq 'fork') {
|
||||
return if $result == 0;
|
||||
|
||||
my $seq = $pr{$pid}{seq};
|
||||
$seq = [] if not defined $seq;
|
||||
push @$seq, ['FORK', $result];
|
||||
$pr{$pid}{seq} = $seq;
|
||||
$pr{$result}{parent} = $pid;
|
||||
} elsif ($call eq '_exit') {
|
||||
$pr{$pid}{end} = $time if defined $time;
|
||||
}
|
||||
}
|
||||
|
||||
sub handle_killed {
|
||||
my ($pid, $time) = @_;
|
||||
$pr{$pid}{end} = $time if defined $time;
|
||||
}
|
||||
|
||||
sub straight_seq {
|
||||
my ($pid) = @_;
|
||||
my $seq = $pr{$pid}{seq};
|
||||
|
||||
for $elem (@$seq) {
|
||||
if ($$elem[0] eq 'EXEC') {
|
||||
my $argv = $$elem[2];
|
||||
print "$$elem[0] $$elem[1] @$argv\n";
|
||||
} elsif ($$elem[0] eq 'FORK') {
|
||||
print "$$elem[0] $$elem[1]\n";
|
||||
} else {
|
||||
print "$$elem[0]\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub first_exec {
|
||||
my ($pid) = @_;
|
||||
my $seq = $pr{$pid}{seq};
|
||||
|
||||
for $elem (@$seq) {
|
||||
if ($$elem[0] eq 'EXEC') {
|
||||
return $elem;
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub display_pid_trace {
|
||||
my ($pid, $lead) = @_;
|
||||
my $i = 0;
|
||||
my @seq = @{$pr{$pid}{seq}};
|
||||
my $elapsed;
|
||||
|
||||
if (not defined first_exec($pid)) {
|
||||
unshift @seq, ['EXEC', '', ['(anon)'] ];
|
||||
}
|
||||
|
||||
if (defined $pr{$pid}{start} and defined $pr{$pid}{end}) {
|
||||
$elapsed = $pr{$pid}{end} - $pr{$pid}{start};
|
||||
$elapsed /= $scale_factor;
|
||||
if ($floatform) {
|
||||
$elapsed = sprintf("%0.02f", $elapsed);
|
||||
} else {
|
||||
$elapsed = int $elapsed;
|
||||
}
|
||||
}
|
||||
|
||||
for $elem (@seq) {
|
||||
$i++;
|
||||
if ($$elem[0] eq 'EXEC') {
|
||||
my $argv = $$elem[2];
|
||||
if (defined $elapsed) {
|
||||
print "$lead [$elapsed] @$argv\n";
|
||||
undef $elapsed;
|
||||
} else {
|
||||
print "$lead @$argv\n";
|
||||
}
|
||||
} elsif ($$elem[0] eq 'FORK') {
|
||||
if ($i == 1) {
|
||||
if ($lead =~ /-$/) {
|
||||
display_pid_trace($$elem[1], "$lead--+--");
|
||||
} else {
|
||||
display_pid_trace($$elem[1], "$lead +--");
|
||||
}
|
||||
} elsif ($i == @seq) {
|
||||
display_pid_trace($$elem[1], "$lead `--");
|
||||
} else {
|
||||
display_pid_trace($$elem[1], "$lead +--");
|
||||
}
|
||||
}
|
||||
if ($i == 1) {
|
||||
$lead =~ s/\`--/ /g;
|
||||
$lead =~ s/-/ /g;
|
||||
$lead =~ s/\+/|/g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub display_trace {
|
||||
my ($startpid) = @_;
|
||||
|
||||
$startpid = (keys %pr)[0];
|
||||
while ($pr{$startpid}{parent}) {
|
||||
$startpid = $pr{$startpid}{parent};
|
||||
}
|
||||
|
||||
display_pid_trace($startpid, "");
|
||||
}
|
||||
|
174
strace.c
174
strace.c
@ -45,6 +45,9 @@
|
||||
#ifdef SVR4
|
||||
#include <sys/stropts.h>
|
||||
#include <poll.h>
|
||||
#ifdef SVR4_MP
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int debug = 0, followfork = 0, followvfork = 0, interactive = 0;
|
||||
@ -105,6 +108,11 @@ static int proc_poll_pipe[2] = { -1, -1 };
|
||||
|
||||
#endif /* !HAVE_POLLABLE_PROCFS */
|
||||
|
||||
#ifdef SVR4_MP
|
||||
#define POLLWANT POLLWRNORM
|
||||
#else
|
||||
#define POLLWANT POLLPRI
|
||||
#endif
|
||||
#endif /* SVR4 */
|
||||
|
||||
static void
|
||||
@ -559,7 +567,6 @@ int pid;
|
||||
}
|
||||
|
||||
#ifdef SVR4
|
||||
|
||||
int
|
||||
proc_open(tcp, attaching)
|
||||
struct tcb *tcp;
|
||||
@ -570,39 +577,17 @@ int attaching;
|
||||
sysset_t sc_enter, sc_exit;
|
||||
sigset_t signals;
|
||||
fltset_t faults;
|
||||
#ifndef MIPS
|
||||
prrun_t run;
|
||||
#endif
|
||||
#ifndef HAVE_POLLABLE_PROCFS
|
||||
static int last_pfd;
|
||||
#endif
|
||||
|
||||
/* Open the process pseudo-file in /proc. */
|
||||
sprintf(proc, "/proc/%d", tcp->pid);
|
||||
if ((tcp->pfd = open(proc, O_RDWR|O_EXCL)) < 0) {
|
||||
#ifdef SVR4_MP
|
||||
/* Open the process pseudo-files in /proc. */
|
||||
sprintf(proc, "/proc/%d/ctl", tcp->pid);
|
||||
if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) {
|
||||
perror("strace: open(\"/proc/...\", ...)");
|
||||
return -1;
|
||||
}
|
||||
rebuild_pollv();
|
||||
if (!attaching) {
|
||||
/*
|
||||
* Wait for the child to pause. Because of a race
|
||||
* condition we have to poll for the event.
|
||||
*/
|
||||
for (;;) {
|
||||
if (ioctl(tcp->pfd, PIOCSTATUS, &tcp->status) < 0) {
|
||||
perror("strace: PIOCSTATUS");
|
||||
return -1;
|
||||
}
|
||||
if (tcp->status.pr_flags & PR_ASLEEP)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Stop the process so that we own the stop. */
|
||||
if (ioctl(tcp->pfd, PIOCSTOP, &tcp->status) < 0) {
|
||||
perror("strace: PIOCSTOP");
|
||||
return -1;
|
||||
}
|
||||
if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) {
|
||||
perror("F_GETFD");
|
||||
return -1;
|
||||
@ -611,16 +596,78 @@ int attaching;
|
||||
perror("F_SETFD");
|
||||
return -1;
|
||||
}
|
||||
sprintf(proc, "/proc/%d/status", tcp->pid);
|
||||
if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) {
|
||||
perror("strace: open(\"/proc/...\", ...)");
|
||||
return -1;
|
||||
}
|
||||
if ((arg = fcntl(tcp->pfd_stat, F_GETFD)) < 0) {
|
||||
perror("F_GETFD");
|
||||
return -1;
|
||||
}
|
||||
if (fcntl(tcp->pfd_stat, F_SETFD, arg|FD_CLOEXEC) < 0) {
|
||||
perror("F_SETFD");
|
||||
return -1;
|
||||
}
|
||||
sprintf(proc, "/proc/%d/as", tcp->pid);
|
||||
if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) {
|
||||
perror("strace: open(\"/proc/...\", ...)");
|
||||
return -1;
|
||||
}
|
||||
if ((arg = fcntl(tcp->pfd_as, F_GETFD)) < 0) {
|
||||
perror("F_GETFD");
|
||||
return -1;
|
||||
}
|
||||
if (fcntl(tcp->pfd_as, F_SETFD, arg|FD_CLOEXEC) < 0) {
|
||||
perror("F_SETFD");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
/* Open the process pseudo-file in /proc. */
|
||||
sprintf(proc, "/proc/%d", tcp->pid);
|
||||
if ((tcp->pfd = open(proc, O_RDWR|O_EXCL)) < 0) {
|
||||
perror("strace: open(\"/proc/...\", ...)");
|
||||
return -1;
|
||||
}
|
||||
if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) {
|
||||
perror("F_GETFD");
|
||||
return -1;
|
||||
}
|
||||
if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) {
|
||||
perror("F_SETFD");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
rebuild_pollv();
|
||||
if (!attaching) {
|
||||
/*
|
||||
* Wait for the child to pause. Because of a race
|
||||
* condition we have to poll for the event.
|
||||
*/
|
||||
for (;;) {
|
||||
if (IOCTL_STATUS (tcp) < 0) {
|
||||
perror("strace: PIOCSTATUS");
|
||||
return -1;
|
||||
}
|
||||
if (tcp->status.PR_FLAGS & PR_ASLEEP)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Stop the process so that we own the stop. */
|
||||
if (IOCTL(tcp->pfd, PIOCSTOP, NULL) < 0) {
|
||||
perror("strace: PIOCSTOP");
|
||||
return -1;
|
||||
}
|
||||
#ifdef PIOCSET
|
||||
/* Set Run-on-Last-Close. */
|
||||
arg = PR_RLC;
|
||||
if (ioctl(tcp->pfd, PIOCSET, &arg) < 0) {
|
||||
if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) {
|
||||
perror("PIOCSET PR_RLC");
|
||||
return -1;
|
||||
}
|
||||
/* Set or Reset Inherit-on-Fork. */
|
||||
arg = PR_FORK;
|
||||
if (ioctl(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) {
|
||||
if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) {
|
||||
perror("PIOC{SET,RESET} PR_FORK");
|
||||
return -1;
|
||||
}
|
||||
@ -636,25 +683,25 @@ int attaching;
|
||||
#endif /* !PIOCSET */
|
||||
/* Enable all syscall entries. */
|
||||
prfillset(&sc_enter);
|
||||
if (ioctl(tcp->pfd, PIOCSENTRY, &sc_enter) < 0) {
|
||||
if (IOCTL(tcp->pfd, PIOCSENTRY, &sc_enter) < 0) {
|
||||
perror("PIOCSENTRY");
|
||||
return -1;
|
||||
}
|
||||
/* Enable all syscall exits. */
|
||||
prfillset(&sc_exit);
|
||||
if (ioctl(tcp->pfd, PIOCSEXIT, &sc_exit) < 0) {
|
||||
if (IOCTL(tcp->pfd, PIOCSEXIT, &sc_exit) < 0) {
|
||||
perror("PIOSEXIT");
|
||||
return -1;
|
||||
}
|
||||
/* Enable all signals. */
|
||||
prfillset(&signals);
|
||||
if (ioctl(tcp->pfd, PIOCSTRACE, &signals) < 0) {
|
||||
if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) {
|
||||
perror("PIOCSTRACE");
|
||||
return -1;
|
||||
}
|
||||
/* Enable all faults. */
|
||||
prfillset(&faults);
|
||||
if (ioctl(tcp->pfd, PIOCSFAULT, &faults) < 0) {
|
||||
if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) {
|
||||
perror("PIOCSFAULT");
|
||||
return -1;
|
||||
}
|
||||
@ -667,29 +714,30 @@ int attaching;
|
||||
kill(tcp->pid, SIGINT);
|
||||
#else /* !MIPS */
|
||||
/* The child is in a pause(), abort it. */
|
||||
run.pr_flags = PRSABORT;
|
||||
if (ioctl(tcp->pfd, PIOCRUN, &run) < 0) {
|
||||
arg = PRSABORT;
|
||||
if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
|
||||
perror("PIOCRUN");
|
||||
return -1;
|
||||
}
|
||||
#endif /* !MIPS */
|
||||
for (;;) {
|
||||
/* Wait for the child to do something. */
|
||||
if (ioctl(tcp->pfd, PIOCWSTOP, &tcp->status) < 0) {
|
||||
if (IOCTL_WSTOP (tcp) < 0) {
|
||||
perror("PIOCWSTOP");
|
||||
return -1;
|
||||
}
|
||||
if (tcp->status.pr_why == PR_SYSENTRY) {
|
||||
if (tcp->status.PR_WHY == PR_SYSENTRY) {
|
||||
#ifdef HAVE_PR_SYSCALL
|
||||
int scno = tcp->status.pr_syscall;
|
||||
#else /* !HAVE_PR_SYSCALL */
|
||||
int scno = tcp->status.pr_what;
|
||||
int scno = tcp->status.PR_WHAT;
|
||||
#endif /* !HAVE_PR_SYSCALL */
|
||||
if (scno == SYS_execve)
|
||||
break;
|
||||
}
|
||||
/* Set it running: maybe execve will be next. */
|
||||
if (ioctl(tcp->pfd, PIOCRUN, NULL) < 0) {
|
||||
arg = 0;
|
||||
if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) {
|
||||
perror("PIOCRUN");
|
||||
return -1;
|
||||
}
|
||||
@ -1012,7 +1060,7 @@ rebuild_pollv()
|
||||
if (!(tcp->flags & TCB_INUSE))
|
||||
continue;
|
||||
pollv[j].fd = tcp->pfd;
|
||||
pollv[j].events = POLLPRI;
|
||||
pollv[j].events = POLLWANT;
|
||||
j++;
|
||||
}
|
||||
if (j != nprocs) {
|
||||
@ -1126,7 +1174,8 @@ int pfd;
|
||||
pollinfo.fd = pfd;
|
||||
pollinfo.pid = getpid();
|
||||
for (;;) {
|
||||
if (ioctl(pfd, PIOCWSTOP, NULL) < 0) {
|
||||
if (ioctl(pfd, PIOCWSTOP, NULL) < 0)
|
||||
{
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
continue;
|
||||
@ -1142,7 +1191,7 @@ int pfd;
|
||||
write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
|
||||
_exit(0);
|
||||
}
|
||||
pollinfo.revents = POLLPRI;
|
||||
pollinfo.revents = POLLWANT;
|
||||
write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
|
||||
sigsuspend(&empty_set);
|
||||
}
|
||||
@ -1159,7 +1208,7 @@ choose_pfd()
|
||||
static int last;
|
||||
|
||||
if (followfork < 2 &&
|
||||
last < nprocs && (pollv[last].revents & POLLPRI)) {
|
||||
last < nprocs && (pollv[last].revents & POLLWANT)) {
|
||||
/*
|
||||
* The previous process is ready to run again. We'll
|
||||
* let it do so if it is currently in a syscall. This
|
||||
@ -1182,7 +1231,7 @@ choose_pfd()
|
||||
droptcb(tcp);
|
||||
return -1;
|
||||
}
|
||||
if (pollv[j].revents & POLLPRI) {
|
||||
if (pollv[j].revents & POLLWANT) {
|
||||
last = j;
|
||||
return pollv[j].fd;
|
||||
}
|
||||
@ -1198,6 +1247,7 @@ trace()
|
||||
int pfd;
|
||||
int what;
|
||||
int ioctl_result = 0, ioctl_errno = 0;
|
||||
long arg;
|
||||
|
||||
for (;;) {
|
||||
if (interactive)
|
||||
@ -1249,8 +1299,7 @@ trace()
|
||||
}
|
||||
/* Get the status of the process. */
|
||||
if (!interrupted) {
|
||||
ioctl_result = ioctl(tcp->pfd, PIOCWSTOP,
|
||||
&tcp->status);
|
||||
ioctl_result = IOCTL_WSTOP (tcp);
|
||||
ioctl_errno = errno;
|
||||
#ifndef HAVE_POLLABLE_PROCFS
|
||||
if (proc_poll_pipe[0] != -1) {
|
||||
@ -1297,11 +1346,11 @@ trace()
|
||||
tcp->stime = stime;
|
||||
}
|
||||
|
||||
what = tcp->status.pr_what;
|
||||
switch (tcp->status.pr_why) {
|
||||
what = tcp->status.PR_WHAT;
|
||||
switch (tcp->status.PR_WHY) {
|
||||
case PR_REQUESTED:
|
||||
if (tcp->status.pr_flags & PR_ASLEEP) {
|
||||
tcp->status.pr_why = PR_SYSENTRY;
|
||||
if (tcp->status.PR_FLAGS & PR_ASLEEP) {
|
||||
tcp->status.PR_WHY = PR_SYSENTRY;
|
||||
if (trace_syscall(tcp) < 0) {
|
||||
fprintf(stderr, "syscall trouble\n");
|
||||
exit(1);
|
||||
@ -1331,11 +1380,12 @@ trace()
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "odd stop %d\n", tcp->status.pr_why);
|
||||
fprintf(stderr, "odd stop %d\n", tcp->status.PR_WHY);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
if (ioctl(tcp->pfd, PIOCRUN, NULL) < 0) {
|
||||
arg = 0;
|
||||
if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
|
||||
perror("PIOCRUN");
|
||||
exit(1);
|
||||
}
|
||||
@ -1656,3 +1706,23 @@ struct tcb *tcp;
|
||||
tprintf("\n");
|
||||
tcp_last = NULL;
|
||||
}
|
||||
|
||||
#ifdef SVR4_MP
|
||||
|
||||
int mp_ioctl (int fd, int cmd, void *arg, int size) {
|
||||
|
||||
struct iovec iov[2];
|
||||
int n = 1;
|
||||
|
||||
iov[0].iov_base = &cmd;
|
||||
iov[0].iov_len = sizeof cmd;
|
||||
if (arg) {
|
||||
++n;
|
||||
iov[1].iov_base = arg;
|
||||
iov[1].iov_len = size;
|
||||
}
|
||||
|
||||
return writev (fd, iov, n);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -221,7 +221,7 @@
|
||||
{ -1, 0, sys_swapctl, "swapctl" }, /* 167 */
|
||||
{ -1, 0, sys_getcontext, "getcontext" }, /* 168 */
|
||||
{ -1, 0, sys_setcontext, "setcontext" }, /* 169 */
|
||||
{ -1, TP, sys_waitsys, "waitid" }, /* 170 */
|
||||
{ -1, TP, sys_waitid, "waitid" }, /* 170 */
|
||||
{ -1, TS, sys_sigstack, "sigstack" }, /* 171 */
|
||||
{ -1, TS, sys_sigaltstack, "sigaltstack" }, /* 172 */
|
||||
{ -1, TS, sys_sigsendset, "sigsendset" }, /* 173 */
|
||||
@ -322,7 +322,11 @@
|
||||
{ -1, 0, sys_fstatvfs, "fstatvfs" }, /* 104 */
|
||||
{ -1, 0, printargs, "SYS_105" }, /* 105 */
|
||||
{ -1, 0, sys_nfssys, "nfssys" }, /* 106 */
|
||||
#if UNIXWARE
|
||||
{ -1, TP, sys_waitsys, "waitsys" }, /* 107 */
|
||||
#else
|
||||
{ -1, TP, sys_waitid, "waitid" }, /* 107 */
|
||||
#endif
|
||||
{ -1, 0, sys_sigsendsys, "sigsendsys" }, /* 108 */
|
||||
{ -1, 0, sys_hrtsys, "hrtsys" }, /* 109 */
|
||||
{ -1, 0, sys_acancel, "acancel" }, /* 110 */
|
||||
@ -356,6 +360,77 @@
|
||||
{ -1, 0, sys_adjtime, "adjtime" }, /* 138 */
|
||||
{ -1, 0, sys_sysinfo, "sysinfo" }, /* 139 */
|
||||
{ -1, 0, printargs, "SYS_140" }, /* 140 */
|
||||
#if UNIXWARE >= 2
|
||||
{ -1, 0, sys_seteuid, "seteuid" }, /* 141 */
|
||||
{ -1, 0, printargs, "SYS_142" }, /* 142 */
|
||||
{ -1, 0, printargs, "keyctl" }, /* 143 */
|
||||
{ -1, 0, printargs, "secsys" }, /* 144 */
|
||||
{ -1, 0, printargs, "filepriv" }, /* 145 */
|
||||
{ -1, 0, printargs, "procpriv" }, /* 146 */
|
||||
{ -1, 0, printargs, "devstat" }, /* 147 */
|
||||
{ -1, 0, printargs, "aclipc" }, /* 148 */
|
||||
{ -1, 0, printargs, "fdevstat" }, /* 149 */
|
||||
{ -1, 0, printargs, "flvlfile" }, /* 150 */
|
||||
{ -1, 0, printargs, "lvlfile" }, /* 151 */
|
||||
{ -1, 0, printargs, "SYS_152" }, /* 152 */
|
||||
{ -1, 0, printargs, "lvlequal" }, /* 153 */
|
||||
{ -1, 0, printargs, "lvlproc" }, /* 154 */
|
||||
{ -1, 0, printargs, "SYS_155" }, /* 155 */
|
||||
{ -1, 0, printargs, "lvlipc" }, /* 156 */
|
||||
{ -1, 0, printargs, "acl" }, /* 157 */
|
||||
{ -1, 0, printargs, "auditevt" }, /* 158 */
|
||||
{ -1, 0, printargs, "auditctl" }, /* 159 */
|
||||
{ -1, 0, printargs, "auditdmp" }, /* 160 */
|
||||
{ -1, 0, printargs, "auditlog" }, /* 161 */
|
||||
{ -1, 0, printargs, "auditbuf" }, /* 162 */
|
||||
{ -1, 0, printargs, "lvldom" }, /* 163 */
|
||||
{ -1, 0, printargs, "lvlvfs" }, /* 164 */
|
||||
{ -1, 0, printargs, "mkmld" }, /* 165 */
|
||||
{ -1, 0, printargs, "mldmode" }, /* 166 */
|
||||
{ -1, 0, printargs, "secadvise" }, /* 167 */
|
||||
{ -1, 0, printargs, "online" }, /* 168 */
|
||||
{ -1, 0, sys_setitimer, "setitimer" }, /* 169 */
|
||||
{ -1, 0, sys_getitimer, "getitimer" }, /* 170 */
|
||||
{ -1, 0, sys_gettimeofday, "gettimeofday" }, /* 171 */
|
||||
{ -1, 0, printargs, "settimeofday" }, /* 172 */
|
||||
{ -1, 0, sys_lwp_create, "lwpcreate" }, /* 173 */
|
||||
{ -1, 0, sys_lwp_exit, "lwpexit" }, /* 174 */
|
||||
{ -1, 0, sys_lwp_wait, "lwpwait" }, /* 175 */
|
||||
{ -1, 0, sys_lwp_self, "lwpself" }, /* 176 */
|
||||
{ -1, 0, printargs, "lwpinfo" }, /* 177 */
|
||||
{ -1, 0, printargs, "lwpprivate" }, /* 178 */
|
||||
{ -1, 0, sys_processor_bind, "processor_bind"}, /* 179 */
|
||||
{ -1, 0, printargs, "processor_exbind"}, /* 180 */
|
||||
{ -1, 0, printargs, "SYS_181" }, /* 181 */
|
||||
{ -1, 0, printargs, "SYS_182" }, /* 182 */
|
||||
{ -1, 0, printargs, "prepblock" }, /* 183 */
|
||||
{ -1, 0, printargs, "block" }, /* 184 */
|
||||
{ -1, 0, printargs, "rdblock" }, /* 185 */
|
||||
{ -1, 0, printargs, "unblock" }, /* 186 */
|
||||
{ -1, 0, printargs, "cancelblock" }, /* 187 */
|
||||
{ -1, 0, printargs, "SYS_188" }, /* 188 */
|
||||
{ -1, 0, sys_pread, "pread" }, /* 189 */
|
||||
{ -1, 0, sys_pwrite, "pwrite" }, /* 190 */
|
||||
{ -1, 0, printargs, "truncate" }, /* 191 */
|
||||
{ -1, 0, printargs, "ftruncate" }, /* 192 */
|
||||
{ -1, 0, printargs, "lwpkill" }, /* 193 */
|
||||
{ -1, 0, printargs, "sigwait" }, /* 194 */
|
||||
{ -1, 0, printargs, "fork1" }, /* 195 */
|
||||
{ -1, 0, printargs, "forkall" }, /* 196 */
|
||||
{ -1, 0, printargs, "modload" }, /* 197 */
|
||||
{ -1, 0, printargs, "moduload" }, /* 198 */
|
||||
{ -1, 0, printargs, "modpath" }, /* 199 */
|
||||
{ -1, 0, printargs, "modstat" }, /* 200 */
|
||||
{ -1, 0, printargs, "modadm" }, /* 201 */
|
||||
{ -1, 0, printargs, "getksym" }, /* 202 */
|
||||
{ -1, 0, printargs, "lwpsuspend" }, /* 203 */
|
||||
{ -1, 0, printargs, "lwpcontinue" }, /* 204 */
|
||||
{ -1, 0, printargs, "priocntllst" }, /* 205 */
|
||||
{ -1, 0, printargs, "sleep" }, /* 206 */
|
||||
{ -1, 0, printargs, "lwp_sema_wait" }, /* 207 */
|
||||
{ -1, 0, printargs, "lwp_sema_post" }, /* 208 */
|
||||
{ -1, 0, printargs, "lwp_sema_trywait"}, /* 209 */
|
||||
#else
|
||||
{ -1, 0, sys_seteuid, "seteuid" }, /* 141 */
|
||||
{ -1, 0, sys_vtrace, "vtrace" }, /* 142 */
|
||||
{ -1, TP, sys_fork1, "fork1" }, /* 143 */
|
||||
@ -437,6 +512,7 @@
|
||||
{ -1, 0, printargs, "SYS_207" }, /* 207 */
|
||||
{ -1, 0, printargs, "SYS_208" }, /* 208 */
|
||||
{ -1, 0, printargs, "SYS_209" }, /* 209 */
|
||||
#endif
|
||||
{ -1, 0, printargs, "SYS_210" }, /* 210 */
|
||||
{ -1, 0, printargs, "SYS_211" }, /* 211 */
|
||||
{ -1, 0, printargs, "SYS_212" }, /* 212 */
|
||||
|
62
syscall.c
62
syscall.c
@ -38,6 +38,10 @@
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#if defined(LINUX) && defined(SPARC)
|
||||
#include <asm/reg.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_REG_H
|
||||
#include <sys/reg.h>
|
||||
# define PTRACE_PEEKUSR PTRACE_PEEKUSER
|
||||
@ -579,7 +583,7 @@ struct tcb *tcp;
|
||||
long r0;
|
||||
long a3;
|
||||
#elif defined (SPARC)
|
||||
struct pt_regs regs;
|
||||
struct regs regs;
|
||||
unsigned long trap;
|
||||
#endif
|
||||
#endif /* LINUX */
|
||||
@ -650,14 +654,11 @@ struct tcb *tcp;
|
||||
if (ptrace(PTRACE_GETREGS,pid,(char *)®s,0) < 0)
|
||||
return -1;
|
||||
|
||||
memmove (®s.u_regs [1], ®s.u_regs [0],
|
||||
sizeof (regs.u_regs) - sizeof (regs.u_regs [0]));
|
||||
|
||||
/* If we are entering, then disassemble the syscall trap. */
|
||||
if (!(tcp->flags & TCB_INSYSCALL)) {
|
||||
/* Retrieve the syscall trap instruction. */
|
||||
errno = 0;
|
||||
trap = ptrace(PTRACE_PEEKTEXT,pid,(char *)regs.pc,0);
|
||||
trap = ptrace(PTRACE_PEEKTEXT,pid,(char *)regs.r_pc,0);
|
||||
if (errno)
|
||||
return -1;
|
||||
|
||||
@ -693,7 +694,7 @@ struct tcb *tcp;
|
||||
tcp->flags &= ~TCB_WAITEXECVE;
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.pc);
|
||||
fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.r_pc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -701,10 +702,10 @@ struct tcb *tcp;
|
||||
if (trap == 0x91d02027)
|
||||
scno = 156;
|
||||
else
|
||||
scno = regs.u_regs[UREG_G1];
|
||||
scno = regs.r_g1;
|
||||
if (scno == 0) {
|
||||
scno = regs.u_regs[UREG_I0];
|
||||
memmove (®s.u_regs[UREG_I0], ®s.u_regs[UREG_I1], 7*sizeof(regs.u_regs[0]));
|
||||
scno = regs.r_o0;
|
||||
memmove (®s.r_o0, ®s.r_o1, 7*sizeof(regs.r_o0));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -717,10 +718,10 @@ struct tcb *tcp;
|
||||
#ifdef HAVE_PR_SYSCALL
|
||||
scno = tcp->status.pr_syscall;
|
||||
#else /* !HAVE_PR_SYSCALL */
|
||||
scno = tcp->status.pr_what;
|
||||
scno = tcp->status.PR_WHAT;
|
||||
#endif /* !HAVE_PR_SYSCALL */
|
||||
if (!(tcp->flags & TCB_INSYSCALL)) {
|
||||
if (tcp->status.pr_why != PR_SYSENTRY) {
|
||||
if (tcp->status.PR_WHY != PR_SYSENTRY) {
|
||||
if (
|
||||
scno == SYS_fork
|
||||
#ifdef SYS_vfork
|
||||
@ -728,9 +729,9 @@ struct tcb *tcp;
|
||||
#endif /* SYS_vfork */
|
||||
) {
|
||||
/* We are returning in the child, fake it. */
|
||||
tcp->status.pr_why = PR_SYSENTRY;
|
||||
tcp->status.PR_WHY = PR_SYSENTRY;
|
||||
trace_syscall(tcp);
|
||||
tcp->status.pr_why = PR_SYSEXIT;
|
||||
tcp->status.PR_WHY = PR_SYSEXIT;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "syscall: missing entry\n");
|
||||
@ -739,7 +740,7 @@ struct tcb *tcp;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tcp->status.pr_why != PR_SYSEXIT) {
|
||||
if (tcp->status.PR_WHY != PR_SYSEXIT) {
|
||||
fprintf(stderr, "syscall: missing exit\n");
|
||||
tcp->flags &= ~TCB_INSYSCALL;
|
||||
}
|
||||
@ -858,12 +859,12 @@ struct tcb *tcp;
|
||||
}
|
||||
#else /* !ALPHA */
|
||||
#ifdef SPARC
|
||||
if (regs.psr & PSR_C) {
|
||||
if (regs.r_psr & PSR_C) {
|
||||
tcp->u_rval = -1;
|
||||
u_error = regs.u_regs[UREG_I0];
|
||||
u_error = regs.r_o0;
|
||||
}
|
||||
else {
|
||||
tcp->u_rval = regs.u_regs[UREG_I0];
|
||||
tcp->u_rval = regs.r_o0;
|
||||
u_error = 0;
|
||||
}
|
||||
#endif /* SPARC */
|
||||
@ -897,12 +898,12 @@ struct tcb *tcp;
|
||||
#endif /* SPARC */
|
||||
#ifdef I386
|
||||
/* Wanna know how to kill an hour single-stepping? */
|
||||
if (tcp->status.pr_reg[EFL] & 0x1) {
|
||||
if (tcp->status.PR_REG[EFL] & 0x1) {
|
||||
tcp->u_rval = -1;
|
||||
u_error = tcp->status.pr_reg[EAX];
|
||||
u_error = tcp->status.PR_REG[EAX];
|
||||
}
|
||||
else {
|
||||
tcp->u_rval = tcp->status.pr_reg[EAX];
|
||||
tcp->u_rval = tcp->status.PR_REG[EAX];
|
||||
u_error = 0;
|
||||
}
|
||||
#endif /* I386 */
|
||||
@ -1074,12 +1075,11 @@ struct tcb *tcp;
|
||||
}
|
||||
#elif defined (SPARC)
|
||||
{
|
||||
int i, offset;
|
||||
int i;
|
||||
|
||||
offset = UREG_I0;
|
||||
tcp->u_nargs = sysent[tcp->scno].nargs;
|
||||
for (i = 0; i < tcp->u_nargs; i++)
|
||||
tcp->u_arg[i] = regs.u_regs[offset + i];
|
||||
tcp->u_arg[i] = *((®s.r_o0) + i);
|
||||
}
|
||||
#else
|
||||
{
|
||||
@ -1141,8 +1141,12 @@ struct tcb *tcp;
|
||||
if (sysent[tcp->scno].nargs != -1)
|
||||
tcp->u_nargs = sysent[tcp->scno].nargs;
|
||||
else
|
||||
#if UNIXWARE >= 2
|
||||
tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
|
||||
#else
|
||||
tcp->u_nargs = 5;
|
||||
umoven(tcp, tcp->status.pr_reg[UESP] + 4,
|
||||
#endif
|
||||
umoven(tcp, tcp->status.PR_REG[UESP] + 4,
|
||||
tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
|
||||
#endif /* I386 */
|
||||
#endif /* !HAVE_PR_SYSCALL */
|
||||
@ -1292,10 +1296,10 @@ struct tcb *tcp;
|
||||
|
||||
#ifdef LINUX
|
||||
#ifdef SPARC
|
||||
struct pt_regs regs;
|
||||
struct regs regs;
|
||||
if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
|
||||
return -1;
|
||||
val = regs.u_regs[UREG_I1];
|
||||
val = regs.r_o1;
|
||||
#endif /* SPARC */
|
||||
#endif /* LINUX */
|
||||
|
||||
@ -1306,13 +1310,13 @@ struct tcb *tcp;
|
||||
|
||||
#ifdef SVR4
|
||||
#ifdef SPARC
|
||||
val = tcp->status.pr_reg[R_O1];
|
||||
val = tcp->status.PR_REG[R_O1];
|
||||
#endif /* SPARC */
|
||||
#ifdef I386
|
||||
val = tcp->status.pr_reg[EDX];
|
||||
val = tcp->status.PR_REG[EDX];
|
||||
#endif /* I386 */
|
||||
#ifdef MIPS
|
||||
val = tcp->status.pr_reg[CTX_V1];
|
||||
val = tcp->status.PR_REG[CTX_V1];
|
||||
#endif /* MIPS */
|
||||
#endif /* SVR4 */
|
||||
|
||||
|
15
system.c
15
system.c
@ -1279,11 +1279,19 @@ static struct xlat sysctl_kern[] = {
|
||||
{ KERN_PROF, "KERN_PROF" },
|
||||
{ KERN_NODENAME, "KERN_NODENAME" },
|
||||
{ KERN_DOMAINNAME, "KERN_DOMAINNAME" },
|
||||
#ifdef KERN_SECURELVL
|
||||
{ KERN_SECURELVL, "KERN_SECURELVL" },
|
||||
#endif
|
||||
{ KERN_PANIC, "KERN_PANIC" },
|
||||
#ifdef KERN_REALROOTDEV
|
||||
{ KERN_REALROOTDEV, "KERN_REALROOTDEV" },
|
||||
#endif
|
||||
#ifdef KERN_JAVA_INTERPRETER
|
||||
{ KERN_JAVA_INTERPRETER, "KERN_JAVA_INTERPRETER" },
|
||||
#endif
|
||||
#ifdef KERN_JAVA_APPLETVIEWER
|
||||
{ KERN_JAVA_APPLETVIEWER, "KERN_JAVA_APPLETVIEWER" },
|
||||
#endif
|
||||
{ KERN_SPARC_REBOOT, "KERN_SPARC_REBOOT" },
|
||||
{ KERN_CTLALTDEL, "KERN_CTLALTDEL" },
|
||||
{ KERN_PRINTK, "KERN_PRINTK" },
|
||||
@ -1562,8 +1570,13 @@ struct tcb *tcp;
|
||||
&& ((name[0] == CTL_KERN
|
||||
&& (name[1] == KERN_OSRELEASE
|
||||
|| name[1] == KERN_OSTYPE
|
||||
#ifdef KERN_JAVA_INTERPRETER
|
||||
|| name[1] == KERN_JAVA_INTERPRETER
|
||||
|| name[1] == KERN_JAVA_APPLETVIEWER)))) {
|
||||
#endif
|
||||
#ifdef KERN_JAVA_APPLETVIEWER
|
||||
|| name[1] == KERN_JAVA_APPLETVIEWER
|
||||
#endif
|
||||
)))) {
|
||||
printpath(tcp, (size_t)info.oldval);
|
||||
tprintf(", %d, ", oldlen);
|
||||
if (info.newval == 0)
|
||||
|
27
util.c
27
util.c
@ -57,7 +57,11 @@
|
||||
#include <sys/utsname.h>
|
||||
#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
|
||||
|
||||
#if defined(LINUX) && defined(SPARC) && !defined(__GLIBC__)
|
||||
#if defined(LINUX) && defined(SPARC)
|
||||
|
||||
#include <asm/reg.h>
|
||||
|
||||
#if !defined(__GLIBC__)
|
||||
|
||||
#include <linux/unistd.h>
|
||||
|
||||
@ -95,6 +99,8 @@ static _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* macros */
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
@ -618,6 +624,10 @@ char *laddr;
|
||||
#endif /* SUNOS4 */
|
||||
|
||||
#ifdef SVR4
|
||||
#ifdef SVR4_MP
|
||||
if (pread(tcp->pfd_as, laddr, len, addr) == -1)
|
||||
return -1;
|
||||
#else
|
||||
/*
|
||||
* We would like to use pread preferentially for speed
|
||||
* but even though SGI has it in their library, it no longer works.
|
||||
@ -633,6 +643,7 @@ char *laddr;
|
||||
if (read(tcp->pfd, laddr, len) == -1)
|
||||
return -1;
|
||||
#endif /* !HAVE_PREAD */
|
||||
#endif /* SVR4_MP */
|
||||
#endif /* SVR4 */
|
||||
|
||||
return 0;
|
||||
@ -878,10 +889,10 @@ struct tcb *tcp;
|
||||
return -1;
|
||||
#else /* !ALPHA */
|
||||
#ifdef SPARC
|
||||
struct pt_regs regs;
|
||||
struct regs regs;
|
||||
if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
|
||||
return -1;
|
||||
pc = regs.pc;
|
||||
pc = regs.r_pc;
|
||||
#endif /* SPARC */
|
||||
#endif /* ALPHA */
|
||||
#endif /* !M68K */
|
||||
@ -955,12 +966,12 @@ struct tcb *tcp;
|
||||
tprintf("[%08lx] ", pc);
|
||||
#else /* !ALPHA */
|
||||
#ifdef SPARC
|
||||
struct pt_regs regs;
|
||||
struct regs regs;
|
||||
if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) {
|
||||
tprintf("[????????] ");
|
||||
return;
|
||||
}
|
||||
tprintf("[%08lx] ", regs.pc);
|
||||
tprintf("[%08lx] ", regs.r_pc);
|
||||
#endif /* SPARC */
|
||||
#endif /* ALPHA */
|
||||
#endif /* !M68K */
|
||||
@ -997,7 +1008,7 @@ struct tcb *tcp;
|
||||
#ifdef SPARC
|
||||
/* We simply use the SunOS breakpoint code. */
|
||||
|
||||
struct pt_regs regs;
|
||||
struct regs regs;
|
||||
#define LOOPA 0x30800000 /* ba,a 0 */
|
||||
|
||||
if (tcp->flags & TCB_BPTSET) {
|
||||
@ -1008,9 +1019,7 @@ struct tcb *tcp;
|
||||
perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
|
||||
return -1;
|
||||
}
|
||||
memmove (®s.u_regs [1], ®s.u_regs [0],
|
||||
sizeof (regs.u_regs) - sizeof (regs.u_regs [0]));
|
||||
tcp->baddr = regs.u_regs[UREG_I7] + 8;
|
||||
tcp->baddr = regs.r_o7 + 8;
|
||||
errno = 0;
|
||||
tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
|
||||
if(errno) {
|
||||
|
Loading…
Reference in New Issue
Block a user