2015-12-17 20:56:48 +03:00
/*
* Copyright ( c ) 1991 , 1992 Paul Kranenburg < pk @ cs . few . eur . nl >
* Copyright ( c ) 1993 Branko Lankester < branko @ hacktic . nl >
* Copyright ( c ) 1993 - 1996 Rick Sladkey < jrs @ world . std . com >
* Copyright ( c ) 1996 - 1999 Wichert Akkerman < wichert @ cistron . nl >
* Copyright ( c ) 2002 - 2004 Roland McGrath < roland @ redhat . com >
* Copyright ( c ) 2004 Ulrich Drepper < drepper @ redhat . com >
* Copyright ( c ) 2009 - 2013 Denys Vlasenko < dvlasenk @ redhat . com >
* Copyright ( c ) 2014 - 2015 Dmitry V . Levin < ldv @ altlinux . org >
2018-02-14 01:00:00 +03:00
* Copyright ( c ) 2014 - 2018 The strace developers .
2015-12-17 20:56:48 +03:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2014-12-11 22:25:02 +03:00
# include "defs.h"
2018-02-11 03:26:09 +03:00
# include "ptrace.h"
2014-12-11 22:25:02 +03:00
# include <sys/wait.h>
# include "xlat/wait4_options.h"
# if !defined WCOREFLAG && defined WCOREFLG
# define WCOREFLAG WCOREFLG
# endif
# ifndef WCOREFLAG
# define WCOREFLAG 0x80
# endif
# ifndef WCOREDUMP
# define WCOREDUMP(status) ((status) & 0200)
# endif
# ifndef W_STOPCODE
# define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
# endif
# ifndef W_EXITCODE
# define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
# endif
2015-02-13 01:43:02 +03:00
# ifndef W_CONTINUED
# define W_CONTINUED 0xffff
# endif
# include "xlat/ptrace_events.h"
2014-12-11 22:25:02 +03:00
static int
printstatus ( int status )
{
int exited = 0 ;
/*
* Here is a tricky presentation problem . This solution
* is still not entirely satisfactory but since there
* are no wait status constructors it will have to do .
*/
if ( WIFSTOPPED ( status ) ) {
2015-02-13 01:43:02 +03:00
int sig = WSTOPSIG ( status ) ;
tprintf ( " [{WIFSTOPPED(s) && WSTOPSIG(s) == %s%s} " ,
signame ( sig & 0x7f ) ,
sig & 0x80 ? " | 0x80 " : " " ) ;
status & = ~ W_STOPCODE ( sig ) ;
2017-06-18 01:23:09 +03:00
} else if ( WIFSIGNALED ( status ) ) {
2014-12-11 22:25:02 +03:00
tprintf ( " [{WIFSIGNALED(s) && WTERMSIG(s) == %s%s} " ,
signame ( WTERMSIG ( status ) ) ,
WCOREDUMP ( status ) ? " && WCOREDUMP(s) " : " " ) ;
status & = ~ ( W_EXITCODE ( 0 , WTERMSIG ( status ) ) | WCOREFLAG ) ;
2017-06-18 01:23:09 +03:00
} else if ( WIFEXITED ( status ) ) {
2014-12-11 22:25:02 +03:00
tprintf ( " [{WIFEXITED(s) && WEXITSTATUS(s) == %d} " ,
WEXITSTATUS ( status ) ) ;
exited = 1 ;
status & = ~ W_EXITCODE ( WEXITSTATUS ( status ) , 0 ) ;
}
2015-02-13 01:43:02 +03:00
# ifdef WIFCONTINUED
else if ( WIFCONTINUED ( status ) ) {
tprints ( " [{WIFCONTINUED(s)} " ) ;
status & = ~ W_CONTINUED ;
}
# endif
2014-12-11 22:25:02 +03:00
else {
tprintf ( " [%#x] " , status ) ;
return 0 ;
}
2015-02-13 01:43:02 +03:00
if ( status ) {
unsigned int event = ( unsigned int ) status > > 16 ;
if ( event ) {
tprints ( " | " ) ;
printxval ( ptrace_events , event , " PTRACE_EVENT_??? " ) ;
tprints ( " << 16 " ) ;
status & = 0xffff ;
}
if ( status )
tprintf ( " | %#x " , status ) ;
}
tprints ( " ] " ) ;
2014-12-11 22:25:02 +03:00
return exited ;
}
static int
2016-12-22 03:54:18 +03:00
printwaitn ( struct tcb * const tcp ,
2016-12-26 13:26:03 +03:00
void ( * const print_rusage ) ( struct tcb * , kernel_ulong_t ) )
2014-12-11 22:25:02 +03:00
{
if ( entering ( tcp ) ) {
/* On Linux, kernel-side pid_t is typedef'ed to int
* on all arches . Also , glibc - 2.8 truncates wait3 and wait4
* pid argument to int on 64 bit arches , producing ,
* for example , wait4 ( 4294967295 , . . . ) instead of - 1
* in strace . We have to use int here , not long .
*/
int pid = tcp - > u_arg [ 0 ] ;
tprintf ( " %d, " , pid ) ;
} else {
2016-02-11 05:39:04 +03:00
int status ;
2014-12-11 22:25:02 +03:00
/* status */
2015-07-15 03:36:20 +03:00
if ( tcp - > u_rval = = 0 )
printaddr ( tcp - > u_arg [ 1 ] ) ;
else if ( ! umove_or_printaddr ( tcp , tcp - > u_arg [ 1 ] , & status ) )
2014-12-11 22:25:02 +03:00
printstatus ( status ) ;
/* options */
tprints ( " , " ) ;
printflags ( wait4_options , tcp - > u_arg [ 2 ] , " W??? " ) ;
2016-02-11 05:39:04 +03:00
if ( print_rusage ) {
2014-12-11 22:25:02 +03:00
/* usage */
2016-02-11 05:39:04 +03:00
tprints ( " , " ) ;
if ( tcp - > u_rval > 0 )
print_rusage ( tcp , tcp - > u_arg [ 3 ] ) ;
2014-12-11 22:25:02 +03:00
else
2015-07-15 03:36:20 +03:00
printaddr ( tcp - > u_arg [ 3 ] ) ;
2014-12-11 22:25:02 +03:00
}
}
return 0 ;
}
2015-04-07 04:36:50 +03:00
SYS_FUNC ( waitpid )
2014-12-11 22:25:02 +03:00
{
2016-02-11 05:39:04 +03:00
return printwaitn ( tcp , NULL ) ;
2014-12-11 22:25:02 +03:00
}
2015-04-07 04:36:50 +03:00
SYS_FUNC ( wait4 )
2014-12-11 22:25:02 +03:00
{
2016-02-11 05:39:04 +03:00
return printwaitn ( tcp , printrusage ) ;
2014-12-11 22:25:02 +03:00
}
# ifdef ALPHA
2015-04-07 04:36:50 +03:00
SYS_FUNC ( osf_wait4 )
2014-12-11 22:25:02 +03:00
{
2016-02-11 05:39:04 +03:00
return printwaitn ( tcp , printrusage32 ) ;
2014-12-11 22:25:02 +03:00
}
# endif
# include "xlat/waitid_types.h"
2015-04-07 04:36:50 +03:00
SYS_FUNC ( waitid )
2014-12-11 22:25:02 +03:00
{
if ( entering ( tcp ) ) {
printxval ( waitid_types , tcp - > u_arg [ 0 ] , " P_??? " ) ;
2016-02-11 05:42:36 +03:00
int pid = tcp - > u_arg [ 1 ] ;
tprintf ( " , %d, " , pid ) ;
2015-07-15 03:36:20 +03:00
} else {
2014-12-11 22:25:02 +03:00
/* siginfo */
2015-09-16 00:51:15 +03:00
printsiginfo_at ( tcp , tcp - > u_arg [ 2 ] ) ;
2014-12-11 22:25:02 +03:00
/* options */
tprints ( " , " ) ;
printflags ( wait4_options , tcp - > u_arg [ 3 ] , " W??? " ) ;
2016-02-11 05:20:18 +03:00
/* usage */
tprints ( " , " ) ;
printrusage ( tcp , tcp - > u_arg [ 4 ] ) ;
2014-12-11 22:25:02 +03:00
}
return 0 ;
}