xref: /freebsd/sys/kern/kern_dtrace.c (revision 80544aebe3e78b37f725a81cd48ae783372dc781)
180544aebSJohn Birrell /*-
280544aebSJohn Birrell  * Copyright (c) 2007-2008 John Birrell <jb@FreeBSD.org>
380544aebSJohn Birrell  * All rights reserved.
480544aebSJohn Birrell  *
580544aebSJohn Birrell  * Redistribution and use in source and binary forms, with or without
680544aebSJohn Birrell  * modification, are permitted provided that the following conditions
780544aebSJohn Birrell  * are met:
880544aebSJohn Birrell  * 1. Redistributions of source code must retain the above copyright
980544aebSJohn Birrell  *    notice, this list of conditions and the following disclaimer.
1080544aebSJohn Birrell  * 2. Redistributions in binary form must reproduce the above copyright
1180544aebSJohn Birrell  *    notice, this list of conditions and the following disclaimer in the
1280544aebSJohn Birrell  *    documentation and/or other materials provided with the distribution.
1380544aebSJohn Birrell  *
1480544aebSJohn Birrell  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1580544aebSJohn Birrell  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1680544aebSJohn Birrell  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1780544aebSJohn Birrell  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1880544aebSJohn Birrell  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1980544aebSJohn Birrell  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2080544aebSJohn Birrell  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2180544aebSJohn Birrell  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2280544aebSJohn Birrell  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2380544aebSJohn Birrell  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2480544aebSJohn Birrell  * SUCH DAMAGE.
2580544aebSJohn Birrell  */
2680544aebSJohn Birrell 
2780544aebSJohn Birrell #include <sys/cdefs.h>
2880544aebSJohn Birrell __FBSDID("$FreeBSD$");
2980544aebSJohn Birrell 
3080544aebSJohn Birrell #include "opt_kdb.h"
3180544aebSJohn Birrell 
3280544aebSJohn Birrell #include <sys/param.h>
3380544aebSJohn Birrell #include <sys/systm.h>
3480544aebSJohn Birrell #include <sys/eventhandler.h>
3580544aebSJohn Birrell #include <sys/kdb.h>
3680544aebSJohn Birrell #include <sys/kernel.h>
3780544aebSJohn Birrell #include <sys/malloc.h>
3880544aebSJohn Birrell #include <sys/proc.h>
3980544aebSJohn Birrell #include <sys/dtrace_bsd.h>
4080544aebSJohn Birrell 
4180544aebSJohn Birrell #define KDTRACE_PROC_SIZE	64
4280544aebSJohn Birrell #define KDTRACE_PROC_ZERO	8
4380544aebSJohn Birrell #define	KDTRACE_THREAD_SIZE	256
4480544aebSJohn Birrell #define	KDTRACE_THREAD_ZERO	64
4580544aebSJohn Birrell 
4680544aebSJohn Birrell MALLOC_DEFINE(M_KDTRACE, "kdtrace", "DTrace hooks");
4780544aebSJohn Birrell 
4880544aebSJohn Birrell /* Return the DTrace process data size compiled in the kernel hooks. */
4980544aebSJohn Birrell size_t
5080544aebSJohn Birrell kdtrace_proc_size()
5180544aebSJohn Birrell {
5280544aebSJohn Birrell 	return(KDTRACE_PROC_SIZE);
5380544aebSJohn Birrell }
5480544aebSJohn Birrell 
5580544aebSJohn Birrell static void
5680544aebSJohn Birrell kdtrace_proc_ctor(void *arg __unused, struct proc *p)
5780544aebSJohn Birrell {
5880544aebSJohn Birrell 	p->p_dtrace = malloc(KDTRACE_PROC_SIZE, M_KDTRACE, M_WAITOK);
5980544aebSJohn Birrell 
6080544aebSJohn Birrell 	bzero(p->p_dtrace, KDTRACE_PROC_ZERO);
6180544aebSJohn Birrell }
6280544aebSJohn Birrell 
6380544aebSJohn Birrell static void
6480544aebSJohn Birrell kdtrace_proc_dtor(void *arg __unused, struct proc *p)
6580544aebSJohn Birrell {
6680544aebSJohn Birrell 	if (p->p_dtrace != NULL) {
6780544aebSJohn Birrell 		free(p->p_dtrace, M_KDTRACE);
6880544aebSJohn Birrell 		p->p_dtrace = NULL;
6980544aebSJohn Birrell 	}
7080544aebSJohn Birrell }
7180544aebSJohn Birrell 
7280544aebSJohn Birrell /* Return the DTrace thread data size compiled in the kernel hooks. */
7380544aebSJohn Birrell size_t
7480544aebSJohn Birrell kdtrace_thread_size()
7580544aebSJohn Birrell {
7680544aebSJohn Birrell 	return(KDTRACE_THREAD_SIZE);
7780544aebSJohn Birrell }
7880544aebSJohn Birrell 
7980544aebSJohn Birrell static void
8080544aebSJohn Birrell kdtrace_thread_ctor(void *arg __unused, struct thread *td)
8180544aebSJohn Birrell {
8280544aebSJohn Birrell 	td->td_dtrace = malloc(KDTRACE_THREAD_SIZE, M_KDTRACE, M_WAITOK);
8380544aebSJohn Birrell 
8480544aebSJohn Birrell 	bzero(td->td_dtrace, KDTRACE_THREAD_ZERO);
8580544aebSJohn Birrell }
8680544aebSJohn Birrell 
8780544aebSJohn Birrell static void
8880544aebSJohn Birrell kdtrace_thread_dtor(void *arg __unused, struct thread *td)
8980544aebSJohn Birrell {
9080544aebSJohn Birrell 	if (td->td_dtrace != NULL) {
9180544aebSJohn Birrell 		free(td->td_dtrace, M_KDTRACE);
9280544aebSJohn Birrell 		td->td_dtrace = NULL;
9380544aebSJohn Birrell 	}
9480544aebSJohn Birrell }
9580544aebSJohn Birrell 
9680544aebSJohn Birrell /*
9780544aebSJohn Birrell  *  Initialise the kernel DTrace hooks.
9880544aebSJohn Birrell  */
9980544aebSJohn Birrell static void
10080544aebSJohn Birrell init_dtrace(void *dummy __unused)
10180544aebSJohn Birrell {
10280544aebSJohn Birrell 	EVENTHANDLER_REGISTER(process_ctor, kdtrace_proc_ctor, NULL, EVENTHANDLER_PRI_ANY);
10380544aebSJohn Birrell 	EVENTHANDLER_REGISTER(process_dtor, kdtrace_proc_dtor, NULL, EVENTHANDLER_PRI_ANY);
10480544aebSJohn Birrell 	EVENTHANDLER_REGISTER(thread_ctor, kdtrace_thread_ctor, NULL, EVENTHANDLER_PRI_ANY);
10580544aebSJohn Birrell 	EVENTHANDLER_REGISTER(thread_dtor, kdtrace_thread_dtor, NULL, EVENTHANDLER_PRI_ANY);
10680544aebSJohn Birrell }
10780544aebSJohn Birrell 
10880544aebSJohn Birrell SYSINIT(kdtrace, SI_SUB_KDTRACE, SI_ORDER_FIRST, init_dtrace, NULL);
10980544aebSJohn Birrell 
11080544aebSJohn Birrell #ifndef KDB
11180544aebSJohn Birrell /*
11280544aebSJohn Birrell  * This is a stub for the kernel debugger for the DTrace actions to call
11380544aebSJohn Birrell  * when the kernel has been built without KDB.
11480544aebSJohn Birrell  */
11580544aebSJohn Birrell void
11680544aebSJohn Birrell kdb_enter(const char *why, const char *msg)
11780544aebSJohn Birrell {
11880544aebSJohn Birrell 	printf("Cannot enter kernel debugger - No KDB in kernel.\n%s - %s\n", why, msg);
11980544aebSJohn Birrell }
12080544aebSJohn Birrell #endif
121