1119936Sjhb/*- 2119936Sjhb * Copyright (c) 2000 John Baldwin <jhb@FreeBSD.org> 3119936Sjhb * All rights reserved. 465556Sjasone * 565556Sjasone * Redistribution and use in source and binary forms, with or without 665556Sjasone * modification, are permitted provided that the following conditions 765556Sjasone * are met: 865556Sjasone * 1. Redistributions of source code must retain the above copyright 965556Sjasone * notice, this list of conditions and the following disclaimer. 1065556Sjasone * 2. Redistributions in binary form must reproduce the above copyright 1165556Sjasone * notice, this list of conditions and the following disclaimer in the 1265556Sjasone * documentation and/or other materials provided with the distribution. 1365556Sjasone * 14119936Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1565556Sjasone * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1665556Sjasone * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17119936Sjhb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18119936Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19119936Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20119936Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21119936Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22119936Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23119936Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24119936Sjhb * SUCH DAMAGE. 2565556Sjasone */ 2665556Sjasone 2765556Sjasone/* 2868420Sjhb * This module holds the global variables used by KTR and the ktr_tracepoint() 2968420Sjhb * function that does the actual tracing. 3065556Sjasone */ 3165556Sjasone 32116182Sobrien#include <sys/cdefs.h> 33116182Sobrien__FBSDID("$FreeBSD$"); 34116182Sobrien 3570035Sjhb#include "opt_ddb.h" 3668420Sjhb#include "opt_ktr.h" 37103787Sjeff#include "opt_alq.h" 3868420Sjhb 3970035Sjhb#include <sys/param.h> 40222813Sattilio#include <sys/queue.h> 41103787Sjeff#include <sys/alq.h> 4270035Sjhb#include <sys/cons.h> 43222813Sattilio#include <sys/cpuset.h> 4470705Sjhb#include <sys/kernel.h> 4565556Sjasone#include <sys/ktr.h> 4668420Sjhb#include <sys/libkern.h> 47243046Sjeff#include <sys/lock.h> 48243046Sjeff#include <sys/malloc.h> 49243046Sjeff#include <sys/mutex.h> 5087793Sjhb#include <sys/proc.h> 51243046Sjeff#include <sys/smp.h> 5265556Sjasone#include <sys/sysctl.h> 5368420Sjhb#include <sys/systm.h> 5478784Sjhb#include <sys/time.h> 5565556Sjasone 5693503Sjake#include <machine/cpu.h> 5793503Sjake 58160312Sjhb#ifdef DDB 5970035Sjhb#include <ddb/ddb.h> 60160312Sjhb#include <ddb/db_output.h> 61160312Sjhb#endif 6270035Sjhb 63246282Savg#ifndef KTR_BOOT_ENTRIES 64246282Savg#define KTR_BOOT_ENTRIES 1024 65246282Savg#endif 66246282Savg 6778784Sjhb#ifndef KTR_ENTRIES 6878784Sjhb#define KTR_ENTRIES 1024 6978784Sjhb#endif 7078784Sjhb 71243046Sjeff/* Limit the allocations to something manageable. */ 72243046Sjeff#define KTR_ENTRIES_MAX (8 * 1024 * 1024) 73243046Sjeff 7468420Sjhb#ifndef KTR_MASK 75210337Sattilio#define KTR_MASK (0) 7668420Sjhb#endif 7768420Sjhb 78239923Sattilio#ifndef KTR_CPUMASK 79239923Sattilio#define KTR_CPUMASK CPUSET_FSET 80239923Sattilio#endif 81239923Sattilio 8293503Sjake#ifndef KTR_TIME 8393503Sjake#define KTR_TIME get_cyclecount() 8468420Sjhb#endif 8568420Sjhb 8693503Sjake#ifndef KTR_CPU 8793503Sjake#define KTR_CPU PCPU_GET(cpuid) 8870705Sjhb#endif 8970705Sjhb 90243046Sjeffstatic MALLOC_DEFINE(M_KTR, "KTR", "KTR"); 91243046Sjeff 92219028SnetchildFEATURE(ktr, "Kernel support for KTR kernel tracing facility"); 93219028Snetchild 94243046Sjeffvolatile int ktr_idx = 0; 95243046Sjeffint ktr_mask = KTR_MASK; 96243046Sjeffint ktr_compile = KTR_COMPILE; 97246282Savgint ktr_entries = KTR_BOOT_ENTRIES; 98243046Sjeffint ktr_version = KTR_VERSION; 99246282Savgstruct ktr_entry ktr_buf_init[KTR_BOOT_ENTRIES]; 100243046Sjeffstruct ktr_entry *ktr_buf = ktr_buf_init; 101243046Sjeffcpuset_t ktr_cpumask = CPUSET_T_INITIALIZER(KTR_CPUMASK); 102243046Sjeffstatic char ktr_cpumask_str[CPUSETBUFSIZ]; 10370705Sjhb 10477900SpeterTUNABLE_INT("debug.ktr.mask", &ktr_mask); 10565556Sjasone 106243046SjeffTUNABLE_STR("debug.ktr.cpumask", ktr_cpumask_str, sizeof(ktr_cpumask_str)); 107132583Srwatson 108243046Sjeffstatic SYSCTL_NODE(_debug, OID_AUTO, ktr, CTLFLAG_RD, 0, "KTR options"); 10965556Sjasone 110205017SjhbSYSCTL_INT(_debug_ktr, OID_AUTO, version, CTLFLAG_RD, 111205017Sjhb &ktr_version, 0, "Version of the KTR interface"); 11293503Sjake 113243971SalfredSYSCTL_UINT(_debug_ktr, OID_AUTO, compile, CTLFLAG_RD, 114243046Sjeff &ktr_compile, 0, "Bitmask of KTR event classes compiled into the kernel"); 115222813Sattilio 116222813Sattiliostatic void 117222813Sattilioktr_cpumask_initializer(void *dummy __unused) 118222813Sattilio{ 119222813Sattilio 120222813Sattilio /* 121222813Sattilio * TUNABLE_STR() runs with SI_ORDER_MIDDLE priority, thus it must be 122222813Sattilio * already set, if necessary. 123222813Sattilio */ 124222813Sattilio if (ktr_cpumask_str[0] != '\0' && 125222813Sattilio cpusetobj_strscan(&ktr_cpumask, ktr_cpumask_str) == -1) 126222813Sattilio CPU_FILL(&ktr_cpumask); 127222813Sattilio} 128222813SattilioSYSINIT(ktr_cpumask_initializer, SI_SUB_TUNABLES, SI_ORDER_ANY, 129222813Sattilio ktr_cpumask_initializer, NULL); 130222813Sattilio 131222813Sattiliostatic int 132222813Sattiliosysctl_debug_ktr_cpumask(SYSCTL_HANDLER_ARGS) 133222813Sattilio{ 134222813Sattilio char lktr_cpumask_str[CPUSETBUFSIZ]; 135222813Sattilio cpuset_t imask; 136222813Sattilio int error; 137222813Sattilio 138222813Sattilio cpusetobj_strprint(lktr_cpumask_str, &ktr_cpumask); 139222813Sattilio error = sysctl_handle_string(oidp, lktr_cpumask_str, 140222813Sattilio sizeof(lktr_cpumask_str), req); 141222813Sattilio if (error != 0 || req->newptr == NULL) 142222813Sattilio return (error); 143222813Sattilio if (cpusetobj_strscan(&imask, lktr_cpumask_str) == -1) 144222813Sattilio return (EINVAL); 145222813Sattilio CPU_COPY(&imask, &ktr_cpumask); 146222813Sattilio 147222813Sattilio return (error); 148222813Sattilio} 149222813SattilioSYSCTL_PROC(_debug_ktr, OID_AUTO, cpumask, 150222813Sattilio CTLFLAG_RW | CTLFLAG_MPSAFE | CTLTYPE_STRING, NULL, 0, 151222813Sattilio sysctl_debug_ktr_cpumask, "S", 152222813Sattilio "Bitmask of CPUs on which KTR logging is enabled"); 153222813Sattilio 154154933Sjhbstatic int 155154933Sjhbsysctl_debug_ktr_clear(SYSCTL_HANDLER_ARGS) 156154933Sjhb{ 157154933Sjhb int clear, error; 158154933Sjhb 159154933Sjhb clear = 0; 160154933Sjhb error = sysctl_handle_int(oidp, &clear, 0, req); 161154933Sjhb if (error || !req->newptr) 162154933Sjhb return (error); 163154933Sjhb 164154933Sjhb if (clear) { 165243046Sjeff bzero(ktr_buf, sizeof(*ktr_buf) * ktr_entries); 166154933Sjhb ktr_idx = 0; 167154933Sjhb } 168154933Sjhb 169154933Sjhb return (error); 170154933Sjhb} 171154933SjhbSYSCTL_PROC(_debug_ktr, OID_AUTO, clear, CTLTYPE_INT|CTLFLAG_RW, 0, 0, 172154933Sjhb sysctl_debug_ktr_clear, "I", "Clear KTR Buffer"); 173154933Sjhb 174243046Sjeff/* 175243046Sjeff * This is a sysctl proc so that it is serialized as !MPSAFE along with 176243046Sjeff * the other ktr sysctl procs. 177243046Sjeff */ 178243046Sjeffstatic int 179243046Sjeffsysctl_debug_ktr_mask(SYSCTL_HANDLER_ARGS) 180243046Sjeff{ 181243046Sjeff int mask, error; 182243046Sjeff 183243046Sjeff mask = ktr_mask; 184243046Sjeff error = sysctl_handle_int(oidp, &mask, 0, req); 185243046Sjeff if (error || !req->newptr) 186243046Sjeff return (error); 187243046Sjeff ktr_mask = mask; 188243046Sjeff return (error); 189243046Sjeff} 190243046Sjeff 191243971SalfredSYSCTL_PROC(_debug_ktr, OID_AUTO, mask, CTLTYPE_UINT|CTLFLAG_RW, 0, 0, 192243971Salfred sysctl_debug_ktr_mask, "IU", 193243046Sjeff "Bitmask of KTR event classes for which logging is enabled"); 194243046Sjeff 195246331Savg#if KTR_ENTRIES > KTR_BOOT_ENTRIES 196246282Savg/* 197246282Savg * A simplified version of sysctl_debug_ktr_entries. 198246282Savg * No need to care about SMP, scheduling, etc. 199246282Savg */ 200246282Savgstatic void 201246282Savgktr_entries_initializer(void *dummy __unused) 202246282Savg{ 203246282Savg int mask; 204246282Savg 205246282Savg /* Temporarily disable ktr in case malloc() is being traced. */ 206246282Savg mask = ktr_mask; 207246282Savg ktr_mask = 0; 208246282Savg ktr_buf = malloc(sizeof(*ktr_buf) * KTR_ENTRIES, M_KTR, 209246282Savg M_WAITOK | M_ZERO); 210246530Savg memcpy(ktr_buf, ktr_buf_init + ktr_idx, 211246530Savg (KTR_BOOT_ENTRIES - ktr_idx) * sizeof(*ktr_buf)); 212246530Savg if (ktr_idx != 0) 213246530Savg memcpy(ktr_buf + KTR_BOOT_ENTRIES - ktr_idx, ktr_buf_init, 214246530Savg ktr_idx * sizeof(*ktr_buf)); 215246282Savg ktr_entries = KTR_ENTRIES; 216246282Savg ktr_mask = mask; 217246282Savg} 218246282SavgSYSINIT(ktr_entries_initializer, SI_SUB_KMEM, SI_ORDER_ANY, 219246282Savg ktr_entries_initializer, NULL); 220246282Savg#endif 221246282Savg 222243046Sjeffstatic int 223243046Sjeffsysctl_debug_ktr_entries(SYSCTL_HANDLER_ARGS) 224243046Sjeff{ 225243046Sjeff int entries, error, mask; 226243046Sjeff struct ktr_entry *buf, *oldbuf; 227243046Sjeff 228243046Sjeff entries = ktr_entries; 229243046Sjeff error = sysctl_handle_int(oidp, &entries, 0, req); 230243046Sjeff if (error || !req->newptr) 231243046Sjeff return (error); 232243046Sjeff if (entries > KTR_ENTRIES_MAX) 233243046Sjeff return (ERANGE); 234243046Sjeff /* Disable ktr temporarily. */ 235243046Sjeff mask = ktr_mask; 236243046Sjeff atomic_store_rel_int(&ktr_mask, 0); 237243046Sjeff /* Wait for threads to go idle. */ 238243046Sjeff if ((error = quiesce_all_cpus("ktrent", PCATCH)) != 0) { 239243046Sjeff ktr_mask = mask; 240243046Sjeff return (error); 241243046Sjeff } 242243046Sjeff if (ktr_buf != ktr_buf_init) 243243046Sjeff oldbuf = ktr_buf; 244243046Sjeff else 245243046Sjeff oldbuf = NULL; 246243046Sjeff /* Allocate a new buffer. */ 247243046Sjeff buf = malloc(sizeof(*buf) * entries, M_KTR, M_WAITOK | M_ZERO); 248243046Sjeff /* Install the new buffer and restart ktr. */ 249243046Sjeff ktr_buf = buf; 250243046Sjeff ktr_entries = entries; 251243046Sjeff ktr_idx = 0; 252243046Sjeff atomic_store_rel_int(&ktr_mask, mask); 253243046Sjeff if (oldbuf != NULL) 254243046Sjeff free(oldbuf, M_KTR); 255243046Sjeff 256243046Sjeff return (error); 257243046Sjeff} 258243046Sjeff 259243046SjeffSYSCTL_PROC(_debug_ktr, OID_AUTO, entries, CTLTYPE_INT|CTLFLAG_RW, 0, 0, 260243046Sjeff sysctl_debug_ktr_entries, "I", "Number of entries in the KTR buffer"); 261243046Sjeff 26293503Sjake#ifdef KTR_VERBOSE 26393503Sjakeint ktr_verbose = KTR_VERBOSE; 26477900SpeterTUNABLE_INT("debug.ktr.verbose", &ktr_verbose); 26570705SjhbSYSCTL_INT(_debug_ktr, OID_AUTO, verbose, CTLFLAG_RW, &ktr_verbose, 0, ""); 26693503Sjake#endif 26768420Sjhb 268103787Sjeff#ifdef KTR_ALQ 269103787Sjeffstruct alq *ktr_alq; 270103787Sjeffchar ktr_alq_file[MAXPATHLEN] = "/tmp/ktr.out"; 271103787Sjeffint ktr_alq_cnt = 0; 272103787Sjeffint ktr_alq_depth = KTR_ENTRIES; 273103787Sjeffint ktr_alq_enabled = 0; 274103787Sjeffint ktr_alq_failed = 0; 275103787Sjeffint ktr_alq_max = 0; 276103787Sjeff 277103787SjeffSYSCTL_INT(_debug_ktr, OID_AUTO, alq_max, CTLFLAG_RW, &ktr_alq_max, 0, 278103787Sjeff "Maximum number of entries to write"); 279103787SjeffSYSCTL_INT(_debug_ktr, OID_AUTO, alq_cnt, CTLFLAG_RD, &ktr_alq_cnt, 0, 280103787Sjeff "Current number of written entries"); 281103787SjeffSYSCTL_INT(_debug_ktr, OID_AUTO, alq_failed, CTLFLAG_RD, &ktr_alq_failed, 0, 282103787Sjeff "Number of times we overran the buffer"); 283103787SjeffSYSCTL_INT(_debug_ktr, OID_AUTO, alq_depth, CTLFLAG_RW, &ktr_alq_depth, 0, 284103787Sjeff "Number of items in the write buffer"); 285103787SjeffSYSCTL_STRING(_debug_ktr, OID_AUTO, alq_file, CTLFLAG_RW, ktr_alq_file, 286103787Sjeff sizeof(ktr_alq_file), "KTR logging file"); 287103787Sjeff 288103787Sjeffstatic int 289103787Sjeffsysctl_debug_ktr_alq_enable(SYSCTL_HANDLER_ARGS) 290103787Sjeff{ 291103787Sjeff int error; 292103787Sjeff int enable; 293103787Sjeff 294103787Sjeff enable = ktr_alq_enabled; 295103787Sjeff 296154940Sjhb error = sysctl_handle_int(oidp, &enable, 0, req); 297154940Sjhb if (error || !req->newptr) 298154940Sjhb return (error); 299103787Sjeff 300103787Sjeff if (enable) { 301103787Sjeff if (ktr_alq_enabled) 302103787Sjeff return (0); 303116697Srwatson error = alq_open(&ktr_alq, (const char *)ktr_alq_file, 304145142Srwatson req->td->td_ucred, ALQ_DEFAULT_CMODE, 305145142Srwatson sizeof(struct ktr_entry), ktr_alq_depth); 306103787Sjeff if (error == 0) { 307103787Sjeff ktr_alq_cnt = 0; 308103787Sjeff ktr_alq_failed = 0; 309103787Sjeff ktr_alq_enabled = 1; 310103787Sjeff } 311103787Sjeff } else { 312103787Sjeff if (ktr_alq_enabled == 0) 313103787Sjeff return (0); 314103787Sjeff ktr_alq_enabled = 0; 315103787Sjeff alq_close(ktr_alq); 316103787Sjeff ktr_alq = NULL; 317103787Sjeff } 318103787Sjeff 319103787Sjeff return (error); 320103787Sjeff} 321103787SjeffSYSCTL_PROC(_debug_ktr, OID_AUTO, alq_enable, 322103787Sjeff CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_debug_ktr_alq_enable, 323103787Sjeff "I", "Enable KTR logging"); 324103787Sjeff#endif 325103787Sjeff 32668420Sjhbvoid 32793503Sjakektr_tracepoint(u_int mask, const char *file, int line, const char *format, 32893503Sjake u_long arg1, u_long arg2, u_long arg3, u_long arg4, u_long arg5, 32993503Sjake u_long arg6) 33068420Sjhb{ 33168420Sjhb struct ktr_entry *entry; 332103787Sjeff#ifdef KTR_ALQ 333103787Sjeff struct ale *ale = NULL; 334206632Sjulian#endif 33574903Sjhb int newindex, saveindex; 336103787Sjeff#if defined(KTR_VERBOSE) || defined(KTR_ALQ) 33787793Sjhb struct thread *td; 33893503Sjake#endif 33991904Sjhb int cpu; 34068420Sjhb 34169880Sjhb if (panicstr) 34269880Sjhb return; 343243046Sjeff if ((ktr_mask & mask) == 0 || ktr_buf == NULL) 34468420Sjhb return; 34593503Sjake cpu = KTR_CPU; 346222813Sattilio if (!CPU_ISSET(cpu, &ktr_cpumask)) 34793503Sjake return; 348103787Sjeff#if defined(KTR_VERBOSE) || defined(KTR_ALQ) 34987793Sjhb td = curthread; 350116101Sjhb if (td->td_pflags & TDP_INKTR) 35187793Sjhb return; 352116101Sjhb td->td_pflags |= TDP_INKTR; 35393503Sjake#endif 354103787Sjeff#ifdef KTR_ALQ 355206632Sjulian if (ktr_alq_enabled) { 356206632Sjulian if (td->td_critnest == 0 && 357206632Sjulian (td->td_flags & TDF_IDLETD) == 0 && 358206632Sjulian td != ald_thread) { 359206632Sjulian if (ktr_alq_max && ktr_alq_cnt > ktr_alq_max) 360206632Sjulian goto done; 361206632Sjulian if ((ale = alq_get(ktr_alq, ALQ_NOWAIT)) == NULL) { 362206632Sjulian ktr_alq_failed++; 363206632Sjulian goto done; 364206632Sjulian } 365206632Sjulian ktr_alq_cnt++; 366206632Sjulian entry = (struct ktr_entry *)ale->ae_data; 367206632Sjulian } else { 368103787Sjeff goto done; 369103787Sjeff } 370103787Sjeff } else 371103787Sjeff#endif 372206632Sjulian { 373206632Sjulian do { 374206632Sjulian saveindex = ktr_idx; 375243046Sjeff newindex = (saveindex + 1) % ktr_entries; 376206632Sjulian } while (atomic_cmpset_rel_int(&ktr_idx, saveindex, newindex) == 0); 377206632Sjulian entry = &ktr_buf[saveindex]; 378206632Sjulian } 37993503Sjake entry->ktr_timestamp = KTR_TIME; 38091904Sjhb entry->ktr_cpu = cpu; 381147278Sjeff entry->ktr_thread = curthread; 382112105Sjhb if (file != NULL) 383112105Sjhb while (strncmp(file, "../", 3) == 0) 384112105Sjhb file += 3; 38593503Sjake entry->ktr_file = file; 38668420Sjhb entry->ktr_line = line; 38793503Sjake#ifdef KTR_VERBOSE 38868420Sjhb if (ktr_verbose) { 38968782Sjhb#ifdef SMP 39093503Sjake printf("cpu%d ", cpu); 39168782Sjhb#endif 39293503Sjake if (ktr_verbose > 1) { 39393503Sjake printf("%s.%d\t", entry->ktr_file, 39493503Sjake entry->ktr_line); 39593503Sjake } 39693503Sjake printf(format, arg1, arg2, arg3, arg4, arg5, arg6); 39768420Sjhb printf("\n"); 39868420Sjhb } 39993503Sjake#endif 40068420Sjhb entry->ktr_desc = format; 40193503Sjake entry->ktr_parms[0] = arg1; 40293503Sjake entry->ktr_parms[1] = arg2; 40393503Sjake entry->ktr_parms[2] = arg3; 40493503Sjake entry->ktr_parms[3] = arg4; 40593503Sjake entry->ktr_parms[4] = arg5; 40693503Sjake entry->ktr_parms[5] = arg6; 407103787Sjeff#ifdef KTR_ALQ 408206632Sjulian if (ktr_alq_enabled && ale) 409103787Sjeff alq_post(ktr_alq, ale); 410103787Sjeffdone: 411103787Sjeff#endif 412103787Sjeff#if defined(KTR_VERBOSE) || defined(KTR_ALQ) 413116101Sjhb td->td_pflags &= ~TDP_INKTR; 41468420Sjhb#endif 41568420Sjhb} 41670035Sjhb 41770035Sjhb#ifdef DDB 41870035Sjhb 41970035Sjhbstruct tstate { 42070035Sjhb int cur; 42170035Sjhb int first; 42270035Sjhb}; 42370035Sjhbstatic struct tstate tstate; 42470035Sjhbstatic int db_ktr_verbose; 42570035Sjhbstatic int db_mach_vtrace(void); 42670035Sjhb 42772755SjhbDB_SHOW_COMMAND(ktr, db_ktr_all) 42870035Sjhb{ 429118269Sjhb 430243046Sjeff tstate.cur = (ktr_idx - 1) % ktr_entries; 43170035Sjhb tstate.first = -1; 432206632Sjulian db_ktr_verbose = 0; 433229272Sed db_ktr_verbose |= (strchr(modif, 'v') != NULL) ? 2 : 0; 434229272Sed db_ktr_verbose |= (strchr(modif, 'V') != NULL) ? 1 : 0; /* just timestap please */ 435229272Sed if (strchr(modif, 'a') != NULL) { 436160312Sjhb db_disable_pager(); 437118269Sjhb while (cncheckc() != -1) 438118269Sjhb if (db_mach_vtrace() == 0) 43972755Sjhb break; 440118269Sjhb } else { 441160312Sjhb while (!db_pager_quit) 442118269Sjhb if (db_mach_vtrace() == 0) 44372755Sjhb break; 444118269Sjhb } 44570035Sjhb} 44670035Sjhb 44770035Sjhbstatic int 44870035Sjhbdb_mach_vtrace(void) 44970035Sjhb{ 45070035Sjhb struct ktr_entry *kp; 45170035Sjhb 452243046Sjeff if (tstate.cur == tstate.first || ktr_buf == NULL) { 45370035Sjhb db_printf("--- End of trace buffer ---\n"); 45470035Sjhb return (0); 45570035Sjhb } 45670035Sjhb kp = &ktr_buf[tstate.cur]; 45770035Sjhb 45870035Sjhb /* Skip over unused entries. */ 45972755Sjhb if (kp->ktr_desc == NULL) { 46072755Sjhb db_printf("--- End of trace buffer ---\n"); 46172755Sjhb return (0); 46272755Sjhb } 463147278Sjeff db_printf("%d (%p", tstate.cur, kp->ktr_thread); 46470035Sjhb#ifdef SMP 465147278Sjeff db_printf(":cpu%d", kp->ktr_cpu); 46670035Sjhb#endif 467147278Sjeff db_printf(")"); 468206632Sjulian if (db_ktr_verbose >= 1) { 469206632Sjulian db_printf(" %10.10lld", (long long)kp->ktr_timestamp); 47093503Sjake } 471206632Sjulian if (db_ktr_verbose >= 2) { 472206632Sjulian db_printf(" %s.%d", kp->ktr_file, kp->ktr_line); 473206632Sjulian } 474147278Sjeff db_printf(": "); 47593503Sjake db_printf(kp->ktr_desc, kp->ktr_parms[0], kp->ktr_parms[1], 47693503Sjake kp->ktr_parms[2], kp->ktr_parms[3], kp->ktr_parms[4], 47793503Sjake kp->ktr_parms[5]); 47872755Sjhb db_printf("\n"); 47970035Sjhb 48070035Sjhb if (tstate.first == -1) 48170035Sjhb tstate.first = tstate.cur; 48270035Sjhb 48370035Sjhb if (--tstate.cur < 0) 484243046Sjeff tstate.cur = ktr_entries - 1; 48570035Sjhb 48670035Sjhb return (1); 48770035Sjhb} 48870035Sjhb 48970035Sjhb#endif /* DDB */ 490