From: Matthew Dillon Date: Mon, 20 Jun 2005 20:37:28 +0000 (+0000) Subject: Add a caller backtrace feature (enabled by default), which records part of X-Git-Tag: v2.0.1~6839 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/af6ff89e8cc28950a4ffd7be3cd935fa6e7a3c01 Add a caller backtrace feature (enabled by default), which records part of the call chain leading up to the traced function. Two call chain instruction addresses are recorded. --- diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 7521698ff0..67ad366073 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -2,7 +2,7 @@ # files marked standard are always included. # # $FreeBSD: src/sys/conf/files.i386,v 1.307.2.38 2003/01/02 20:41:33 kan Exp $ -# $DragonFly: src/sys/conf/Attic/files.i386,v 1.31 2005/06/11 09:03:48 swildner Exp $ +# $DragonFly: src/sys/conf/Attic/files.i386,v 1.32 2005/06/20 20:37:23 dillon Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -166,6 +166,7 @@ i386/i386/identcpu.c standard i386/i386/in_cksum2.s optional inet i386/i386/initcpu.c standard i386/i386/k6_mem.c standard +i386/i386/ktr.c optional ktr i386/i386/tls.c standard # locore.s needs to be handled in Makefile to put it first. Otherwise it's # now normal. diff --git a/sys/cpu/i386/misc/ktr.c b/sys/cpu/i386/misc/ktr.c new file mode 100644 index 0000000000..e35495baea --- /dev/null +++ b/sys/cpu/i386/misc/ktr.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * + * 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. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 + * COPYRIGHT HOLDERS OR CONTRIBUTORS 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. + * + * $DragonFly: src/sys/cpu/i386/misc/ktr.c,v 1.1 2005/06/20 20:37:28 dillon Exp $ + */ +/* + * Kernel tracepoint facility. + */ + +#include "opt_ddb.h" +#include "opt_ktr.h" + +#include +#include +#include +#include +#include +#include +#include + +/* + * This routine fills in the ktr_caller1 and ktr_caller2 fields by + * tracing back through the kernel stack to locate the stack frames + * and return addresses. + * + * + * [first argument] + * [retpc] + * [frameptr] -> points to caller's frame pointer + * sp ->[junk] + */ + +static __inline +void ** +FRAMEUP(void **frameptr) +{ + void **newframeptr; + + newframeptr = (void **)frameptr[0]; + if (((uintptr_t)newframeptr ^ (uintptr_t)frameptr) & ~16383) + newframeptr = frameptr; + return(newframeptr); +} + +void +cpu_ktr_caller(struct ktr_entry *_ktr) +{ + struct ktr_entry *ktr; + void **frameptr; + + frameptr = (void **)&_ktr - 2; /* frame, retpc to ktr_log */ + ktr = _ktr; + frameptr = FRAMEUP(frameptr); /* frame, retpc to traced function */ + frameptr = FRAMEUP(frameptr); /* frame, caller1 of traced function */ + ktr->ktr_caller1 = frameptr[1]; + frameptr = FRAMEUP(frameptr); /* frame, caller2 of caller1 */ + ktr->ktr_caller2 = frameptr[1]; +} + diff --git a/sys/i386/i386/ktr.c b/sys/i386/i386/ktr.c new file mode 100644 index 0000000000..851da7812a --- /dev/null +++ b/sys/i386/i386/ktr.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * + * 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. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 + * COPYRIGHT HOLDERS OR CONTRIBUTORS 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. + * + * $DragonFly: src/sys/i386/i386/Attic/ktr.c,v 1.1 2005/06/20 20:37:28 dillon Exp $ + */ +/* + * Kernel tracepoint facility. + */ + +#include "opt_ddb.h" +#include "opt_ktr.h" + +#include +#include +#include +#include +#include +#include +#include + +/* + * This routine fills in the ktr_caller1 and ktr_caller2 fields by + * tracing back through the kernel stack to locate the stack frames + * and return addresses. + * + * + * [first argument] + * [retpc] + * [frameptr] -> points to caller's frame pointer + * sp ->[junk] + */ + +static __inline +void ** +FRAMEUP(void **frameptr) +{ + void **newframeptr; + + newframeptr = (void **)frameptr[0]; + if (((uintptr_t)newframeptr ^ (uintptr_t)frameptr) & ~16383) + newframeptr = frameptr; + return(newframeptr); +} + +void +cpu_ktr_caller(struct ktr_entry *_ktr) +{ + struct ktr_entry *ktr; + void **frameptr; + + frameptr = (void **)&_ktr - 2; /* frame, retpc to ktr_log */ + ktr = _ktr; + frameptr = FRAMEUP(frameptr); /* frame, retpc to traced function */ + frameptr = FRAMEUP(frameptr); /* frame, caller1 of traced function */ + ktr->ktr_caller1 = frameptr[1]; + frameptr = FRAMEUP(frameptr); /* frame, caller2 of caller1 */ + ktr->ktr_caller2 = frameptr[1]; +} + diff --git a/sys/kern/kern_ktr.c b/sys/kern/kern_ktr.c index 5f536af9b6..704d9bad44 100644 --- a/sys/kern/kern_ktr.c +++ b/sys/kern/kern_ktr.c @@ -62,7 +62,7 @@ * SUCH DAMAGE. */ /* - * $DragonFly: src/sys/kern/kern_ktr.c,v 1.5 2005/06/20 17:59:32 dillon Exp $ + * $DragonFly: src/sys/kern/kern_ktr.c,v 1.6 2005/06/20 20:37:24 dillon Exp $ */ /* * Kernel tracepoint facility. @@ -100,16 +100,19 @@ MALLOC_DEFINE(M_KTR, "ktr", "ktr buffers"); SYSCTL_NODE(_debug, OID_AUTO, ktr, CTLFLAG_RW, 0, "ktr"); -int32_t ktr_cpumask = -1; +static int32_t ktr_cpumask = -1; TUNABLE_INT("debug.ktr.cpumask", &ktr_cpumask); SYSCTL_INT(_debug_ktr, OID_AUTO, cpumask, CTLFLAG_RW, &ktr_cpumask, 0, ""); -int ktr_entries = KTR_ENTRIES; +static int ktr_entries = KTR_ENTRIES; SYSCTL_INT(_debug_ktr, OID_AUTO, entries, CTLFLAG_RD, &ktr_entries, 0, ""); -int ktr_version = KTR_VERSION; +static int ktr_version = KTR_VERSION; SYSCTL_INT(_debug_ktr, OID_AUTO, version, CTLFLAG_RD, &ktr_version, 0, ""); +static int ktr_stacktrace = 1; +SYSCTL_INT(_debug_ktr, OID_AUTO, stacktrace, CTLFLAG_RD, &ktr_stacktrace, 0, ""); + /* * Give cpu0 a static buffer so the tracepoint facility can be used during * early boot (note however that we still use a critical section, XXX). @@ -162,6 +165,8 @@ ktr_write_entry(struct ktr_info *info, const char *file, int line, bcopyi(ptr, entry->ktr_data, KTR_BUFSIZE); else bcopyi(ptr, entry->ktr_data, info->kf_data_size); + if (ktr_stacktrace) + cpu_ktr_caller(entry); } #ifdef KTR_VERBOSE if (ktr_verbose && info->kf_format) { @@ -182,15 +187,19 @@ ktr_log(struct ktr_info *info, const char *file, int line, ...) { __va_list va; - __va_start(va, line); - ktr_write_entry(info, file, line, va); - __va_end(va); + if (panicstr == NULL) { + __va_start(va, line); + ktr_write_entry(info, file, line, va); + __va_end(va); + } } void ktr_log_ptr(struct ktr_info *info, const char *file, int line, const void *ptr) { - ktr_write_entry(info, file, line, ptr); + if (panicstr == NULL) { + ktr_write_entry(info, file, line, ptr); + } } #ifdef DDB @@ -315,8 +324,9 @@ db_mach_vtrace(int cpu, struct ktr_entry *kp, int idx) kp->ktr_file, kp->ktr_line); } db_printf("%s\t", kp->ktr_info->kf_name); + db_printf("from(%p,%p) ", kp->ktr_caller1, kp->ktr_caller2); if (kp->ktr_info->kf_format) { - int32_t *args = (int32_t *)kp->ktr_data; + int32_t *args = kp->ktr_data; db_printf(kp->ktr_info->kf_format, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], diff --git a/sys/sys/ktr.h b/sys/sys/ktr.h index b259de5476..1ade243402 100644 --- a/sys/sys/ktr.h +++ b/sys/sys/ktr.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/ktr.h,v 1.5 2005/06/20 17:59:30 dillon Exp $ + * $DragonFly: src/sys/sys/ktr.h,v 1.6 2005/06/20 20:37:26 dillon Exp $ */ /* * Generic Kernel trace buffer support. @@ -69,11 +69,12 @@ struct ktr_entry { void *ktr_caller2; int32_t ktr_line; int32_t ktr_unused; - char ktr_data[KTR_BUFSIZE]; + int32_t ktr_data[KTR_BUFSIZE / sizeof(int32_t)]; }; void ktr_log(struct ktr_info *info, const char *file, int line, ...); void ktr_log_ptr(struct ktr_info *info, const char *file, int line, const void *ptr); +void cpu_ktr_caller(struct ktr_entry *ktr); /* * Take advantage of constant integer optimizations by the compiler