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

📄 systrace.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
字号:
/* * Copyright 2005 Sun Microsystems, Inc.  All rights reserved. * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only. * See the file usr/src/LICENSING.NOTICE in this distribution or * http://www.opensolaris.org/license/ for details. */#pragma ident	"@(#)systrace.c	1.3	04/09/28 SMI"#include <sys/dtrace.h>#include <sys/systrace.h>#include <sys/stat.h>#include <sys/systm.h>#include <sys/conf.h>#include <sys/ddi.h>#include <sys/sunddi.h>#include <sys/atomic.h>#define	SYSTRACE_ARTIFICIAL_FRAMES	1#define	SYSTRACE_SHIFT			16#define	SYSTRACE_ISENTRY(x)		((int)(x) >> SYSTRACE_SHIFT)#define	SYSTRACE_SYSNUM(x)		((int)(x) & ((1 << SYSTRACE_SHIFT) - 1))#define	SYSTRACE_ENTRY(id)		((1 << SYSTRACE_SHIFT) | (id))#define	SYSTRACE_RETURN(id)		(id)#if ((1 << SYSTRACE_SHIFT) <= NSYSCALL)#error 1 << SYSTRACE_SHIFT must exceed number of system calls#endifstatic dev_info_t *systrace_devi;static dtrace_provider_id_t systrace_id;static voidsystrace_init(struct sysent *actual, systrace_sysent_t **interposed){	systrace_sysent_t *sysent = *interposed;	int i;	if (sysent == NULL) {		*interposed = sysent = kmem_zalloc(sizeof (systrace_sysent_t) *		    NSYSCALL, KM_SLEEP);	}	for (i = 0; i < NSYSCALL; i++) {		struct sysent *a = &actual[i];		systrace_sysent_t *s = &sysent[i];		if (LOADABLE_SYSCALL(a) && !LOADED_SYSCALL(a))			continue;		if (a->sy_callc == dtrace_systrace_syscall)			continue;#ifdef _SYSCALL32_IMPL		if (a->sy_callc == dtrace_systrace_syscall32)			continue;#endif		s->stsy_underlying = a->sy_callc;	}}/*ARGSUSED*/static voidsystrace_provide(void *arg, const dtrace_probedesc_t *desc){	int i;	if (desc != NULL)		return;	systrace_init(sysent, &systrace_sysent);#ifdef _SYSCALL32_IMPL	systrace_init(sysent32, &systrace_sysent32);#endif	for (i = 0; i < NSYSCALL; i++) {		if (systrace_sysent[i].stsy_underlying == NULL)			continue;		if (dtrace_probe_lookup(systrace_id, NULL,		    syscallnames[i], "entry") != 0)			continue;		(void) dtrace_probe_create(systrace_id, NULL, syscallnames[i],		    "entry", SYSTRACE_ARTIFICIAL_FRAMES,		    (void *)((uintptr_t)SYSTRACE_ENTRY(i)));		(void) dtrace_probe_create(systrace_id, NULL, syscallnames[i],		    "return", SYSTRACE_ARTIFICIAL_FRAMES,		    (void *)((uintptr_t)SYSTRACE_RETURN(i)));		systrace_sysent[i].stsy_entry = DTRACE_IDNONE;		systrace_sysent[i].stsy_return = DTRACE_IDNONE;#ifdef _SYSCALL32_IMPL		systrace_sysent32[i].stsy_entry = DTRACE_IDNONE;		systrace_sysent32[i].stsy_return = DTRACE_IDNONE;#endif	}}/*ARGSUSED*/static voidsystrace_destroy(void *arg, dtrace_id_t id, void *parg){	int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);	/*	 * There's nothing to do here but assert that we have actually been	 * disabled.	 */	if (SYSTRACE_ISENTRY((uintptr_t)parg)) {		ASSERT(systrace_sysent[sysnum].stsy_entry == DTRACE_IDNONE);#ifdef _SYSCALL32_IMPL		ASSERT(systrace_sysent32[sysnum].stsy_entry == DTRACE_IDNONE);#endif	} else {		ASSERT(systrace_sysent[sysnum].stsy_return == DTRACE_IDNONE);#ifdef _SYSCALL32_IMPL		ASSERT(systrace_sysent32[sysnum].stsy_return == DTRACE_IDNONE);#endif	}}/*ARGSUSED*/static voidsystrace_enable(void *arg, dtrace_id_t id, void *parg){	int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);	int enabled = (systrace_sysent[sysnum].stsy_entry != DTRACE_IDNONE ||	    systrace_sysent[sysnum].stsy_return != DTRACE_IDNONE);	if (SYSTRACE_ISENTRY((uintptr_t)parg)) {		systrace_sysent[sysnum].stsy_entry = id;#ifdef _SYSCALL32_IMPL		systrace_sysent32[sysnum].stsy_entry = id;#endif	} else {		systrace_sysent[sysnum].stsy_return = id;#ifdef _SYSCALL32_IMPL		systrace_sysent32[sysnum].stsy_return = id;#endif	}	if (enabled) {		ASSERT(sysent[sysnum].sy_callc == dtrace_systrace_syscall);		return;	}	(void) casptr(&sysent[sysnum].sy_callc,	    (void *)systrace_sysent[sysnum].stsy_underlying,	    (void *)dtrace_systrace_syscall);#ifdef _SYSCALL32_IMPL	(void) casptr(&sysent32[sysnum].sy_callc,	    (void *)systrace_sysent32[sysnum].stsy_underlying,	    (void *)dtrace_systrace_syscall32);#endif}/*ARGSUSED*/static voidsystrace_disable(void *arg, dtrace_id_t id, void *parg){	int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);	int disable = (systrace_sysent[sysnum].stsy_entry == DTRACE_IDNONE ||	    systrace_sysent[sysnum].stsy_return == DTRACE_IDNONE);	if (disable) {		(void) casptr(&sysent[sysnum].sy_callc,		    (void *)dtrace_systrace_syscall,		    (void *)systrace_sysent[sysnum].stsy_underlying);#ifdef _SYSCALL32_IMPL		(void) casptr(&sysent32[sysnum].sy_callc,		    (void *)dtrace_systrace_syscall32,		    (void *)systrace_sysent32[sysnum].stsy_underlying);#endif	}	if (SYSTRACE_ISENTRY((uintptr_t)parg)) {		systrace_sysent[sysnum].stsy_entry = DTRACE_IDNONE;#ifdef _SYSCALL32_IMPL		systrace_sysent32[sysnum].stsy_entry = DTRACE_IDNONE;#endif	} else {		systrace_sysent[sysnum].stsy_return = DTRACE_IDNONE;#ifdef _SYSCALL32_IMPL		systrace_sysent32[sysnum].stsy_return = DTRACE_IDNONE;#endif	}}static dtrace_pattr_t systrace_attr = {{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },};static dtrace_pops_t systrace_pops = {	systrace_provide,	NULL,	systrace_enable,	systrace_disable,	NULL,	NULL,	NULL,	NULL,	NULL,	systrace_destroy};static intsystrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd){	switch (cmd) {	case DDI_ATTACH:		break;	case DDI_RESUME:		return (DDI_SUCCESS);	default:		return (DDI_FAILURE);	}	systrace_probe = dtrace_probe;	membar_enter();	if (ddi_create_minor_node(devi, "systrace", S_IFCHR, 0,	    DDI_PSEUDO, NULL) == DDI_FAILURE ||	    dtrace_register("syscall", &systrace_attr, DTRACE_PRIV_USER, 0,	    &systrace_pops, NULL, &systrace_id) != 0) {		systrace_probe = systrace_stub;		ddi_remove_minor_node(devi, NULL);		return (DDI_FAILURE);	}	ddi_report_dev(devi);	systrace_devi = devi;	return (DDI_SUCCESS);}static intsystrace_detach(dev_info_t *devi, ddi_detach_cmd_t cmd){	switch (cmd) {	case DDI_DETACH:		break;	case DDI_SUSPEND:		return (DDI_SUCCESS);	default:		return (DDI_FAILURE);	}	if (dtrace_unregister(systrace_id) != 0)		return (DDI_FAILURE);	ddi_remove_minor_node(devi, NULL);	systrace_probe = systrace_stub;	return (DDI_SUCCESS);}/*ARGSUSED*/static intsystrace_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result){	int error;	switch (infocmd) {	case DDI_INFO_DEVT2DEVINFO:		*result = (void *)systrace_devi;		error = DDI_SUCCESS;		break;	case DDI_INFO_DEVT2INSTANCE:		*result = (void *)0;		error = DDI_SUCCESS;		break;	default:		error = DDI_FAILURE;	}	return (error);}/*ARGSUSED*/static intsystrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p){	return (0);}static struct cb_ops systrace_cb_ops = {	systrace_open,		/* open */	nodev,			/* close */	nulldev,		/* strategy */	nulldev,		/* print */	nodev,			/* dump */	nodev,			/* read */	nodev,			/* write */	nodev,			/* ioctl */	nodev,			/* devmap */	nodev,			/* mmap */	nodev,			/* segmap */	nochpoll,		/* poll */	ddi_prop_op,		/* cb_prop_op */	0,			/* streamtab  */	D_NEW | D_MP		/* Driver compatibility flag */};static struct dev_ops systrace_ops = {	DEVO_REV,		/* devo_rev, */	0,			/* refcnt  */	systrace_info,		/* get_dev_info */	nulldev,		/* identify */	nulldev,		/* probe */	systrace_attach,	/* attach */	systrace_detach,	/* detach */	nodev,			/* reset */	&systrace_cb_ops,	/* driver operations */	NULL,			/* bus operations */	nodev			/* dev power */};/* * Module linkage information for the kernel. */static struct modldrv modldrv = {	&mod_driverops,		/* module type (this is a pseudo driver) */	"System Call Tracing",	/* name of module */	&systrace_ops,		/* driver ops */};static struct modlinkage modlinkage = {	MODREV_1,	(void *)&modldrv,	NULL};int_init(void){	return (mod_install(&modlinkage));}int_info(struct modinfo *modinfop){	return (mod_info(&modlinkage, modinfop));}int_fini(void){	return (mod_remove(&modlinkage));}

⌨️ 快捷键说明

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