⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.c

📁 linux进程跟踪的工具和源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation *                     Linux for s390 port by D.J. Barrow *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com> * * 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. * *	$Id: process.c,v 1.28 2001/03/28 20:29:17 wichert Exp $ */#include "defs.h"#include <fcntl.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/wait.h>#include <sys/resource.h>#include <sys/utsname.h>#include <sys/user.h>#include <sys/syscall.h>#include <signal.h>#ifdef SUNOS4#include <machine/reg.h>#endif /* SUNOS4 */#ifdef FREEBSD#include <sys/ptrace.h>#endif#if HAVE_ASM_REG_H#ifdef SPARC#  define fpq kernel_fpq#  define fq kernel_fq#  define fpu kernel_fpu#endif#include <asm/reg.h>#ifdef SPARC#  undef fpq#  undef fq#  undef fpu #endif#endif /* HAVE_ASM_REG_H */#ifdef HAVE_SYS_REG_H# include <sys/reg.h>#ifndef PTRACE_PEEKUSR# define PTRACE_PEEKUSR PTRACE_PEEKUSER#endif#ifndef PTRACE_POKEUSR# define PTRACE_POKEUSR PTRACE_POKEUSER#endif#elif defined(HAVE_LINUX_PTRACE_H)#undef PTRACE_SYSCALL#include <linux/ptrace.h>#endif#ifdef LINUX#include <asm/posix_types.h>#undef GETGROUPS_T#define GETGROUPS_T __kernel_gid_t#endif /* LINUX */#if defined(LINUX) && defined(IA64)# include <asm/ptrace_offsets.h># include <asm/rse.h>#endif#ifdef HAVE_PRCTL#include <sys/prctl.h>#endif#ifndef WCOREDUMP#define WCOREDUMP(status) ((status) & 0200)#endif/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */#if defined(HAVE_PRCTL)static struct xlat prctl_options[] = {#ifdef PR_MAXPROCS	{ PR_MAXPROCS,		"PR_MAXPROCS"		},#endif#ifdef PR_ISBLOCKED	{ PR_ISBLOCKED,		"PR_ISBLOCKED"		},#endif#ifdef PR_SETSTACKSIZE	{ PR_SETSTACKSIZE,	"PR_SETSTACKSIZE"	},#endif#ifdef PR_GETSTACKSIZE	{ PR_GETSTACKSIZE,	"PR_GETSTACKSIZE"	},#endif#ifdef PR_MAXPPROCS	{ PR_MAXPPROCS,		"PR_MAXPPROCS"		},#endif#ifdef PR_UNBLKONEXEC	{ PR_UNBLKONEXEC,	"PR_UNBLKONEXEC"	},#endif#ifdef PR_ATOMICSIM	{ PR_ATOMICSIM,		"PR_ATOMICSIM"		},#endif#ifdef PR_SETEXITSIG	{ PR_SETEXITSIG,	"PR_SETEXITSIG"		},#endif#ifdef PR_RESIDENT	{ PR_RESIDENT,		"PR_RESIDENT"		},#endif#ifdef PR_ATTACHADDR	{ PR_ATTACHADDR,	"PR_ATTACHADDR"		},#endif#ifdef PR_DETACHADDR	{ PR_DETACHADDR,	"PR_DETACHADDR"		},#endif#ifdef PR_TERMCHILD	{ PR_TERMCHILD,		"PR_TERMCHILD"		},#endif#ifdef PR_GETSHMASK	{ PR_GETSHMASK,		"PR_GETSHMASK"		},#endif#ifdef PR_GETNSHARE	{ PR_GETNSHARE,		"PR_GETNSHARE"		},#endif#if defined(PR_SET_PDEATHSIG)	{ PR_SET_PDEATHSIG,	"PR_SET_PDEATHSIG"	},#endif#ifdef PR_COREPID	{ PR_COREPID,		"PR_COREPID"		},#endif#ifdef PR_ATTACHADDRPERM	{ PR_ATTACHADDRPERM,	"PR_ATTACHADDRPERM"	},#endif#ifdef PR_PTHREADEXIT	{ PR_PTHREADEXIT,	"PR_PTHREADEXIT"	},#endif#ifdef PR_SET_PDEATHSIG	{ PR_SET_PDEATHSIG,	"PR_SET_PDEATHSIG"	},#endif#ifdef PR_GET_PDEATHSIG	{ PR_GET_PDEATHSIG,	"PR_GET_PDEATHSIG"	},#endif#ifdef PR_GET_UNALIGN	{ PR_GET_UNALIGN,	"PR_GET_UNALIGN"	},#endif#ifdef PR_SET_UNALIGN	{ PR_SET_UNALIGN,	"PR_SET_UNALIGN"	},#endif#ifdef PR_GET_KEEPCAPS	{ PR_GET_KEEPCAPS,	"PR_GET_KEEP_CAPS"	},#endif#ifdef PR_SET_KEEPCAPS	{ PR_SET_KEEPCAPS,	"PR_SET_KEEP_CAPS"	},#endif	{ 0,			NULL			},};const char *unalignctl_string (unsigned int ctl){	static char buf[16];	switch (ctl) {#ifdef PR_UNALIGN_NOPRINT	      case PR_UNALIGN_NOPRINT:		return "NOPRINT";#endif#ifdef PR_UNALIGN_SIGBUS	      case PR_UNALIGN_SIGBUS:		return "SIGBUS";#endif	      default:		break;	}	sprintf(buf, "%x", ctl);	return buf;}intsys_prctl(tcp)struct tcb *tcp;{	int i;	if (entering(tcp)) {		printxval(prctl_options, tcp->u_arg[0], "PR_???");		switch (tcp->u_arg[0]) {#ifdef PR_GETNSHARE		case PR_GETNSHARE:			break;#endif#ifdef PR_SET_DEATHSIG		case PR_GET_PDEATHSIG:			break;#endif#ifdef PR_SET_UNALIGN		case PR_SET_UNALIGN:			tprintf(", %s", unalignctl_string(tcp->u_arg[1]));			break;#endif#ifdef PR_GET_UNALIGN		case PR_GET_UNALIGN:			tprintf(", %#lx", tcp->u_arg[1]);			break;#endif		default:			for (i = 1; i < tcp->u_nargs; i++)				tprintf(", %#lx", tcp->u_arg[i]);			break;		}	} else {		switch (tcp->u_arg[0]) {#ifdef PR_GET_PDEATHSIG		case PR_GET_PDEATHSIG:			for (i=1; i<tcp->u_nargs; i++)				tprintf(", %#lx", tcp->u_arg[i]);			break;#endif#ifdef PR_SET_UNALIGN		case PR_SET_UNALIGN:			break;#endif#ifdef PR_GET_UNALIGN		case PR_GET_UNALIGN:		{			int ctl;			umove(tcp, tcp->u_arg[1], &ctl);			tcp->auxstr = unalignctl_string(ctl);			return RVAL_STR;		}#endif		default:			break;		}	}	return 0;}#endif /* HAVE_PRCTL */intsys_gethostid(tcp)struct tcb *tcp;{	if (exiting(tcp))		return RVAL_HEX;	return 0;}intsys_sethostname(tcp)struct tcb *tcp;{	if (entering(tcp)) {		printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);		tprintf(", %lu", tcp->u_arg[1]);	}	return 0;}intsys_gethostname(tcp)struct tcb *tcp;{	if (exiting(tcp)) {		if (syserror(tcp))			tprintf("%#lx", tcp->u_arg[0]);		else			printpath(tcp, tcp->u_arg[0]);		tprintf(", %lu", tcp->u_arg[1]);	}	return 0;}intsys_setdomainname(tcp)struct tcb *tcp;{	if (entering(tcp)) {		printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);		tprintf(", %lu", tcp->u_arg[1]);	}	return 0;}#if !defined(LINUX)intsys_getdomainname(tcp)struct tcb *tcp;{	if (exiting(tcp)) {		if (syserror(tcp))			tprintf("%#lx", tcp->u_arg[0]);		else			printpath(tcp, tcp->u_arg[0]);		tprintf(", %lu", tcp->u_arg[1]);	}	return 0;}#endif /* !LINUX */intsys_exit(tcp)struct tcb *tcp;{	if (exiting(tcp)) {		fprintf(stderr, "_exit returned!\n");		return -1;	}	/* special case: we stop tracing this process, finish line now */	tprintf("%ld) ", tcp->u_arg[0]);	tabto(acolumn);	tprintf("= ?");	printtrailer(tcp);	return 0;}intinternal_exit(tcp)struct tcb *tcp;{	if (entering(tcp))		tcp->flags |= TCB_EXITING;	return 0;}#ifdef USE_PROCFSintsys_fork(tcp)struct tcb *tcp;{	if (exiting(tcp)) {		if (getrval2(tcp)) {			tcp->auxstr = "child process";			return RVAL_UDECIMAL | RVAL_STR;		}	}	return 0;}intinternal_fork(tcp)struct tcb *tcp;{	struct tcb *tcpchild;	if (exiting(tcp)) {		if (getrval2(tcp))			return 0;		if (!followfork)			return 0;		if (nprocs == MAX_PROCS) {			tcp->flags &= ~TCB_FOLLOWFORK;			fprintf(stderr, "sys_fork: tcb table full\n");			return 0;		}		else			tcp->flags |= TCB_FOLLOWFORK;		if (syserror(tcp))			return 0;		if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {			fprintf(stderr, "sys_fork: tcb table full\n");			return 0;		}		if (proc_open(tcpchild, 2) < 0)		  	droptcb(tcpchild);	}	return 0;}#else /* !USE_PROCFS */#ifdef LINUX/* defines copied from linux/sched.h since we can't include that * ourselves (it conflicts with *lots* of libc includes) */#define CSIGNAL         0x000000ff      /* signal mask to be sent at exit */#define CLONE_VM        0x00000100      /* set if VM shared between processes */#define CLONE_FS        0x00000200      /* set if fs info shared between processes */#define CLONE_FILES     0x00000400      /* set if open files shared between processes */#define CLONE_SIGHAND   0x00000800      /* set if signal handlers shared */#define CLONE_PID       0x00001000      /* set if pid shared */#define CLONE_PTRACE    0x00002000      /* set if we want to let tracing continue on the child too */#define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */#define CLONE_PARENT    0x00008000      /* set if we want to have the same parent as the cloner */static struct xlat clone_flags[] = {    { CLONE_VM,		"CLONE_VM"	},    { CLONE_FS,		"CLONE_FS"	},    { CLONE_FILES,	"CLONE_FILES"	},    { CLONE_SIGHAND,	"CLONE_SIGHAND"	},    { CLONE_PID,	"CLONE_PID"	},    { CLONE_PTRACE,	"CLONE_PTRACE"	},    { CLONE_VFORK,	"CLONE_VFORK"	},    { CLONE_PARENT,	"CLONE_PARENT"	},    { 0,		NULL		},};intsys_clone(tcp)struct tcb *tcp;{	if (exiting(tcp)) {		tprintf("child_stack=%#lx, flags=", tcp->u_arg[1]);		if (printflags(clone_flags, tcp->u_arg[0]) == 0)			tprintf("0");	}	return 0;}#endifintsys_fork(tcp)struct tcb *tcp;{	if (exiting(tcp))		return RVAL_UDECIMAL;	return 0;}intchange_syscall(tcp, new)struct tcb *tcp;int new;{#if defined(LINUX)#if defined(I386)	/* Attempt to make vfork into fork, which we can follow. */	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0) 		return -1;	return 0;#elif defined(POWERPC)	if (ptrace(PTRACE_POKEUSER, tcp->pid, (CHAR*)(4*PT_R0), new) < 0)		return -1;#elif defined(S390)	long	pc;	if (upeek(tcp->pid, PT_PSWADDR,&pc)<0)	    	return -1;	if (ptrace(PTRACE_POKETEXT, tcp->pid, (char*)(pc-4), new)<0)	    	return -1;	return 0;#elif defined(M68K)	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)	    	return -1;	return 0;#elif defined(SPARC)	struct regs regs;	if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)		return -1;	regs.r_g1=new;	if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)	    	return -1;	return 0;#elif defined(MIPS)	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)	    	return -1;	return 0;#elif defined(ALPHA)	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)	    	return -1;	return 0;#elif defined(HPPA)	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)	    	return -1;	return 0;#else#warning Do not know how to handle change_syscall for this architecture#endif /* architecture */#endif /* LINUX */	return -1;}intsetarg(tcp, argnum)	struct tcb *tcp;	int argnum;{#if defined (IA64)	{		unsigned long *bsp, *ap;		if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)			return -1;		ap = ia64_rse_skip_regs(bsp, argnum);		errno = 0;		ptrace(PTRACE_POKEDATA, tcp->pid, ap, tcp->u_arg[argnum]);		if (errno)			return -1;	}#elif defined(I386)	{		ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);		if (errno)			return -1;	}#elif defined(MIPS)	{		errno = 0;		if (argnum < 4)			ptrace(PTRACE_POKEUSER, tcp->pid,			       (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);		else {			unsigned long *sp;			if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)				return -1;			ptrace(PTRACE_POKEDATA, tcp->pid,			       (char*)(sp + argnum - 4), tcp->u_arg[argnum]);		}		if (errno)			return -1;	}#else# warning Sorry, setargs not implemented for this architecture.#endif	return 0;}#ifdef SYS_cloneintinternal_clone(tcp)struct tcb *tcp;{	struct tcb *tcpchild;	int pid;	if (entering(tcp)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -