Index: share/man/man9/Makefile =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/share/man/man9/Makefile,v retrieving revision 1.310.2.2 diff -u -r1.310.2.2 Makefile --- share/man/man9/Makefile 15 Feb 2008 10:28:46 -0000 1.310.2.2 +++ share/man/man9/Makefile 20 Feb 2008 16:38:07 -0000 @@ -1056,6 +1056,7 @@ stack.9 stack_put.9 \ stack.9 stack_save.9 \ stack.9 stack_sbuf_print.9 \ + stack.9 stack_sbuf_print_ddb.9 \ stack.9 stack_zero.9 MLINKS+=store.9 subyte.9 \ store.9 suswintr.9 \ Index: share/man/man9/stack.9 =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/share/man/man9/stack.9,v retrieving revision 1.5.2.1 diff -u -r1.5.2.1 stack.9 --- share/man/man9/stack.9 4 Dec 2007 15:22:31 -0000 1.5.2.1 +++ share/man/man9/stack.9 17 Jan 2008 17:05:04 -0000 @@ -36,9 +36,9 @@ .Sh SYNOPSIS .In sys/param.h> .In sys/stack.h -.Pp -In kernel configuration files: +In the kernel configuration file: .Cd "options DDB" +.Cd "options STACK" .Ft struct stack * .Fn stack_create "void" .Ft void @@ -54,6 +54,8 @@ .Ft void .Fn stack_sbuf_print "struct sbuf sb*" "struct stack *st" .Ft void +.Fn stack_sbuf_print_ddb "struct sbuf sb*" "struct stack *st" +.Ft void .Fn stack_save "struct stack *st" .Sh DESCRIPTION The @@ -61,12 +63,11 @@ KPI allows querying of kernel stack trace information and the automated generation of kernel stack trace strings for the purposes of debugging and tracing. -.Nm -relies on the presence of -.Xr DDB 4 , -and all use of these functions must be made conditional on -.Nm DDB -being compiled in the kernel. +To use the KPI, at least one of +.Cd "options DDB" +and +.Cd "options STACK" +must be compiled into the kernel. .Pp Each stack trace is described by a .Vt "struct stack" . @@ -74,7 +75,7 @@ must be allocated with .Fn stack_create , which may sleep. -Memory associated with a trace may be freed by calling +Memory associated with a trace is freed by calling .Fn stack_destroy . .Pp A trace of the current kernel thread's call stack may be captured using @@ -82,7 +83,16 @@ .Pp .Fn stack_print may be used to print a stack trace using the kernel -.Xr printf 9 . +.Xr printf 9 , +and may sleep as a result of acquiring +.Xr sx 9 +locks in the kernel linker while looking up symbol names. +In locking-sensitive environments, the unsynchronized +.Fn stack_print_ddb +variant may be invoked. +This function bypasses kernel linker locking, making it usable in +.Xr ddb 4 , +but not in a live system where linker data structures may change. .Pp .Fn stack_sbuf_print may be used to construct a human-readable string, including conversion (where @@ -96,7 +106,13 @@ .Xr sbuf 9 . This function may sleep if an auto-extending .Dv struct sbuf -is used. +is used, or due to kernel linker locking. +In locking-sensitive environments, such as +.Xr ddb 4 , +the unsynchronized +.Fn stack_sbuf_print_ddb +variant may be invoked to avoid kernel linker locking; it should be used with +a fixed-length sbuf. .Pp The utility functions .Nm stack_zero , @@ -105,15 +121,18 @@ .Nm stack_put may be used to manipulate stack data structures directly. .Sh SEE ALSO -.Xr DDB 4 , +.Xr ddb 4 , .Xr printf 9 , -.Xr sbuf 9 +.Xr sbuf 9 , +.Xr sx 9 .Sh AUTHORS .An -nosplit The .Xr stack 9 function suite was created by .An Antoine Brodin . -.Pp -This manual page was written by -.An Robert Watson . +.Xr stack 9 +was extended by +.An Robert Watson +for general-purpose use outside of +.Xr ddb 4 . Index: sys/amd64/amd64/db_trace.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/amd64/amd64/db_trace.c,v retrieving revision 1.80.2.1 diff -u -r1.80.2.1 db_trace.c --- sys/amd64/amd64/db_trace.c 21 Nov 2007 16:38:54 -0000 1.80.2.1 +++ sys/amd64/amd64/db_trace.c 17 Jan 2008 17:06:03 -0000 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -177,18 +178,6 @@ return (1); } -/* - * Stack trace. - */ -#define INKERNEL(va) (((va) >= DMAP_MIN_ADDRESS && (va) < DMAP_MAX_ADDRESS) \ - || ((va) >= KERNBASE && (va) < VM_MAX_KERNEL_ADDRESS)) - -struct amd64_frame { - struct amd64_frame *f_frame; - long f_retaddr; - long f_arg0; -}; - #define NORMAL 0 #define TRAP 1 #define INTERRUPT 2 @@ -505,32 +494,6 @@ ctx->pcb_rip, count)); } -void -stack_save(struct stack *st) -{ - struct amd64_frame *frame; - vm_offset_t callpc; - register_t rbp; - - stack_zero(st); - __asm __volatile("movq %%rbp,%0" : "=r" (rbp)); - frame = (struct amd64_frame *)rbp; - while (1) { - if (!INKERNEL((long)frame)) - break; - callpc = frame->f_retaddr; - if (!INKERNEL(callpc)) - break; - if (stack_put(st, callpc) == -1) - break; - if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= - (vm_offset_t)rbp + KSTACK_PAGES * PAGE_SIZE) - break; - frame = frame->f_frame; - } -} - int amd64_set_watch(watchnum, watchaddr, size, access, d) int watchnum; Index: sys/amd64/amd64/stack_machdep.c =================================================================== RCS file: sys/amd64/amd64/stack_machdep.c diff -N sys/amd64/amd64/stack_machdep.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/amd64/amd64/stack_machdep.c 17 Jan 2008 18:33:02 -0000 @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2005 Antoine Brodin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include +__FBSDID("$FreeBSD: src/sys/amd64/amd64/stack_machdep.c,v 1.1 2007/12/02 20:40:30 rwatson Exp $"); + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +static void +stack_capture(struct stack *st, register_t rbp) +{ + struct amd64_frame *frame; + vm_offset_t callpc; + + stack_zero(st); + frame = (struct amd64_frame *)rbp; + while (1) { + if (!INKERNEL((long)frame)) + break; + callpc = frame->f_retaddr; + if (!INKERNEL(callpc)) + break; + if (stack_put(st, callpc) == -1) + break; + if (frame->f_frame <= frame || + (vm_offset_t)frame->f_frame >= + (vm_offset_t)rbp + KSTACK_PAGES * PAGE_SIZE) + break; + frame = frame->f_frame; + } +} + +void +stack_save_td(struct stack *st, struct thread *td) +{ + register_t rbp; + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + rbp = td->td_pcb->pcb_rbp; + stack_capture(st, rbp); +} + +void +stack_save(struct stack *st) +{ + register_t rbp; + + __asm __volatile("movq %%rbp,%0" : "=r" (rbp)); + stack_capture(st, rbp); +} Index: sys/amd64/include/stack.h =================================================================== RCS file: sys/amd64/include/stack.h diff -N sys/amd64/include/stack.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/amd64/include/stack.h 17 Jan 2008 18:33:21 -0000 @@ -0,0 +1,44 @@ +/*- + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + * + * $FreeBSD: src/sys/amd64/include/stack.h,v 1.1 2007/12/02 20:40:31 rwatson Exp $ + */ + +#ifndef _MACHINE_STACK_H_ +#define _MACHINE_STACK_H_ + +/* + * Stack trace. + */ +#define INKERNEL(va) (((va) >= DMAP_MIN_ADDRESS && (va) < DMAP_MAX_ADDRESS) \ + || ((va) >= KERNBASE && (va) < VM_MAX_KERNEL_ADDRESS)) + +struct amd64_frame { + struct amd64_frame *f_frame; + long f_retaddr; + long f_arg0; +}; + +#endif /* !_MACHINE_STACK_H_ */ Index: sys/arm/arm/db_trace.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/arm/arm/db_trace.c,v retrieving revision 1.13 diff -u -r1.13 db_trace.c --- sys/arm/arm/db_trace.c 12 Jul 2006 21:22:42 -0000 1.13 +++ sys/arm/arm/db_trace.c 17 Jan 2008 18:33:59 -0000 @@ -43,14 +43,13 @@ #include #include #include +#include #include #include #include #include #include -#define INKERNEL(va) (((vm_offset_t)(va)) >= VM_MIN_KERNEL_ADDRESS) - /* * APCS stack frames are awkward beasts, so I don't think even trying to use * a structure to represent them is a good idea. @@ -79,11 +78,6 @@ * fields are actually present. */ -#define FR_SCP (0) -#define FR_RLV (-1) -#define FR_RSP (-2) -#define FR_RFP (-3) - static void db_stack_trace_cmd(db_expr_t addr, db_expr_t count) { @@ -215,21 +209,3 @@ { db_trace_thread(curthread, -1); } - -void -stack_save(struct stack *st) -{ - vm_offset_t callpc; - u_int32_t *frame; - - stack_zero(st); - frame = (u_int32_t *)__builtin_frame_address(0); - while (1) { - if (!INKERNEL(frame)) - break; - callpc = frame[FR_SCP]; - if (stack_put(st, callpc) == -1) - break; - frame = (u_int32_t *)(frame[FR_RFP]); - } -} Index: sys/arm/arm/stack_machdep.c =================================================================== RCS file: sys/arm/arm/stack_machdep.c diff -N sys/arm/arm/stack_machdep.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arm/arm/stack_machdep.c 17 Jan 2008 18:34:19 -0000 @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2005 Antoine Brodin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include +__FBSDID("$FreeBSD: src/sys/arm/arm/stack_machdep.c,v 1.1 2007/12/02 20:40:31 rwatson Exp $"); + +#include +#include +#include +#include + +#include +#include +#include + +static void +stack_capture(struct stack *st, u_int32_t *frame) +{ + vm_offset_t callpc; + + stack_zero(st); + while (1) { + if (!INKERNEL(frame)) + break; + callpc = frame[FR_SCP]; + if (stack_put(st, callpc) == -1) + break; + frame = (u_int32_t *)(frame[FR_RFP]); + } +} + +void +stack_save_td(struct stack *st, struct thread *td) +{ + u_int32_t *frame; + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + frame = (u_int32_t *)td->td_pcb->un_32.pcb32_r11; + stack_capture(st, frame); +} + +void +stack_save(struct stack *st) +{ + u_int32_t *frame; + + frame = (u_int32_t *)__builtin_frame_address(0); + stack_capture(st, frame); +} Index: sys/arm/include/stack.h =================================================================== RCS file: sys/arm/include/stack.h diff -N sys/arm/include/stack.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arm/include/stack.h 17 Jan 2008 18:34:30 -0000 @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2000, 2001 Ben Harris + * Copyright (c) 1996 Scott K. Stevens + * + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + * + * $FreeBSD: src/sys/arm/include/stack.h,v 1.1 2007/12/02 20:40:31 rwatson Exp $ + */ + +#ifndef _MACHINE_STACK_H_ +#define _MACHINE_STACK_H_ + +#define INKERNEL(va) (((vm_offset_t)(va)) >= VM_MIN_KERNEL_ADDRESS) + +#define FR_SCP (0) +#define FR_RLV (-1) +#define FR_RSP (-2) +#define FR_RFP (-3) + +#endif /* !_MACHINE_STACK_H_ */ Index: sys/conf/NOTES =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/conf/NOTES,v retrieving revision 1.1454 diff -u -r1.1454 NOTES --- sys/conf/NOTES 26 Sep 2007 21:14:17 -0000 1.1454 +++ sys/conf/NOTES 17 Jan 2008 18:34:57 -0000 @@ -471,6 +471,13 @@ # options COMPILING_LINT +# +# STACK enables the stack(9) facility, allowing the capture of kernel stack +# for the purpose of procinfo(1), etc. stack(9) will also be compiled in +# automatically if DDB(4) is compiled into the kernel. +# +options STACK + ##################################################################### # PERFORMANCE MONITORING OPTIONS Index: sys/conf/files =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/conf/files,v retrieving revision 1.1243.2.4 diff -u -r1.1243.2.4 files --- sys/conf/files 14 Feb 2008 18:33:49 -0000 1.1243.2.4 +++ sys/conf/files 20 Feb 2008 16:38:36 -0000 @@ -1503,7 +1503,7 @@ kern/subr_scanf.c standard kern/subr_sleepqueue.c standard kern/subr_smp.c standard -kern/subr_stack.c optional ddb +kern/subr_stack.c optional ddb | stack kern/subr_taskqueue.c standard kern/subr_trap.c standard kern/subr_turnstile.c standard Index: sys/conf/files.amd64 =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/conf/files.amd64,v retrieving revision 1.107.2.5 diff -u -r1.107.2.5 files.amd64 --- sys/conf/files.amd64 3 Feb 2008 07:28:38 -0000 1.107.2.5 +++ sys/conf/files.amd64 20 Feb 2008 16:38:36 -0000 @@ -121,6 +121,7 @@ amd64/amd64/pmap.c standard amd64/amd64/prof_machdep.c optional profiling-routine amd64/amd64/sigtramp.S standard +amd64/amd64/stack_machdep.c optional ddb | stack amd64/amd64/support.S standard amd64/amd64/sys_machdep.c standard amd64/amd64/trap.c standard Index: sys/conf/files.arm =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/conf/files.arm,v retrieving revision 1.15 diff -u -r1.15 files.arm --- sys/conf/files.arm 3 Jul 2007 12:13:42 -0000 1.15 +++ sys/conf/files.arm 17 Jan 2008 18:35:49 -0000 @@ -38,6 +38,7 @@ arm/arm/pmap.c standard arm/arm/setcpsr.S standard arm/arm/setstack.s standard +arm/arm/stack_machdep.c optional ddb | stack arm/arm/support.S standard arm/arm/swtch.S standard arm/arm/sys_machdep.c standard Index: sys/conf/files.i386 =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/conf/files.i386,v retrieving revision 1.580.2.5 diff -u -r1.580.2.5 files.i386 --- sys/conf/files.i386 3 Feb 2008 07:28:38 -0000 1.580.2.5 +++ sys/conf/files.i386 20 Feb 2008 16:38:36 -0000 @@ -298,6 +298,7 @@ i386/i386/perfmon.c optional perfmon i386/i386/pmap.c standard i386/i386/ptrace_machdep.c standard +i386/i386/stack_machdep.c optional ddb | stack i386/i386/support.s standard i386/i386/swtch.s standard i386/i386/sys_machdep.c standard Index: sys/conf/files.ia64 =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/conf/files.ia64,v retrieving revision 1.92 diff -u -r1.92 files.ia64 --- sys/conf/files.ia64 3 Jul 2007 12:13:42 -0000 1.92 +++ sys/conf/files.ia64 17 Jan 2008 18:58:06 -0000 @@ -98,6 +98,7 @@ ia64/ia64/setjmp.S standard ia64/ia64/ssc.c optional ski ia64/ia64/sscdisk.c optional ski +ia64/ia64/stack_machdep.c optional ddb | stack ia64/ia64/support.S standard ia64/ia64/sys_machdep.c standard ia64/ia64/syscall.S standard Index: sys/conf/files.pc98 =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/conf/files.pc98,v retrieving revision 1.356 diff -u -r1.356 files.pc98 --- sys/conf/files.pc98 3 Jul 2007 12:13:42 -0000 1.356 +++ sys/conf/files.pc98 17 Jan 2008 19:31:23 -0000 @@ -177,6 +177,7 @@ i386/i386/perfmon.c optional perfmon i386/i386/pmap.c standard i386/i386/ptrace_machdep.c standard +i386/i386/stack_machdep.c optional ddb | stack i386/i386/support.s standard i386/i386/swtch.s standard i386/i386/sys_machdep.c standard Index: sys/conf/files.powerpc =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/conf/files.powerpc,v retrieving revision 1.65 diff -u -r1.65 files.powerpc --- sys/conf/files.powerpc 3 Jul 2007 12:13:42 -0000 1.65 +++ sys/conf/files.powerpc 17 Jan 2008 18:58:21 -0000 @@ -61,6 +61,7 @@ powerpc/powerpc/sc_machdep.c optional sc powerpc/powerpc/setjmp.S standard powerpc/powerpc/sigcode.S standard +powerpc/powerpc/stack_machdep.c optional ddb | stack powerpc/powerpc/suswintr.c standard powerpc/powerpc/syncicache.c standard powerpc/powerpc/sys_machdep.c standard Index: sys/conf/files.sparc64 =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/conf/files.sparc64,v retrieving revision 1.92 diff -u -r1.92 files.sparc64 --- sys/conf/files.sparc64 3 Jul 2007 12:13:42 -0000 1.92 +++ sys/conf/files.sparc64 17 Jan 2008 18:58:30 -0000 @@ -124,6 +124,7 @@ sparc64/sparc64/rwindow.c standard sparc64/sparc64/sc_machdep.c optional sc sparc64/sparc64/spitfire.c standard +sparc64/sparc64/stack_machdep.c optional ddb | stack sparc64/sparc64/support.S standard sparc64/sparc64/sys_machdep.c standard sparc64/sparc64/swtch.S standard Index: sys/conf/files.sun4v =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/conf/files.sun4v,v retrieving revision 1.11 diff -u -r1.11 files.sun4v --- sys/conf/files.sun4v 3 Jul 2007 12:13:42 -0000 1.11 +++ sys/conf/files.sun4v 17 Jan 2008 19:00:35 -0000 @@ -74,6 +74,7 @@ sparc64/sparc64/rwindow.c standard sun4v/sun4v/rtc.c standard sun4v/sun4v/simdisk.c optional simulator +sun4v/sun4v/stack_machdep.c optional ddb | stack sun4v/sun4v/support.S standard sparc64/sparc64/sys_machdep.c standard sun4v/sun4v/swtch.S standard Index: sys/conf/options =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/conf/options,v retrieving revision 1.608 diff -u -r1.608 options --- sys/conf/options 23 Sep 2007 07:34:23 -0000 1.608 +++ sys/conf/options 17 Jan 2008 19:00:48 -0000 @@ -141,6 +141,7 @@ SLEEPQUEUE_PROFILING SLHCI_DEBUG opt_slhci.h SPX_HACK +STACK opt_stack.h SUIDDIR MSGMNB opt_sysvipc.h MSGMNI opt_sysvipc.h Index: sys/i386/conf/GENERIC =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/i386/conf/GENERIC,v retrieving revision 1.474.2.3 diff -u -r1.474.2.3 GENERIC --- sys/i386/conf/GENERIC 3 Feb 2008 07:28:37 -0000 1.474.2.3 +++ sys/i386/conf/GENERIC 20 Feb 2008 16:39:33 -0000 @@ -54,6 +54,7 @@ options COMPAT_FREEBSD6 # Compatible with FreeBSD6 options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support +options STACK # stack(9) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores Index: sys/i386/i386/db_trace.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/i386/i386/db_trace.c,v retrieving revision 1.79 diff -u -r1.79 db_trace.c --- sys/i386/i386/db_trace.c 19 Feb 2007 10:57:47 -0000 1.79 +++ sys/i386/i386/db_trace.c 17 Jan 2008 19:02:34 -0000 @@ -31,13 +31,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include @@ -166,18 +166,6 @@ return (1); } -/* - * Stack trace. - */ -#define INKERNEL(va) (((vm_offset_t)(va)) >= USRSTACK && \ - ((vm_offset_t)(va)) < VM_MAX_KERNEL_ADDRESS) - -struct i386_frame { - struct i386_frame *f_frame; - int f_retaddr; - int f_arg0; -}; - #define NORMAL 0 #define TRAP 1 #define INTERRUPT 2 @@ -537,32 +525,6 @@ ctx->pcb_eip, count)); } -void -stack_save(struct stack *st) -{ - struct i386_frame *frame; - vm_offset_t callpc; - register_t ebp; - - stack_zero(st); - __asm __volatile("movl %%ebp,%0" : "=r" (ebp)); - frame = (struct i386_frame *)ebp; - while (1) { - if (!INKERNEL(frame)) - break; - callpc = frame->f_retaddr; - if (!INKERNEL(callpc)) - break; - if (stack_put(st, callpc) == -1) - break; - if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= - (vm_offset_t)ebp + KSTACK_PAGES * PAGE_SIZE) - break; - frame = frame->f_frame; - } -} - int i386_set_watch(watchnum, watchaddr, size, access, d) int watchnum; Index: sys/i386/i386/stack_machdep.c =================================================================== RCS file: sys/i386/i386/stack_machdep.c diff -N sys/i386/i386/stack_machdep.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/i386/i386/stack_machdep.c 17 Jan 2008 19:28:20 -0000 @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2005 Antoine Brodin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/stack_machdep.c,v 1.2 2007/12/02 21:07:49 rwatson Exp $"); + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +static void +stack_capture(struct stack *st, register_t ebp) +{ + struct i386_frame *frame; + vm_offset_t callpc; + + stack_zero(st); + frame = (struct i386_frame *)ebp; + while (1) { + if (!INKERNEL(frame)) + break; + callpc = frame->f_retaddr; + if (!INKERNEL(callpc)) + break; + if (stack_put(st, callpc) == -1) + break; + if (frame->f_frame <= frame || + (vm_offset_t)frame->f_frame >= + (vm_offset_t)ebp + KSTACK_PAGES * PAGE_SIZE) + break; + frame = frame->f_frame; + } +} + +void +stack_save_td(struct stack *st, struct thread *td) +{ + register_t ebp; + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + ebp = td->td_pcb->pcb_ebp; + stack_capture(st, ebp); +} + +void +stack_save(struct stack *st) +{ + register_t ebp; + + __asm __volatile("movl %%ebp,%0" : "=r" (ebp)); + stack_capture(st, ebp); +} Index: sys/i386/include/stack.h =================================================================== RCS file: sys/i386/include/stack.h diff -N sys/i386/include/stack.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/i386/include/stack.h 17 Jan 2008 19:03:12 -0000 @@ -0,0 +1,44 @@ +/*- + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + * + * $FreeBSD: src/sys/i386/include/stack.h,v 1.1 2007/12/02 20:40:32 rwatson Exp $ + */ + +#ifndef _MACHINE_STACK_H_ +#define _MACHINE_STACK_H_ + +/* + * Stack trace. + */ +#define INKERNEL(va) (((vm_offset_t)(va)) >= USRSTACK && \ + ((vm_offset_t)(va)) < VM_MAX_KERNEL_ADDRESS) + +struct i386_frame { + struct i386_frame *f_frame; + int f_retaddr; + int f_arg0; +}; + +#endif /* !_MACHINE_STACK_H_ */ Index: sys/ia64/conf/GENERIC =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/ia64/conf/GENERIC,v retrieving revision 1.92 diff -u -r1.92 GENERIC --- sys/ia64/conf/GENERIC 26 Sep 2007 20:05:07 -0000 1.92 +++ sys/ia64/conf/GENERIC 17 Jan 2008 19:03:33 -0000 @@ -50,6 +50,7 @@ options SMP # Symmetric Multi-Processor support options SOFTUPDATES # Enable FFS soft updates support options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options STACK # stack(9) support options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options SYSVSHM # SYSV-style shared memory Index: sys/ia64/ia64/db_machdep.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/ia64/ia64/db_machdep.c,v retrieving revision 1.4 diff -u -r1.4 db_machdep.c --- sys/ia64/ia64/db_machdep.c 30 Jul 2007 22:42:33 -0000 1.4 +++ sys/ia64/ia64/db_machdep.c 17 Jan 2008 19:07:39 -0000 @@ -595,18 +595,6 @@ return (db_backtrace(td, ctx, count)); } -void -stack_save(struct stack *st) -{ - - stack_zero(st); - /* - * Nothing for now. - * Is libuwx reentrant? - * Can unw_create* sleep? - */ -} - #ifdef EXCEPTION_TRACING extern long xtrace[]; Index: sys/ia64/ia64/stack_machdep.c =================================================================== RCS file: sys/ia64/ia64/stack_machdep.c diff -N sys/ia64/ia64/stack_machdep.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/ia64/ia64/stack_machdep.c 17 Jan 2008 19:07:53 -0000 @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2005 Antoine Brodin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include +__FBSDID("$FreeBSD: src/sys/ia64/ia64/stack_machdep.c,v 1.1 2007/12/02 20:40:33 rwatson Exp $"); + +#include +#include +#include +#include + +void +stack_save_td(struct stack *st, struct thread *td) +{ + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + stack_zero(st); +} + +void +stack_save(struct stack *st) +{ + + stack_zero(st); + /* + * Nothing for now. + * Is libuwx reentrant? + * Can unw_create* sleep? + */ +} Index: sys/kern/kern_descrip.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.313.2.1 diff -u -r1.313.2.1 kern_descrip.c --- sys/kern/kern_descrip.c 14 Feb 2008 11:44:59 -0000 1.313.2.1 +++ sys/kern/kern_descrip.c 20 Feb 2008 16:39:45 -0000 @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -59,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +70,7 @@ #include #include #include +#include #include #include @@ -2405,7 +2408,7 @@ } /* - * Get file structures. + * Get file structures globally. */ static int sysctl_kern_file(SYSCTL_HANDLER_ARGS) @@ -2488,6 +2491,182 @@ SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD, 0, 0, sysctl_kern_file, "S,xfile", "Entire file table"); +/* + * Get per-process file descriptors for use by procstat(1), et al. + */ +static int +sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS) +{ + char *fullpath, *freepath; + struct kinfo_file *kif; + struct filedesc *fdp; + int error, i, *name; + struct socket *so; + struct vnode *vp; + struct file *fp; + struct proc *p; + int vfslocked; + + name = (int *)arg1; + if ((p = pfind((pid_t)name[0])) == NULL) + return (ESRCH); + if ((error = p_candebug(curthread, p))) { + PROC_UNLOCK(p); + return (error); + } + fdp = fdhold(p); + PROC_UNLOCK(p); + kif = malloc(sizeof(*kif), M_TEMP, M_WAITOK); + FILEDESC_SLOCK(fdp); + for (i = 0; i < fdp->fd_nfiles; i++) { + if ((fp = fdp->fd_ofiles[i]) == NULL) + continue; + bzero(kif, sizeof(*kif)); + kif->kf_structsize = sizeof(*kif); + FILE_LOCK(fp); + vp = NULL; + so = NULL; + kif->kf_fd = i; + switch (fp->f_type) { + case DTYPE_VNODE: + kif->kf_type = KF_TYPE_VNODE; + vp = fp->f_vnode; + vref(vp); + break; + + case DTYPE_SOCKET: + kif->kf_type = KF_TYPE_SOCKET; + so = fp->f_data; + break; + + case DTYPE_PIPE: + kif->kf_type = KF_TYPE_PIPE; + break; + + case DTYPE_FIFO: + kif->kf_type = KF_TYPE_FIFO; + vp = fp->f_vnode; + vref(vp); + break; + + case DTYPE_KQUEUE: + kif->kf_type = KF_TYPE_KQUEUE; + break; + + case DTYPE_CRYPTO: + kif->kf_type = KF_TYPE_CRYPTO; + break; + + case DTYPE_MQUEUE: + kif->kf_type = KF_TYPE_MQUEUE; + break; + + default: + kif->kf_type = KF_TYPE_UNKNOWN; + break; + } + kif->kf_ref_count = fp->f_count; + if (fp->f_flag & FREAD) + kif->kf_flags |= KF_FLAG_READ; + if (fp->f_flag & FWRITE) + kif->kf_flags |= KF_FLAG_WRITE; + if (fp->f_flag & FAPPEND) + kif->kf_flags |= KF_FLAG_APPEND; + if (fp->f_flag & FASYNC) + kif->kf_flags |= KF_FLAG_ASYNC; + if (fp->f_flag & FFSYNC) + kif->kf_flags |= KF_FLAG_FSYNC; + if (fp->f_flag & FNONBLOCK) + kif->kf_flags |= KF_FLAG_NONBLOCK; + if (fp->f_flag & O_DIRECT) + kif->kf_flags |= KF_FLAG_DIRECT; + if (fp->f_flag & FHASLOCK) + kif->kf_flags |= KF_FLAG_HASLOCK; + kif->kf_offset = fp->f_offset; + FILE_UNLOCK(fp); + if (vp != NULL) { + switch (vp->v_type) { + case VNON: + kif->kf_vnode_type = KF_VTYPE_VNON; + break; + case VREG: + kif->kf_vnode_type = KF_VTYPE_VREG; + break; + case VDIR: + kif->kf_vnode_type = KF_VTYPE_VDIR; + break; + case VBLK: + kif->kf_vnode_type = KF_VTYPE_VBLK; + break; + case VCHR: + kif->kf_vnode_type = KF_VTYPE_VCHR; + break; + case VLNK: + kif->kf_vnode_type = KF_VTYPE_VLNK; + break; + case VSOCK: + kif->kf_vnode_type = KF_VTYPE_VSOCK; + break; + case VFIFO: + kif->kf_vnode_type = KF_VTYPE_VFIFO; + break; + case VBAD: + kif->kf_vnode_type = KF_VTYPE_VBAD; + break; + default: + kif->kf_vnode_type = KF_VTYPE_UNKNOWN; + break; + } + /* + * It is OK to drop the filedesc lock here as we will + * re-validate and re-evaluate its properties when + * the loop continues. + */ + freepath = NULL; + fullpath = "-"; + FILEDESC_SUNLOCK(fdp); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread); + vn_fullpath(curthread, vp, &fullpath, &freepath); + vput(vp); + VFS_UNLOCK_GIANT(vfslocked); + strlcpy(kif->kf_path, fullpath, + sizeof(kif->kf_path)); + if (freepath != NULL) + free(freepath, M_TEMP); + FILEDESC_SLOCK(fdp); + } + if (so != NULL) { + struct sockaddr *sa; + + if (so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa) + == 0 && sa->sa_len <= sizeof(kif->kf_sa_local)) { + bcopy(sa, &kif->kf_sa_local, sa->sa_len); + free(sa, M_SONAME); + } + if (so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa) + == 00 && sa->sa_len <= sizeof(kif->kf_sa_peer)) { + bcopy(sa, &kif->kf_sa_peer, sa->sa_len); + free(sa, M_SONAME); + } + kif->kf_sock_domain = + so->so_proto->pr_domain->dom_family; + kif->kf_sock_type = so->so_type; + kif->kf_sock_protocol = so->so_proto->pr_protocol; + } + error = SYSCTL_OUT(req, kif, sizeof(*kif)); + if (error) + break; + } + FILEDESC_SUNLOCK(fdp); + fddrop(fdp); + free(kif, M_TEMP); + return (0); +} + +static SYSCTL_NODE(_kern_proc, KERN_PROC_FILEDESC, filedesc, CTLFLAG_RD, + sysctl_kern_proc_filedesc, "Process filedesc entries"); + #ifdef DDB /* * For the purposes of debugging, generate a human-readable string for the Index: sys/kern/kern_linker.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/kern/kern_linker.c,v retrieving revision 1.149 diff -u -r1.149 kern_linker.c --- sys/kern/kern_linker.c 31 May 2007 11:51:51 -0000 1.149 +++ sys/kern/kern_linker.c 17 Jan 2008 17:01:30 -0000 @@ -767,18 +767,18 @@ return (0); } -#ifdef DDB /* - * DDB Helpers. DDB has to look across multiple files with their own symbol - * tables and string tables. + * Both DDB and stack(9) rely on the kernel linker to provide forward and + * backward lookup of symbols. However, DDB and sometimes stack(9) need to + * do this in a lockfree manner. We provide a set of internal helper + * routines to perform these operations without locks, and then wrappers that + * optionally lock. * - * Note that we do not obey list locking protocols here. We really don't need - * DDB to hang because somebody's got the lock held. We'll take the chance - * that the files list is inconsistant instead. + * linker_debug_lookup() is ifdef DDB as currently it's only used by DDB. */ - -int -linker_ddb_lookup(const char *symstr, c_linker_sym_t *sym) +#ifdef DDB +static int +linker_debug_lookup(const char *symstr, c_linker_sym_t *sym) { linker_file_t lf; @@ -788,9 +788,10 @@ } return (ENOENT); } +#endif -int -linker_ddb_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp) +static int +linker_debug_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp) { linker_file_t lf; c_linker_sym_t best, es; @@ -820,8 +821,8 @@ } } -int -linker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval) +static int +linker_debug_symbol_values(c_linker_sym_t sym, linker_symval_t *symval) { linker_file_t lf; @@ -831,9 +832,82 @@ } return (ENOENT); } + +static int +linker_debug_search_symbol_name(caddr_t value, char *buf, u_int buflen, + long *offset) +{ + linker_symval_t symval; + c_linker_sym_t sym; + int error; + + *offset = 0; + error = linker_debug_search_symbol(value, &sym, offset); + if (error) + return (error); + error = linker_debug_symbol_values(sym, &symval); + if (error) + return (error); + strlcpy(buf, symval.name, buflen); + return (0); +} + +#ifdef DDB +/* + * DDB Helpers. DDB has to look across multiple files with their own symbol + * tables and string tables. + * + * Note that we do not obey list locking protocols here. We really don't need + * DDB to hang because somebody's got the lock held. We'll take the chance + * that the files list is inconsistant instead. + */ +int +linker_ddb_lookup(const char *symstr, c_linker_sym_t *sym) +{ + + return (linker_debug_lookup(symstr, sym)); +} + +int +linker_ddb_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp) +{ + + return (linker_debug_search_symbol(value, sym, diffp)); +} + +int +linker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval) +{ + + return (linker_debug_symbol_values(sym, symval)); +} + +int +linker_ddb_search_symbol_name(caddr_t value, char *buf, u_int buflen, + long *offset) +{ + + return (linker_debug_search_symbol_name(value, buf, buflen, offset)); +} #endif /* + * stack(9) helper for non-debugging environemnts. Unlike DDB helpers, we do + * obey locking protocols, and offer a significantly less complex interface. + */ +int +linker_search_symbol_name(caddr_t value, char *buf, u_int buflen, + long *offset) +{ + int error; + + KLD_LOCK(); + error = linker_debug_search_symbol_name(value, buf, buflen, offset); + KLD_UNLOCK(); + return (error); +} + +/* * Syscalls. */ int Index: sys/kern/kern_lock.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/kern/kern_lock.c,v retrieving revision 1.110 diff -u -r1.110 kern_lock.c --- sys/kern/kern_lock.c 18 May 2007 15:04:59 -0000 1.110 +++ sys/kern/kern_lock.c 17 Jan 2008 17:02:30 -0000 @@ -644,7 +644,7 @@ if (lkp->lk_waitcount > 0) printf(" with %d pending", lkp->lk_waitcount); #ifdef DEBUG_LOCKS - stack_print(&lkp->lk_stack); + stack_print_ddb(&lkp->lk_stack); #endif } Index: sys/kern/kern_proc.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/kern/kern_proc.c,v retrieving revision 1.252.2.3 diff -u -r1.252.2.3 kern_proc.c --- sys/kern/kern_proc.c 18 Jan 2008 10:02:51 -0000 1.252.2.3 +++ sys/kern/kern_proc.c 31 Jan 2008 08:55:50 -0000 @@ -32,20 +32,25 @@ #include __FBSDID("$FreeBSD: src/sys/kern/kern_proc.c,v 1.252.2.3 2008/01/18 10:02:51 kib Exp $"); +#include "opt_ddb.h" #include "opt_ktrace.h" #include "opt_kstack_pages.h" +#include "opt_stack.h" #include #include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include @@ -60,10 +65,15 @@ #include #endif +#ifdef DDB +#include +#endif + #include #include #include #include +#include #include MALLOC_DEFINE(M_PGRP, "pgrp", "process group header"); @@ -1285,8 +1295,264 @@ return (sysctl_handle_string(oidp, sv_name, 0, req)); } +static int +sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS) +{ + vm_map_entry_t entry, tmp_entry; + unsigned int last_timestamp; + char *fullpath, *freepath; + struct kinfo_vmentry *kve; + int error, *name; + struct vnode *vp; + struct proc *p; + vm_map_t map; + + name = (int *)arg1; + if ((p = pfind((pid_t)name[0])) == NULL) + return (ESRCH); + /* XXXRW: Not clear ESRCH is the right error during proc execve(). */ + if (p->p_flag & P_WEXIT || p->p_flag & P_INEXEC) { + PROC_UNLOCK(p); + return (ESRCH); + } + if ((error = p_candebug(curthread, p))) { + PROC_UNLOCK(p); + return (error); + } + _PHOLD(p); + PROC_UNLOCK(p); + + kve = malloc(sizeof(*kve), M_TEMP, M_WAITOK); + + map = &p->p_vmspace->vm_map; /* XXXRW: More locking required? */ + vm_map_lock_read(map); + for (entry = map->header.next; entry != &map->header; + entry = entry->next) { + vm_object_t obj, tobj, lobj; + vm_offset_t addr; + int vfslocked; + + if (entry->eflags & MAP_ENTRY_IS_SUB_MAP) + continue; + + bzero(kve, sizeof(*kve)); + kve->kve_structsize = sizeof(*kve); + + kve->kve_private_resident = 0; + obj = entry->object.vm_object; + if (obj != NULL) { + VM_OBJECT_LOCK(obj); + if (obj->shadow_count == 1) + kve->kve_private_resident = + obj->resident_page_count; + } + kve->kve_resident = 0; + addr = entry->start; + while (addr < entry->end) { + if (pmap_extract(map->pmap, addr)) + kve->kve_resident++; + addr += PAGE_SIZE; + } + + for (lobj = tobj = obj; tobj; tobj = tobj->backing_object) { + if (tobj != obj) + VM_OBJECT_LOCK(tobj); + if (lobj != obj) + VM_OBJECT_UNLOCK(lobj); + lobj = tobj; + } + + freepath = NULL; + fullpath = ""; + if (lobj) { + vp = NULL; + switch(lobj->type) { + case OBJT_DEFAULT: + kve->kve_type = KVME_TYPE_DEFAULT; + break; + case OBJT_VNODE: + kve->kve_type = KVME_TYPE_VNODE; + vp = lobj->handle; + vref(vp); + break; + case OBJT_SWAP: + kve->kve_type = KVME_TYPE_SWAP; + break; + case OBJT_DEVICE: + kve->kve_type = KVME_TYPE_DEVICE; + break; + case OBJT_PHYS: + kve->kve_type = KVME_TYPE_PHYS; + break; + case OBJT_DEAD: + kve->kve_type = KVME_TYPE_DEAD; + break; + default: + kve->kve_type = KVME_TYPE_UNKNOWN; + break; + } + if (lobj != obj) + VM_OBJECT_UNLOCK(lobj); + + kve->kve_ref_count = obj->ref_count; + kve->kve_shadow_count = obj->shadow_count; + VM_OBJECT_UNLOCK(obj); + if (vp != NULL) { + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, + curthread); + vn_fullpath(curthread, vp, &fullpath, + &freepath); + vput(vp); + VFS_UNLOCK_GIANT(vfslocked); + } + } else { + kve->kve_type = KVME_TYPE_NONE; + kve->kve_ref_count = 0; + kve->kve_shadow_count = 0; + } -static SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table"); + kve->kve_start = (void*)entry->start; + kve->kve_end = (void*)entry->end; + + if (entry->protection & VM_PROT_READ) + kve->kve_protection |= KVME_PROT_READ; + if (entry->protection & VM_PROT_WRITE) + kve->kve_protection |= KVME_PROT_WRITE; + if (entry->protection & VM_PROT_EXECUTE) + kve->kve_protection |= KVME_PROT_EXEC; + + if (entry->eflags & MAP_ENTRY_COW) + kve->kve_flags |= KVME_FLAG_COW; + if (entry->eflags & MAP_ENTRY_NEEDS_COPY) + kve->kve_flags |= KVME_FLAG_NEEDS_COPY; + + strlcpy(kve->kve_path, fullpath, sizeof(kve->kve_path)); + if (freepath != NULL) + free(freepath, M_TEMP); + + last_timestamp = map->timestamp; + vm_map_unlock_read(map); + error = SYSCTL_OUT(req, kve, sizeof(*kve)); + vm_map_lock_read(map); + if (error) + break; + if (last_timestamp + 1 != map->timestamp) { + vm_map_lookup_entry(map, addr - 1, &tmp_entry); + entry = tmp_entry; + } + } + vm_map_unlock_read(map); + PRELE(p); + free(kve, M_TEMP); + return (error); +} + +#if defined(STACK) || defined(DDB) +static int +sysctl_kern_proc_kstack(SYSCTL_HANDLER_ARGS) +{ + struct kinfo_kstack *kkstp; + int error, i, *name, numthreads; + lwpid_t *lwpidarray; + struct thread *td; + struct stack *st; + struct sbuf sb; + struct proc *p; + + name = (int *)arg1; + if ((p = pfind((pid_t)name[0])) == NULL) + return (ESRCH); + /* XXXRW: Not clear ESRCH is the right error during proc execve(). */ + if (p->p_flag & P_WEXIT || p->p_flag & P_INEXEC) { + PROC_UNLOCK(p); + return (ESRCH); + } + if ((error = p_candebug(curthread, p))) { + PROC_UNLOCK(p); + return (error); + } + _PHOLD(p); + PROC_UNLOCK(p); + + kkstp = malloc(sizeof(*kkstp), M_TEMP, M_WAITOK); + st = stack_create(); + + lwpidarray = NULL; + numthreads = 0; + PROC_SLOCK(p); +repeat: + if (numthreads < p->p_numthreads) { + if (lwpidarray != NULL) { + free(lwpidarray, M_TEMP); + lwpidarray = NULL; + } + numthreads = p->p_numthreads; + PROC_SUNLOCK(p); + lwpidarray = malloc(sizeof(*lwpidarray) * numthreads, M_TEMP, + M_WAITOK | M_ZERO); + PROC_SLOCK(p); + goto repeat; + } + PROC_SUNLOCK(p); + i = 0; + + /* + * XXXRW: During the below loop, execve(2) and countless other sorts + * of changes could have taken place. Should we check to see if the + * vmspace has been replaced, or the like, in order to prevent + * giving a snapshot that spans, say, execve(2), with some threads + * before and some after? Among other things, the credentials could + * have changed, in which case the right to extract debug info might + * no longer be assured. + */ + PROC_LOCK(p); + FOREACH_THREAD_IN_PROC(p, td) { + KASSERT(i < numthreads, + ("sysctl_kern_proc_kstack: numthreads")); + lwpidarray[i] = td->td_tid; + i++; + } + numthreads = i; + for (i = 0; i < numthreads; i++) { + td = thread_find(p, lwpidarray[i]); + if (td == NULL) { + continue; + } + bzero(kkstp, sizeof(*kkstp)); + (void)sbuf_new(&sb, kkstp->kkst_trace, + sizeof(kkstp->kkst_trace), SBUF_FIXEDLEN); + thread_lock(td); + kkstp->kkst_tid = td->td_tid; + if (TD_IS_SWAPPED(td)) + kkstp->kkst_state = KKST_STATE_SWAPPED; + else if (TD_IS_RUNNING(td)) + kkstp->kkst_state = KKST_STATE_RUNNING; + else { + kkstp->kkst_state = KKST_STATE_STACKOK; + stack_save_td(st, td); + } + thread_unlock(td); + PROC_UNLOCK(p); + stack_sbuf_print(&sb, st); + sbuf_finish(&sb); + sbuf_delete(&sb); + error = SYSCTL_OUT(req, kkstp, sizeof(*kkstp)); + PROC_LOCK(p); + if (error) + break; + } + _PRELE(p); + PROC_UNLOCK(p); + if (lwpidarray != NULL) + free(lwpidarray, M_TEMP); + stack_destroy(st); + free(kkstp, M_TEMP); + return (error); +} +#endif + +SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table"); SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT, 0, 0, sysctl_kern_proc, "S,proc", "Return entire process table"); @@ -1354,3 +1620,11 @@ static SYSCTL_NODE(_kern_proc, (KERN_PROC_PROC | KERN_PROC_INC_THREAD), proc_td, CTLFLAG_RD, sysctl_kern_proc, "Return process table, no threads"); + +static SYSCTL_NODE(_kern_proc, KERN_PROC_VMMAP, vmmap, CTLFLAG_RD, + sysctl_kern_proc_vmmap, "Process vm map entries"); + +#if defined(STACK) || defined(DDB) +static SYSCTL_NODE(_kern_proc, KERN_PROC_KSTACK, kstack, CTLFLAG_RD, + sysctl_kern_proc_kstack, "Process kernel stacks"); +#endif Index: sys/kern/subr_stack.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/kern/subr_stack.c,v retrieving revision 1.3 diff -u -r1.3 subr_stack.c --- sys/kern/subr_stack.c 28 May 2006 22:15:28 -0000 1.3 +++ sys/kern/subr_stack.c 17 Jan 2008 19:31:50 -0000 @@ -24,6 +24,8 @@ * SUCH DAMAGE. */ +#include "opt_ddb.h" + #include __FBSDID("$FreeBSD: src/sys/kern/subr_stack.c,v 1.3 2006/05/28 22:15:28 kris Exp $"); @@ -40,7 +42,12 @@ MALLOC_DEFINE(M_STACK, "stack", "Stack Traces"); -static void stack_symbol(vm_offset_t pc, const char **name, long *offset); +static void stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, + long *offset); +#ifdef DDB +static void stack_symbol_ddb(vm_offset_t pc, char *namebuf, u_int buflen, + long *offset); +#endif struct stack * stack_create(void) @@ -86,30 +93,69 @@ void stack_print(struct stack *st) { - const char *name; + char namebuf[64]; long offset; int i; KASSERT(st->depth <= STACK_MAX, ("bogus stack")); for (i = 0; i < st->depth; i++) { - stack_symbol(st->pcs[i], &name, &offset); + stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), &offset); printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], - name, offset); + namebuf, offset); } } +#ifdef DDB +void +stack_print_ddb(struct stack *st) +{ + char namebuf[64]; + long offset; + int i; + + KASSERT(st->depth <= STACK_MAX, ("bogus stack")); + for (i = 0; i < st->depth; i++) { + stack_symbol_ddb(st->pcs[i], namebuf, sizeof(namebuf), + &offset); + printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], + namebuf, offset); + } +} +#endif + +/* + * Two print routines -- one for use from DDB and DDB-like contexts, the + * other for use in the live kernel. + */ void stack_sbuf_print(struct sbuf *sb, struct stack *st) { - const char *name; + char namebuf[64]; long offset; int i; KASSERT(st->depth <= STACK_MAX, ("bogus stack")); for (i = 0; i < st->depth; i++) { - stack_symbol(st->pcs[i], &name, &offset); + stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), &offset); sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], - name, offset); + namebuf, offset); + } +} + +#ifdef DDB +void +stack_sbuf_print_ddb(struct sbuf *sb, struct stack *st) +{ + char namebuf[64]; + long offset; + int i; + + KASSERT(st->depth <= STACK_MAX, ("bogus stack")); + for (i = 0; i < st->depth; i++) { + stack_symbol_ddb(st->pcs[i], namebuf, sizeof(namebuf), + &offset); + sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], + namebuf, offset); } } @@ -118,7 +164,7 @@ stack_ktr(u_int mask, const char *file, int line, struct stack *st, u_int depth, int cheap) { - const char *name; + char namebuf[64]; long offset; int i; @@ -141,29 +187,40 @@ if (depth == 0 || st->depth < depth) depth = st->depth; for (i = 0; i < depth; i++) { - stack_symbol(st->pcs[i], &name, &offset); + stack_symbol_ddb(st->pcs[i], namebuf, + sizeof(namebuf), &offset); ktr_tracepoint(mask, file, line, "#%d %p at %s+%#lx", - i, st->pcs[i], (u_long)name, offset, 0, 0); + i, st->pcs[i], (u_long)namebuf, offset, 0, 0); } } } #endif +#endif + +/* + * Two variants of stack symbol lookup -- one that uses the DDB interfaces + * and bypasses linker locking, and the other that doesn't. + */ +static void +stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, long *offset) +{ + if (linker_search_symbol_name((caddr_t)pc, namebuf, buflen, + offset) != 0) { + *offset = 0; + strlcpy(namebuf, "??", buflen); + } +} + +#ifdef DDB static void -stack_symbol(vm_offset_t pc, const char **name, long *offset) +stack_symbol_ddb(vm_offset_t pc, char *namebuf, u_int buflen, long *offset) { - linker_symval_t symval; - c_linker_sym_t sym; - if (linker_ddb_search_symbol((caddr_t)pc, &sym, offset) != 0) - goto out; - if (linker_ddb_symbol_values(sym, &symval) != 0) - goto out; - if (symval.name != NULL) { - *name = symval.name; - return; - } -out: - *offset = 0; - *name = "Unknown func"; + if (linker_ddb_search_symbol_name((caddr_t)pc, namebuf, buflen, + offset) != 0) { + *offset = 0; + strlcpy(namebuf, "??", buflen); + }; } +#endif Index: sys/pc98/conf/GENERIC =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/pc98/conf/GENERIC,v retrieving revision 1.297.2.1 diff -u -r1.297.2.1 GENERIC --- sys/pc98/conf/GENERIC 11 Oct 2007 06:20:27 -0000 1.297.2.1 +++ sys/pc98/conf/GENERIC 17 Jan 2008 19:08:30 -0000 @@ -57,6 +57,7 @@ #options EPSON_MEMWIN # EPSON memory window support #options LINE30 options KTRACE # ktrace(1) support +options STACK # stack(9) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores Index: sys/pc98/include/stack.h =================================================================== RCS file: sys/pc98/include/stack.h diff -N sys/pc98/include/stack.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/pc98/include/stack.h 17 Jan 2008 19:31:34 -0000 @@ -0,0 +1,6 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD: src/sys/pc98/include/stack.h,v 1.1 2007/12/03 11:38:28 rwatson Exp $ */ + +#include Index: sys/powerpc/conf/GENERIC =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/powerpc/conf/GENERIC,v retrieving revision 1.71.2.2 diff -u -r1.71.2.2 GENERIC --- sys/powerpc/conf/GENERIC 29 Oct 2007 00:07:03 -0000 1.71.2.2 +++ sys/powerpc/conf/GENERIC 17 Jan 2008 19:20:14 -0000 @@ -55,6 +55,7 @@ options COMPAT_FREEBSD6 #Compatible with FreeBSD6 options SCSI_DELAY=5000 #Delay (in ms) before probing SCSI options KTRACE #ktrace(1) syscall trace support +options STACK #stack(9) support options SYSVSHM #SYSV-style shared memory options SYSVMSG #SYSV-style message queues options SYSVSEM #SYSV-style semaphores Index: sys/powerpc/include/stack.h =================================================================== RCS file: sys/powerpc/include/stack.h diff -N sys/powerpc/include/stack.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/powerpc/include/stack.h 17 Jan 2008 19:20:26 -0000 @@ -0,0 +1,36 @@ +/*- + * Mach Operating System + * Copyright (c) 1992 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + * + * $FreeBSD: src/sys/powerpc/include/stack.h,v 1.1 2007/12/02 20:40:34 rwatson Exp $ + */ + +#ifndef _MACHINE_STACK_H_ +#define _MACHINE_STACK_H_ + +extern int trapexit[]; +extern int asttrapexit[]; +extern int end[]; + +#endif /* !_MACHINE_STACK_H_ */ Index: sys/powerpc/powerpc/db_trace.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/powerpc/powerpc/db_trace.c,v retrieving revision 1.13 diff -u -r1.13 db_trace.c --- sys/powerpc/powerpc/db_trace.c 12 Jul 2006 21:22:44 -0000 1.13 +++ sys/powerpc/powerpc/db_trace.c 17 Jan 2008 19:23:14 -0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -96,10 +97,6 @@ }; struct db_variable *db_eregs = db_regs + sizeof (db_regs)/sizeof (db_regs[0]); -extern int trapexit[]; -extern int asttrapexit[]; -extern int end[]; - /* * register variable handling */ @@ -287,37 +284,3 @@ ctx = kdb_thr_ctx(td); return (db_backtrace(td, (db_addr_t)ctx->pcb_sp, count)); } - -void -stack_save(struct stack *st) -{ - vm_offset_t callpc; - db_addr_t stackframe; - - stack_zero(st); - stackframe = (db_addr_t)__builtin_frame_address(1); - if (stackframe < PAGE_SIZE) - return; - while (1) { - stackframe = *(db_addr_t *)stackframe; - if (stackframe < PAGE_SIZE) - break; - callpc = *(vm_offset_t *)(stackframe + 4) - 4; - if ((callpc & 3) || (callpc < 0x100)) - break; - - /* - * Don't bother traversing trap-frames - there should - * be enough info down to the frame to work out where - * things are going wrong. Plus, prevents this shortened - * version of code from accessing user-space frames - */ - if (callpc + 4 == (db_addr_t) &trapexit || - callpc + 4 == (db_addr_t) &asttrapexit) - break; - - if (stack_put(st, callpc) == -1) - break; - } -} - Index: sys/powerpc/powerpc/stack_machdep.c =================================================================== RCS file: sys/powerpc/powerpc/stack_machdep.c diff -N sys/powerpc/powerpc/stack_machdep.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/powerpc/powerpc/stack_machdep.c 17 Jan 2008 19:23:25 -0000 @@ -0,0 +1,97 @@ +/*- + * Copyright (c) 2005 Antoine Brodin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include +__FBSDID("$FreeBSD: src/sys/powerpc/powerpc/stack_machdep.c,v 1.1 2007/12/02 20:40:34 rwatson Exp $"); + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +static void +stack_capture(struct stack *st, register_t frame) +{ + vm_offset_t callpc; + + stack_zero(st); + if (frame < PAGE_SIZE) + return; + while (1) { + frame = *(register_t *)frame; + if (frame < PAGE_SIZE) + break; + callpc = *(vm_offset_t *)(frame + 4) - 4; + if ((callpc & 3) || (callpc < 0x100)) + break; + + /* + * Don't bother traversing trap-frames - there should + * be enough info down to the frame to work out where + * things are going wrong. Plus, prevents this shortened + * version of code from accessing user-space frames + */ + if (callpc + 4 == (register_t) &trapexit || + callpc + 4 == (register_t) &asttrapexit) + break; + + if (stack_put(st, callpc) == -1) + break; + } +} + +void +stack_save_td(struct stack *st, struct thread *td) +{ + register_t frame; + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + frame = td->td_pcb->pcb_sp; + stack_capture(st, frame); +} + +void +stack_save(struct stack *st) +{ + register_t frame; + + frame = (register_t)__builtin_frame_address(1); + stack_capture(st, frame); +} Index: sys/sparc64/conf/GENERIC =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/sparc64/conf/GENERIC,v retrieving revision 1.127.2.1 diff -u -r1.127.2.1 GENERIC --- sys/sparc64/conf/GENERIC 11 Oct 2007 06:20:27 -0000 1.127.2.1 +++ sys/sparc64/conf/GENERIC 17 Jan 2008 19:24:20 -0000 @@ -56,6 +56,7 @@ options COMPAT_FREEBSD6 # Compatible with FreeBSD6 options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support +options STACK # stack(9) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores Index: sys/sparc64/include/stack.h =================================================================== RCS file: sys/sparc64/include/stack.h diff -N sys/sparc64/include/stack.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sparc64/include/stack.h 17 Jan 2008 19:24:53 -0000 @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2001 Jake Burkholder. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/sys/sparc64/include/stack.h,v 1.1 2007/12/02 20:40:34 rwatson Exp $ + */ + +#ifndef _MACHINE_STACK_H_ +#define _MACHINE_STACK_H_ + +extern char tl_trap_begin[]; +extern char tl_trap_end[]; +extern char tl_text_begin[]; +extern char tl_text_end[]; + +#define INKERNEL(va) \ + ((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS) + +#endif /* !_MACHINE_STACK_H_ */ Index: sys/sparc64/sparc64/db_trace.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/sparc64/sparc64/db_trace.c,v retrieving revision 1.26 diff -u -r1.26 db_trace.c --- sys/sparc64/sparc64/db_trace.c 12 Jul 2006 21:22:44 -0000 1.26 +++ sys/sparc64/sparc64/db_trace.c 17 Jan 2008 19:25:16 -0000 @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -50,14 +51,6 @@ #include #include -extern char tl_trap_begin[]; -extern char tl_trap_end[]; -extern char tl_text_begin[]; -extern char tl_text_end[]; - -#define INKERNEL(va) \ - ((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS) - static db_varfcn_t db_frame; #define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) @@ -297,29 +290,3 @@ ctx = kdb_thr_ctx(td); return (db_backtrace(td, (struct frame*)(ctx->pcb_sp + SPOFF), count)); } - -void -stack_save(struct stack *st) -{ - struct frame *fp; - db_expr_t addr; - vm_offset_t callpc; - - stack_zero(st); - addr = (db_expr_t)__builtin_frame_address(1); - fp = (struct frame *)(addr + SPOFF); - while (1) { - callpc = fp->fr_pc; - if (!INKERNEL(callpc)) - break; - /* Don't bother traversing trap frames. */ - if ((callpc > (u_long)tl_trap_begin && - callpc < (u_long)tl_trap_end) || - (callpc > (u_long)tl_text_begin && - callpc < (u_long)tl_text_end)) - break; - if (stack_put(st, callpc) == -1) - break; - fp = (struct frame *)(fp->fr_fp + SPOFF); - } -} Index: sys/sparc64/sparc64/stack_machdep.c =================================================================== RCS file: sys/sparc64/sparc64/stack_machdep.c diff -N sys/sparc64/sparc64/stack_machdep.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sparc64/sparc64/stack_machdep.c 17 Jan 2008 19:25:27 -0000 @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2005 Antoine Brodin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include +__FBSDID("$FreeBSD: src/sys/sparc64/sparc64/stack_machdep.c,v 1.1 2007/12/02 20:40:34 rwatson Exp $"); + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +static void +stack_capture(struct stack *st, uint64_t addr) +{ + struct frame *fp; + vm_offset_t callpc; + + stack_zero(st); + fp = (struct frame *)(addr + SPOFF); + while (1) { + callpc = fp->fr_pc; + if (!INKERNEL(callpc)) + break; + /* Don't bother traversing trap frames. */ + if ((callpc > (uint64_t)tl_trap_begin && + callpc < (uint64_t)tl_trap_end) || + (callpc > (uint64_t)tl_text_begin && + callpc < (uint64_t)tl_text_end)) + break; + if (stack_put(st, callpc) == -1) + break; + fp = (struct frame *)(fp->fr_fp + SPOFF); + } +} + +void +stack_save_td(struct stack *st, struct thread *td) +{ + uint64_t addr; + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + addr = td->td_pcb->pcb_sp; + stack_capture(st, addr); +} + +void +stack_save(struct stack *st) +{ + uint64_t addr; + + addr = (uint64_t)__builtin_frame_address(1); + stack_capture(st, addr); +} Index: sys/sun4v/conf/GENERIC =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/sun4v/conf/GENERIC,v retrieving revision 1.14.2.1 diff -u -r1.14.2.1 GENERIC --- sys/sun4v/conf/GENERIC 11 Oct 2007 06:20:27 -0000 1.14.2.1 +++ sys/sun4v/conf/GENERIC 17 Jan 2008 19:26:30 -0000 @@ -55,6 +55,7 @@ options COMPAT_FREEBSD5 # Compatible with FreeBSD5 options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support +options STACK # stack(9) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores Index: sys/sun4v/include/stack.h =================================================================== RCS file: sys/sun4v/include/stack.h diff -N sys/sun4v/include/stack.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sun4v/include/stack.h 17 Jan 2008 19:26:43 -0000 @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2001 Jake Burkholder. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/sys/sun4v/include/stack.h,v 1.1 2007/12/02 20:40:35 rwatson Exp $ + */ + +#ifndef _MACHINE_STACK_H_ +#define _MACHINE_STACK_H_ + +#define INKERNEL(va) \ + ((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS) + +#endif /* !_MACHINE_STACK_H_ */ Index: sys/sun4v/sun4v/db_trace.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/sun4v/sun4v/db_trace.c,v retrieving revision 1.1 diff -u -r1.1 db_trace.c --- sys/sun4v/sun4v/db_trace.c 5 Oct 2006 06:14:28 -0000 1.1 +++ sys/sun4v/sun4v/db_trace.c 17 Jan 2008 19:27:33 -0000 @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -49,9 +50,6 @@ #include #include -#define INKERNEL(va) \ - ((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS) - static db_varfcn_t db_frame; #define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) @@ -304,23 +302,3 @@ ctx = kdb_thr_ctx(td); return (db_backtrace(td, (struct frame*)(ctx->pcb_sp + SPOFF), count)); } - -void -stack_save(struct stack *st) -{ - struct frame *fp; - db_expr_t addr; - vm_offset_t callpc; - - stack_zero(st); - addr = (db_expr_t)__builtin_frame_address(1); - fp = (struct frame *)(addr + SPOFF); - while (1) { - callpc = fp->fr_pc; - if (!INKERNEL(callpc)) - break; - if (stack_put(st, callpc) == -1) - break; - fp = (struct frame *)(fp->fr_fp + SPOFF); - } -} Index: sys/sun4v/sun4v/stack_machdep.c =================================================================== RCS file: sys/sun4v/sun4v/stack_machdep.c diff -N sys/sun4v/sun4v/stack_machdep.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sun4v/sun4v/stack_machdep.c 17 Jan 2008 19:27:46 -0000 @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2005 Antoine Brodin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include +__FBSDID("$FreeBSD: src/sys/sun4v/sun4v/stack_machdep.c,v 1.1 2007/12/02 20:40:35 rwatson Exp $"); + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +static void +stack_capture(struct stack *st, uint64_t addr) +{ + struct frame *fp; + vm_offset_t callpc; + + stack_zero(st); + fp = (struct frame *)(addr + SPOFF); + while (1) { + callpc = fp->fr_pc; + if (!INKERNEL(callpc)) + break; + if (stack_put(st, callpc) == -1) + break; + fp = (struct frame *)(fp->fr_fp + SPOFF); + } + +} + +void +stack_save_td(struct stack *st, struct thread *td) +{ + uint64_t addr; + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + addr = td->td_pcb->pcb_sp; + stack_capture(st, addr); +} + +void +stack_save(struct stack *st) +{ + uint64_t addr; + + addr = (uint64_t)__builtin_frame_address(1); + stack_capture(st, addr); +} Index: sys/sys/linker.h =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/sys/linker.h,v retrieving revision 1.46 diff -u -r1.46 linker.h --- sys/sys/linker.h 20 Jun 2006 20:59:55 -0000 1.46 +++ sys/sys/linker.h 17 Jan 2008 17:01:41 -0000 @@ -155,6 +155,14 @@ int linker_ddb_search_symbol(caddr_t _value, c_linker_sym_t *_sym, long *_diffp); int linker_ddb_symbol_values(c_linker_sym_t _sym, linker_symval_t *_symval); +int linker_ddb_search_symbol_name(caddr_t value, char *buf, u_int buflen, + long *offset); + +/* + * stack(9) helper for situations where kernel locking is required. + */ +int linker_search_symbol_name(caddr_t value, char *buf, u_int buflen, + long *offset); /* HWPMC helper */ Index: sys/sys/stack.h =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/sys/stack.h,v retrieving revision 1.2 diff -u -r1.2 stack.h --- sys/sys/stack.h 29 Aug 2005 11:34:08 -0000 1.2 +++ sys/sys/stack.h 17 Jan 2008 19:27:58 -0000 @@ -45,7 +45,9 @@ void stack_copy(struct stack *, struct stack *); void stack_zero(struct stack *); void stack_print(struct stack *); +void stack_print_ddb(struct stack *); void stack_sbuf_print(struct sbuf *, struct stack *); +void stack_sbuf_print_ddb(struct sbuf *, struct stack *); #ifdef KTR void stack_ktr(u_int, const char *, int, struct stack *, u_int, int); #define CTRSTACK(m, st, depth, cheap) do { \ @@ -57,6 +59,8 @@ #endif /* MD Routine. */ +struct thread; void stack_save(struct stack *); +void stack_save_td(struct stack *, struct thread *); #endif Index: sys/sys/sysctl.h =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/sys/sysctl.h,v retrieving revision 1.148 diff -u -r1.148 sysctl.h --- sys/sys/sysctl.h 4 Jun 2007 18:14:28 -0000 1.148 +++ sys/sys/sysctl.h 17 Jan 2008 19:28:45 -0000 @@ -456,6 +456,9 @@ #define KERN_PROC_RGID 10 /* by real group id */ #define KERN_PROC_GID 11 /* by effective group id */ #define KERN_PROC_PATHNAME 12 /* path to executable */ +#define KERN_PROC_VMMAP 13 /* VM map entries for process */ +#define KERN_PROC_FILEDESC 14 /* File descriptors for process */ +#define KERN_PROC_KSTACK 15 /* Kernel stacks for process */ #define KERN_PROC_INC_THREAD 0x10 /* * modifier for pid, pgrp, tty, * uid, ruid, gid, rgid and proc @@ -618,6 +621,7 @@ extern struct sysctl_oid_list sysctl__children; SYSCTL_DECL(_kern); SYSCTL_DECL(_kern_ipc); +SYSCTL_DECL(_kern_proc); SYSCTL_DECL(_sysctl); SYSCTL_DECL(_vm); SYSCTL_DECL(_vm_stats); Index: sys/sys/user.h =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/sys/user.h,v retrieving revision 1.70 diff -u -r1.70 user.h --- sys/sys/user.h 17 Sep 2007 05:27:21 -0000 1.70 +++ sys/sys/user.h 17 Jan 2008 16:53:30 -0000 @@ -1,6 +1,8 @@ /*- * Copyright (c) 1982, 1986, 1989, 1991, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. + * Copyright (c) 2007 Robert N. M. Watson + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -56,6 +58,9 @@ #ifndef _SYS_SIGNALVAR_H_ #include #endif +#ifndef _SYS_SOCKET_VAR_H_ +#include +#endif /* * KERN_PROC subtype ops return arrays of selected proc structure entries: @@ -228,4 +233,109 @@ struct kinfo_proc u_kproc; /* eproc */ }; +/* + * The KERN_PROC_FILE sysctl allows a process to dumpt the file descriptor + * array of another process. + */ +#define KF_TYPE_NONE 0 +#define KF_TYPE_VNODE 1 +#define KF_TYPE_SOCKET 2 +#define KF_TYPE_PIPE 3 +#define KF_TYPE_FIFO 4 +#define KF_TYPE_KQUEUE 5 +#define KF_TYPE_CRYPTO 6 +#define KF_TYPE_MQUEUE 7 +#define KF_TYPE_UNKNOWN 255 + +#define KF_VTYPE_VNON 0 +#define KF_VTYPE_VREG 1 +#define KF_VTYPE_VDIR 2 +#define KF_VTYPE_VBLK 3 +#define KF_VTYPE_VCHR 4 +#define KF_VTYPE_VLNK 5 +#define KF_VTYPE_VSOCK 6 +#define KF_VTYPE_VFIFO 7 +#define KF_VTYPE_VBAD 8 +#define KF_VTYPE_UNKNOWN 255 + +#define KF_FLAG_READ 0x00000001 +#define KF_FLAG_WRITE 0x00000002 +#define KF_FLAG_APPEND 0x00000004 +#define KF_FLAG_ASYNC 0x00000008 +#define KF_FLAG_FSYNC 0x00000010 +#define KF_FLAG_NONBLOCK 0x00000020 +#define KF_FLAG_DIRECT 0x00000040 +#define KF_FLAG_HASLOCK 0x00000080 + +struct kinfo_file { + int kf_structsize; /* Size of kinfo_file. */ + int kf_type; /* Descriptor type. */ + int kf_fd; /* Array index. */ + int kf_ref_count; /* Reference count. */ + int kf_flags; /* Flags. */ + off_t kf_offset; /* Seek location. */ + int kf_vnode_type; /* Vnode type. */ + int kf_sock_domain; /* Socket domain. */ + int kf_sock_type; /* Socket type. */ + int kf_sock_protocol; /* Socket protocol. */ + char kf_path[PATH_MAX]; /* Path to file, if any. */ + struct sockaddr_storage kf_sa_local; /* Socket address. */ + struct sockaddr_storage kf_sa_peer; /* Peer address. */ +}; + +/* + * The KERN_PROC_VMMAP sysctl allows a process to dump the VM layout of + * another process as a series of entries. + */ +#define KVME_TYPE_NONE 0 +#define KVME_TYPE_DEFAULT 1 +#define KVME_TYPE_VNODE 2 +#define KVME_TYPE_SWAP 3 +#define KVME_TYPE_DEVICE 4 +#define KVME_TYPE_PHYS 5 +#define KVME_TYPE_DEAD 6 +#define KVME_TYPE_UNKNOWN 255 + +#define KVME_PROT_READ 0x00000001 +#define KVME_PROT_WRITE 0x00000002 +#define KVME_PROT_EXEC 0x00000004 + +#define KVME_FLAG_COW 0x00000001 +#define KVME_FLAG_NEEDS_COPY 0x00000002 + +struct kinfo_vmentry { + int kve_structsize; /* Size of kinfo_vmmapentry. */ + int kve_type; /* Type of map entry. */ + void *kve_start; /* Starting pointer. */ + void *kve_end; /* Finishing pointer. */ + int kve_flags; /* Flags on map entry. */ + int kve_resident; /* Number of resident pages. */ + int kve_private_resident; /* Number of private pages. */ + int kve_protection; /* Protection bitmask. */ + int kve_ref_count; /* VM obj ref count. */ + int kve_shadow_count; /* VM obj shadow count. */ + char kve_path[PATH_MAX]; /* Path to VM obj, if any. */ + void *_kve_pspare[8]; /* Space for more stuff. */ + int _kve_ispare[8]; /* Space for more stuff. */ +}; + +/* + * The KERN_PROC_KSTACK sysctl allows a process to dump the kernel stacks of + * another process as a series of entries. Each stack is represented by a + * series of symbol names and offsets as generated by stack_sbuf_print(9). + */ +#define KKST_MAXLEN 1024 + +#define KKST_STATE_STACKOK 0 /* Stack is valid. */ +#define KKST_STATE_SWAPPED 1 /* Stack swapped out. */ +#define KKST_STATE_RUNNING 2 /* Stack ephemeral. */ + +struct kinfo_kstack { + lwpid_t kkst_tid; /* ID of thread. */ + int kkst_state; /* Validity of stack. */ + char kkst_trace[KKST_MAXLEN]; /* String representing stack. */ + void *_kkst_pspare[8]; /* Space for more stuff. */ + int _kkst_ispare[8]; /* Space for more stuff. */ +}; + #endif Index: sys/vm/redzone.c =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/sys/vm/redzone.c,v retrieving revision 1.1 diff -u -r1.1 redzone.c --- sys/vm/redzone.c 31 Jan 2006 11:09:20 -0000 1.1 +++ sys/vm/redzone.c 17 Jan 2008 17:03:21 -0000 @@ -152,10 +152,10 @@ "corrupted before %p (%lu bytes allocated).\n", ncorruptions, ncorruptions == 1 ? "" : "s", naddr, nsize); printf("Allocation backtrace:\n"); - stack_print(&ast); + stack_print_ddb(&ast); printf("Free backtrace:\n"); stack_save(&fst); - stack_print(&fst); + stack_print_ddb(&fst); if (redzone_panic) panic("Stopping here."); } @@ -171,10 +171,10 @@ "after %p (%lu bytes allocated).\n", ncorruptions, ncorruptions == 1 ? "" : "s", naddr + nsize, nsize); printf("Allocation backtrace:\n"); - stack_print(&ast); + stack_print_ddb(&ast); printf("Free backtrace:\n"); stack_save(&fst); - stack_print(&fst); + stack_print_ddb(&fst); if (redzone_panic) panic("Stopping here."); } Index: usr.bin/Makefile =================================================================== RCS file: /home/data/fbsd-cvs/ncvs/src/usr.bin/Makefile,v retrieving revision 1.303 diff -u -r1.303 Makefile --- usr.bin/Makefile 9 Oct 2007 23:31:11 -0000 1.303 +++ usr.bin/Makefile 17 Jan 2008 19:31:01 -0000 @@ -149,6 +149,7 @@ pr \ printenv \ printf \ + procstat \ quota \ renice \ rev \ Index: usr.bin/procstat/Makefile =================================================================== RCS file: usr.bin/procstat/Makefile diff -N usr.bin/procstat/Makefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/Makefile 17 Jan 2008 19:30:45 -0000 @@ -0,0 +1,15 @@ +# $FreeBSD: src/usr.bin/procstat/Makefile,v 1.1 2007/12/02 23:31:45 rwatson Exp $ + +PROG= procstat +MAN= procstat.1 +SRCS= procstat.c \ + procstat_args.c \ + procstat_basic.c \ + procstat_bin.c \ + procstat_cred.c \ + procstat_files.c \ + procstat_kstack.c \ + procstat_threads.c \ + procstat_vm.c + +.include Index: usr.bin/procstat/procstat.1 =================================================================== RCS file: usr.bin/procstat/procstat.1 diff -N usr.bin/procstat/procstat.1 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/procstat.1 17 Jan 2008 19:30:45 -0000 @@ -0,0 +1,114 @@ +.\"- +.\" Copyright (c) 2007 Robert N. M. Watson +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: src/usr.bin/procstat/procstat.1,v 1.1 2007/12/02 23:31:45 rwatson Exp $ +.\" +.Dd October 30, 2007 +.Dt PROCSTAT 1 +.Os +.Sh NAME +.Nm procstat +.Nd get detailed process information +.Sh SYNOPSIS +.Nm +.Op Fl h +.Op Fl w Ar interval +.Op Fl b | c | f | k | s | t | v +.Op Fl a | Ar pid ... +.Sh DESCRIPTION +The +.Nm +utility displays detailed information about the processes identified by the +.Ar pid +arguments, or if the +.Fl a +flag is used, all processes. +.Pp +By default, basic process statistics are printed; one of the following +options may be specified in order to select more detailed process information +for printing: +.Bl -tag -width indent +.It Fl b +Display binary information for the process. +.It Fl c +Display command line arguments for the process. +.It Fl f +Display file descriptor information for the process. +.It Fl k +Display the stacks of kernel threads in the process, excluding stacks of +threads currently running on a CPU and threads with stacks swapped to disk. +If the flag is repeated, function offsets as well as function names are +printed. +This feature requires +.Cd "options STACK" +or +.Cd "options DDB" +to be compiled into the kernel. +.It Fl s +Display security credential information for the process. +.It Fl t +Display thread information for the process. +.It Fl v +Display virtual memory mappings for the process. +.El +.Pp +All options generate output in the format of a table, the first field of +which is the process ID to which the row of information corresponds. +The +.Fl h +flag may be used to suppress table headers. +.Pp +The +.Fl w +flag may be used to specify a wait interval at which to repeat the printing +of the requested process information. +If the +.Fl w +flag is not specified, the output will not repeat. +.Pp +Some information, such as VM and file descriptor information, is available +only to the owner of a process or the superuser. +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr fstat 1 , +.Xr ps 1 , +.Xr sockstat 1 , +.Xr DDB 4 , +.Xr stack 9 +.Sh AUTHORS +.An Robert N M Watson +.Sh BUGS +Some field values may include spaces, which limits the extent to which the +output of +.Nm +may be mechanically parsed. +.Pp +The display of open file or memory mapping pathnames is implemented using the +kernel's name cache. +It therefore does not work for file systems +that do not use the name cache, such as +.Xr devfs 4 , +or if the name is not present in the cache due to removal. Index: usr.bin/procstat/procstat.c =================================================================== RCS file: usr.bin/procstat/procstat.c diff -N usr.bin/procstat/procstat.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/procstat.c 17 Jan 2008 19:30:45 -0000 @@ -0,0 +1,252 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/usr.bin/procstat/procstat.c,v 1.1 2007/12/02 23:31:45 rwatson Exp $ + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "procstat.h" + +static int aflag, bflag, cflag, fflag, kflag, sflag, tflag, vflag; +int hflag; + +static void +usage(void) +{ + + fprintf(stderr, "usage: procstat [-h] [-w interval] [-b | -c | -f | " + "-k | -s | -t | -v]\n"); + fprintf(stderr, " [-a | pid ...]\n"); + exit(EX_USAGE); +} + +static void +procstat(pid_t pid, struct kinfo_proc *kipp) +{ + + if (bflag) + procstat_bin(pid, kipp); + else if (cflag) + procstat_args(pid, kipp); + else if (fflag) + procstat_files(pid, kipp); + else if (kflag) + procstat_kstack(pid, kipp, kflag); + else if (sflag) + procstat_cred(pid, kipp); + else if (tflag) + procstat_threads(pid, kipp); + else if (vflag) + procstat_vm(pid, kipp); + else + procstat_basic(pid, kipp); +} + +/* + * Sort processes first by pid and then tid. + */ +static int +kinfo_proc_compare(const void *a, const void *b) +{ + int i; + + i = ((struct kinfo_proc *)a)->ki_pid - + ((struct kinfo_proc *)b)->ki_pid; + if (i != 0) + return (i); + i = ((struct kinfo_proc *)a)->ki_tid - + ((struct kinfo_proc *)b)->ki_tid; + return (i); +} + +void +kinfo_proc_sort(struct kinfo_proc *kipp, int count) +{ + + qsort(kipp, count, sizeof(*kipp), kinfo_proc_compare); +} + +int +main(int argc, char *argv[]) +{ + int ch, i, interval, name[4], tmp; + struct kinfo_proc *kipp; + size_t len; + long l; + pid_t pid; + char *dummy; + + interval = 0; + while ((ch = getopt(argc, argv, "abcfkhstvw:")) != -1) { + switch (ch) { + case 'a': + aflag++; + break; + + case 'b': + bflag++; + break; + + case 'c': + cflag++; + break; + + case 'f': + fflag++; + break; + + case 'k': + kflag++; + break; + + case 'h': + hflag++; + break; + + case 's': + sflag++; + break; + + case 't': + tflag++; + break; + + case 'v': + vflag++; + break; + + case 'w': + l = strtol(optarg, &dummy, 10); + if (*dummy != '\0') + usage(); + if (l < 1 || l > INT_MAX) + usage(); + interval = l; + break; + + case '?': + default: + usage(); + } + + } + argc -= optind; + argv += optind; + + /* We require that either 0 or 1 mode flags be set. */ + tmp = bflag + cflag + fflag + (kflag ? 1 : 0) + sflag + tflag + vflag; + if (!(tmp == 0 || tmp == 1)) + usage(); + + /* We allow -k to be specified up to twice, but not more. */ + if (kflag > 2) + usage(); + + /* Must specify either the -a flag or a list of pids. */ + if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0)) + usage(); + + do { + if (aflag) { + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PROC; + + len = 0; + if (sysctl(name, 3, NULL, &len, NULL, 0) < 0) + err(-1, "sysctl: kern.proc.all"); + + kipp = malloc(len); + if (kipp == NULL) + err(-1, "malloc"); + + if (sysctl(name, 3, kipp, &len, NULL, 0) < 0) { + free(kipp); + err(-1, "sysctl: kern.proc.all"); + } + if (len % sizeof(*kipp) != 0) + err(-1, "kinfo_proc mismatch"); + if (kipp->ki_structsize != sizeof(*kipp)) + err(-1, "kinfo_proc structure mismatch"); + kinfo_proc_sort(kipp, len / sizeof(*kipp)); + for (i = 0; i < len / sizeof(*kipp); i++) { + procstat(kipp[i].ki_pid, &kipp[i]); + + /* Suppress header after first process. */ + hflag = 1; + } + free(kipp); + } + for (i = 0; i < argc; i++) { + l = strtol(argv[i], &dummy, 10); + if (*dummy != '\0') + usage(); + if (l < 0) + usage(); + pid = l; + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PID; + name[3] = pid; + + len = 0; + if (sysctl(name, 4, NULL, &len, NULL, 0) < 0) + err(-1, "sysctl: kern.proc.pid: %d", pid); + + kipp = malloc(len); + if (kipp == NULL) + err(-1, "malloc"); + + if (sysctl(name, 4, kipp, &len, NULL, 0) < 0) { + free(kipp); + err(-1, "sysctl: kern.proc.pid: %d", pid); + } + if (len != sizeof(*kipp)) + err(-1, "kinfo_proc mismatch"); + if (kipp->ki_structsize != sizeof(*kipp)) + errx(-1, "kinfo_proc structure mismatch"); + if (kipp->ki_pid != pid) + errx(-1, "kinfo_proc pid mismatch"); + procstat(pid, kipp); + free(kipp); + + /* Suppress header after first process. */ + hflag = 1; + } + if (interval) + sleep(interval); + } while (interval); + exit(0); +} Index: usr.bin/procstat/procstat.h =================================================================== RCS file: usr.bin/procstat/procstat.h diff -N usr.bin/procstat/procstat.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/procstat.h 17 Jan 2008 19:30:46 -0000 @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/usr.bin/procstat/procstat.h,v 1.1 2007/12/02 23:31:45 rwatson Exp $ + */ + +#ifndef PROCSTAT_H +#define PROCSTAT_H + +extern int hflag; + +struct kinfo_proc; +void kinfo_proc_sort(struct kinfo_proc *kipp, int count); + +void procstat_args(pid_t pid, struct kinfo_proc *kipp); +void procstat_basic(pid_t pid, struct kinfo_proc *kipp); +void procstat_bin(pid_t pid, struct kinfo_proc *kipp); +void procstat_cred(pid_t pid, struct kinfo_proc *kipp); +void procstat_files(pid_t pid, struct kinfo_proc *kipp); +void procstat_kstack(pid_t pid, struct kinfo_proc *kipp, int kflag); +void procstat_threads(pid_t pid, struct kinfo_proc *kipp); +void procstat_vm(pid_t pid, struct kinfo_proc *kipp); + +#endif /* !PROCSTAT_H */ Index: usr.bin/procstat/procstat_args.c =================================================================== RCS file: usr.bin/procstat/procstat_args.c diff -N usr.bin/procstat/procstat_args.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/procstat_args.c 17 Jan 2008 19:30:46 -0000 @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/usr.bin/procstat/procstat_args.c,v 1.2 2007/12/10 20:55:43 rwatson Exp $ + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "procstat.h" + +static char args[ARG_MAX]; + +void +procstat_args(pid_t pid, struct kinfo_proc *kipp) +{ + int error, name[4]; + size_t len; + char *cp; + + if (!hflag) + printf("%5s %-16s %-53s\n", "PID", "COMM", "ARGS"); + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_ARGS; + name[3] = pid; + len = sizeof(args); + error = sysctl(name, 4, args, &len, NULL, 0); + if (error < 0 && errno != ESRCH) { + warn("sysctl: kern.proc.args: %d", pid); + return; + } + if (error < 0) + return; + if (len == 0 || strlen(args) == 0) { + strcpy(args, "-"); + len = strlen(args) + 1; + } + + printf("%5d ", pid); + printf("%-16s ", kipp->ki_comm); + for (cp = args; cp < args + len; cp += strlen(cp) + 1) + printf("%s%s", cp != args ? " " : "", cp); + printf("\n"); +} Index: usr.bin/procstat/procstat_basic.c =================================================================== RCS file: usr.bin/procstat/procstat_basic.c diff -N usr.bin/procstat/procstat_basic.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/procstat_basic.c 17 Jan 2008 19:30:46 -0000 @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/usr.bin/procstat/procstat_basic.c,v 1.1 2007/12/02 23:31:45 rwatson Exp $ + */ + +#include +#include +#include + +#include +#include +#include + +#include "procstat.h" + +void +procstat_basic(pid_t pid, struct kinfo_proc *kipp) +{ + + if (!hflag) + printf("%5s %5s %5s %5s %5s %3s %-8s %-9s %-13s %-12s\n", + "PID", "PPID", "PGID", "SID", "TSID", "THR", "LOGIN", + "WCHAN", "EMUL", "COMM"); + + printf("%5d ", kipp->ki_pid); + printf("%5d ", kipp->ki_ppid); + printf("%5d ", kipp->ki_pgid); + printf("%5d ", kipp->ki_sid); + printf("%5d ", kipp->ki_tsid); + printf("%3d ", kipp->ki_numthreads); + printf("%-8s ", strlen(kipp->ki_login) ? kipp->ki_login : "-"); + if (kipp->ki_kiflag & KI_LOCKBLOCK) { + printf("*%-8s ", strlen(kipp->ki_lockname) ? + kipp->ki_lockname : "-"); + } else { + printf("%-9s ", strlen(kipp->ki_wmesg) ? + kipp->ki_wmesg : "-"); + } + printf("%-13s ", strcmp(kipp->ki_emul, "null") ? kipp->ki_emul : "-"); + printf("%-12s\n", kipp->ki_comm); +} Index: usr.bin/procstat/procstat_bin.c =================================================================== RCS file: usr.bin/procstat/procstat_bin.c diff -N usr.bin/procstat/procstat_bin.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/procstat_bin.c 17 Jan 2008 19:30:46 -0000 @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/usr.bin/procstat/procstat_bin.c,v 1.2 2007/12/10 20:55:43 rwatson Exp $ + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "procstat.h" + +void +procstat_bin(pid_t pid, struct kinfo_proc *kipp) +{ + char pathname[PATH_MAX]; + int error, name[4]; + size_t len; + + if (!hflag) + printf("%5s %-16s %-53s\n", "PID", "COMM", "PATH"); + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PATHNAME; + name[3] = pid; + + len = sizeof(pathname); + error = sysctl(name, 4, pathname, &len, NULL, 0); + if (error < 0 && errno != ESRCH) { + warn("sysctl: kern.proc.pathname: %d", pid); + return; + } + if (error < 0) + return; + if (len == 0 || strlen(pathname) == 0) + strcpy(pathname, "-"); + + printf("%5d ", pid); + printf("%-16s ", kipp->ki_comm); + printf("%s\n", pathname); +} Index: usr.bin/procstat/procstat_cred.c =================================================================== RCS file: usr.bin/procstat/procstat_cred.c diff -N usr.bin/procstat/procstat_cred.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/procstat_cred.c 17 Jan 2008 19:30:46 -0000 @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/usr.bin/procstat/procstat_cred.c,v 1.2 2007/12/10 20:55:43 rwatson Exp $ + */ + +#include +#include +#include + +#include +#include + +#include "procstat.h" + +void +procstat_cred(pid_t pid, struct kinfo_proc *kipp) +{ + int i; + + if (!hflag) + printf("%5s %-16s %5s %5s %5s %5s %5s %5s %-20s\n", "PID", + "COMM", "EUID", "RUID", "SVUID", "EGID", "RGID", "SVGID", + "GROUPS"); + + printf("%5d ", pid); + printf("%-16s ", kipp->ki_comm); + printf("%5d ", kipp->ki_uid); + printf("%5d ", kipp->ki_ruid); + printf("%5d ", kipp->ki_svuid); + printf("%5d ", kipp->ki_groups[0]); + printf("%5d ", kipp->ki_rgid); + printf("%5d ", kipp->ki_svgid); + for (i = 0; i < kipp->ki_ngroups; i++) + printf("%s%d", (i > 0) ? "," : "", kipp->ki_groups[i]); + printf("\n"); +} Index: usr.bin/procstat/procstat_files.c =================================================================== RCS file: usr.bin/procstat/procstat_files.c diff -N usr.bin/procstat/procstat_files.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/procstat_files.c 17 Jan 2008 19:30:46 -0000 @@ -0,0 +1,306 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/usr.bin/procstat/procstat_files.c,v 1.2 2007/12/10 20:55:43 rwatson Exp $ + */ + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include "procstat.h" + +static const char * +protocol_to_string(int domain, int type, int protocol) +{ + + switch (domain) { + case AF_INET: + case AF_INET6: + switch (protocol) { + case IPPROTO_TCP: + return ("TCP"); + case IPPROTO_UDP: + return ("UDP"); + case IPPROTO_ICMP: + return ("ICM"); + case IPPROTO_RAW: + return ("RAW"); + case IPPROTO_SCTP: + return ("SCT"); + case IPPROTO_DIVERT: + return ("IPD"); + default: + return ("IP?"); + } + + case AF_LOCAL: + switch (type) { + case SOCK_STREAM: + return ("UDS"); + case SOCK_DGRAM: + return ("UDD"); + default: + return ("UD?"); + } + default: + return ("?"); + } +} + +static void +addr_to_string(struct sockaddr_storage *ss, char *buffer, int buflen) +{ + char buffer2[INET6_ADDRSTRLEN]; + struct sockaddr_in6 *sin6; + struct sockaddr_in *sin; + struct sockaddr_un *sun; + + switch (ss->ss_family) { + case AF_LOCAL: + sun = (struct sockaddr_un *)ss; + if (strlen(sun->sun_path) == 0) + strlcpy(buffer, "-", buflen); + else + strlcpy(buffer, sun->sun_path, buflen); + break; + + case AF_INET: + sin = (struct sockaddr_in *)ss; + snprintf(buffer, buflen, "%s:%d", inet_ntoa(sin->sin_addr), + ntohs(sin->sin_port)); + break; + + case AF_INET6: + sin6 = (struct sockaddr_in6 *)ss; + if (inet_ntop(AF_INET6, &sin6->sin6_addr, buffer2, + sizeof(buffer2)) != NULL) + snprintf(buffer, buflen, "%s.%d", buffer2, + ntohs(sin6->sin6_port)); + else + strlcpy(buffer, "-", sizeof(buffer)); + break; + + default: + strlcpy(buffer, "", buflen); + break; + } +} + +static void +print_address(struct sockaddr_storage *ss) +{ + char addr[PATH_MAX]; + + addr_to_string(ss, addr, sizeof(addr)); + printf("%s", addr); +} + +void +procstat_files(pid_t pid, struct kinfo_proc *kipp) +{ + struct kinfo_file *freep, *kif; + int error, i, name[4]; + const char *str; + size_t len; + + if (!hflag) + printf("%5s %-16s %3s %1s %1s %-8s %3s %7s %-3s %-12s\n", + "PID", "COMM", "FD", "T", "V", "FLAGS", "REF", "OFFSET", + "PRO", "NAME"); + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_FILEDESC; + name[3] = pid; + + error = sysctl(name, 4, NULL, &len, NULL, 0); + if (error < 0 && errno != ESRCH && errno != EPERM) { + warn("sysctl: kern.proc.filedesc: %d", pid); + return; + } + if (error < 0) + return; + + freep = kif = malloc(len); + if (kif == NULL) + err(-1, "malloc"); + + if (sysctl(name, 4, kif, &len, NULL, 0) < 0) { + warn("sysctl: kern.proc.filedesc %d", pid); + free(freep); + return; + } + + for (i = 0; i < len / sizeof(*kif); i++, kif++) { + if (kif->kf_structsize != sizeof(*kif)) + errx(-1, "kinfo_file mismatch"); + printf("%5d ", pid); + printf("%-16s ", kipp->ki_comm); + printf("%3d ", kif->kf_fd); + switch (kif->kf_type) { + case KF_TYPE_VNODE: + str = "v"; + break; + + case KF_TYPE_SOCKET: + str = "s"; + break; + + case KF_TYPE_PIPE: + str = "p"; + break; + + case KF_TYPE_FIFO: + str = "f"; + break; + + case KF_TYPE_KQUEUE: + str = "k"; + break; + + case KF_TYPE_CRYPTO: + str = "c"; + break; + + case KF_TYPE_MQUEUE: + str = "m"; + break; + + case KF_TYPE_NONE: + case KF_TYPE_UNKNOWN: + default: + str = "?"; + break; + } + printf("%1s ", str); + str = "-"; + if (kif->kf_type == KF_TYPE_VNODE) { + switch (kif->kf_vnode_type) { + case KF_VTYPE_VREG: + str = "r"; + break; + + case KF_VTYPE_VDIR: + str = "d"; + break; + + case KF_VTYPE_VBLK: + str = "b"; + break; + + case KF_VTYPE_VCHR: + str = "c"; + break; + + case KF_VTYPE_VLNK: + str = "l"; + break; + + case KF_VTYPE_VSOCK: + str = "s"; + break; + + case KF_VTYPE_VFIFO: + str = "f"; + break; + + case KF_VTYPE_VBAD: + str = "x"; + break; + + case KF_VTYPE_VNON: + case KF_VTYPE_UNKNOWN: + default: + str = "?"; + break; + } + } + printf("%1s ", str); + printf("%s", kif->kf_flags & KF_FLAG_READ ? "r" : "-"); + printf("%s", kif->kf_flags & KF_FLAG_WRITE ? "w" : "-"); + printf("%s", kif->kf_flags & KF_FLAG_APPEND ? "a" : "-"); + printf("%s", kif->kf_flags & KF_FLAG_ASYNC ? "s" : "-"); + printf("%s", kif->kf_flags & KF_FLAG_FSYNC ? "f" : "-"); + printf("%s", kif->kf_flags & KF_FLAG_NONBLOCK ? "n" : "-"); + printf("%s", kif->kf_flags & KF_FLAG_DIRECT ? "d" : "-"); + printf("%s ", kif->kf_flags & KF_FLAG_HASLOCK ? "l" : "-"); + printf("%3d ", kif->kf_ref_count); + printf("%7jd ", (intmax_t)kif->kf_offset); + + switch (kif->kf_type) { + case KF_TYPE_VNODE: + case KF_TYPE_FIFO: + printf("%-3s ", "-"); + printf("%-18s", kif->kf_path); + break; + + case KF_TYPE_SOCKET: + printf("%-3s ", + protocol_to_string(kif->kf_sock_domain, + kif->kf_sock_type, kif->kf_sock_protocol)); + /* + * While generally we like to print two addresses, + * local and peer, for sockets, it turns out to be + * more useful to print the first non-nul address for + * local sockets, as typically they aren't bound and + * connected, and the path strings can get long. + */ + if (kif->kf_sock_domain == AF_LOCAL) { + struct sockaddr_un *sun = + (struct sockaddr_un *)&kif->kf_sa_local; + + if (sun->sun_path[0] != 0) + print_address(&kif->kf_sa_local); + else + print_address(&kif->kf_sa_peer); + } else { + print_address(&kif->kf_sa_local); + printf(" "); + print_address(&kif->kf_sa_peer); + } + break; + + default: + printf("%-3s ", "-"); + printf("%-18s", "-"); + } + + printf("\n"); + } + free(freep); +} Index: usr.bin/procstat/procstat_kstack.c =================================================================== RCS file: usr.bin/procstat/procstat_kstack.c diff -N usr.bin/procstat/procstat_kstack.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/procstat_kstack.c 17 Jan 2008 19:30:46 -0000 @@ -0,0 +1,245 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/usr.bin/procstat/procstat_kstack.c,v 1.2 2007/12/03 21:21:15 rwatson Exp $ + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "procstat.h" + +/* + * Walk the stack trace provided by the kernel and reduce it to what we + * actually want to print. This involves stripping true instruction pointers, + * frame numbers, and carriage returns as generated by stack(9). If -kk is + * specified, print the function and offset, otherwise just the function. + */ +enum trace_state { TS_FRAMENUM, TS_PC, TS_AT, TS_FUNC, TS_OFF }; + +static enum trace_state +kstack_nextstate(enum trace_state ts) +{ + + switch (ts) { + case TS_FRAMENUM: + return (TS_PC); + + case TS_PC: + return (TS_AT); + + case TS_AT: + return (TS_FUNC); + + case TS_FUNC: + return (TS_OFF); + + case TS_OFF: + return TS_FRAMENUM; + + default: + errx(-1, "kstack_nextstate"); + } +} + +static void +kstack_cleanup(const char *old, char *new, int kflag) +{ + enum trace_state old_ts, ts; + const char *cp_old; + char *cp_new; + + ts = TS_FRAMENUM; + for (cp_old = old, cp_new = new; *cp_old != '\0'; cp_old++) { + switch (*cp_old) { + case ' ': + case '\n': + case '+': + old_ts = ts; + ts = kstack_nextstate(old_ts); + if (old_ts == TS_OFF) { + *cp_new = ' '; + cp_new++; + } + if (kflag > 1 && old_ts == TS_FUNC) { + *cp_new = '+'; + cp_new++; + } + continue; + } + if (ts == TS_FUNC || (kflag > 1 && ts == TS_OFF)) { + *cp_new = *cp_old; + cp_new++; + } + } + *cp_new = '\0'; +} + +/* + * Sort threads by tid. + */ +static int +kinfo_kstack_compare(const void *a, const void *b) +{ + + return ((struct kinfo_kstack *)a)->kkst_tid - + ((struct kinfo_kstack *)b)->kkst_tid; +} + +static void +kinfo_kstack_sort(struct kinfo_kstack *kkstp, int count) +{ + + qsort(kkstp, count, sizeof(*kkstp), kinfo_kstack_compare); +} + + +void +procstat_kstack(pid_t pid, struct kinfo_proc *kipp, int kflag) +{ + struct kinfo_kstack *kkstp, *kkstp_free; + struct kinfo_proc *kip, *kip_free; + char trace[KKST_MAXLEN]; + int error, i, j, name[4]; + size_t kip_len, kstk_len; + + if (!hflag) + printf("%5s %6s %-16s %-16s %-29s\n", "PID", "TID", "COMM", + "TDNAME", "KSTACK"); + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_KSTACK; + name[3] = pid; + + kstk_len = 0; + error = sysctl(name, 4, NULL, &kstk_len, NULL, 0); + if (error < 0 && errno != ESRCH && errno != EPERM && errno != ENOENT) { + warn("sysctl: kern.proc.kstack: %d", pid); + return; + } + if (error < 0 && errno == ENOENT) { + warnx("sysctl: kern.proc.kstack unavailable"); + errx(-1, "options DDB or options STACK required in kernel"); + } + if (error < 0) + return; + + kkstp = kkstp_free = malloc(kstk_len); + if (kkstp == NULL) + err(-1, "malloc"); + + if (sysctl(name, 4, kkstp, &kstk_len, NULL, 0) < 0) { + warn("sysctl: kern.proc.pid: %d", pid); + free(kkstp); + return; + } + + /* + * We need to re-query for thread information, so don't use *kipp. + */ + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD; + name[3] = pid; + + kip_len = 0; + error = sysctl(name, 4, NULL, &kip_len, NULL, 0); + if (error < 0 && errno != ESRCH) { + warn("sysctl: kern.proc.pid: %d", pid); + return; + } + if (error < 0) + return; + + kip = kip_free = malloc(kip_len); + if (kip == NULL) + err(-1, "malloc"); + + if (sysctl(name, 4, kip, &kip_len, NULL, 0) < 0) { + warn("sysctl: kern.proc.pid: %d", pid); + free(kip); + return; + } + + kinfo_kstack_sort(kkstp, kstk_len / sizeof(*kkstp)); + for (i = 0; i < kstk_len / sizeof(*kkstp); i++) { + kkstp = &kkstp_free[i]; + + /* + * Look up the specific thread using its tid so we can + * display the per-thread command line. + */ + kipp = NULL; + for (j = 0; j < kip_len / sizeof(*kipp); j++) { + kipp = &kip_free[j]; + if (kkstp->kkst_tid == kipp->ki_tid) + break; + } + if (kipp == NULL) + continue; + + printf("%5d ", pid); + printf("%6d ", kkstp->kkst_tid); + printf("%-16s ", kipp->ki_comm); + printf("%-16s ", (strlen(kipp->ki_ocomm) && + (strcmp(kipp->ki_comm, kipp->ki_ocomm) != 0)) ? + kipp->ki_ocomm : "-"); + + switch (kkstp->kkst_state) { + case KKST_STATE_RUNNING: + printf("%-29s\n", ""); + continue; + + case KKST_STATE_SWAPPED: + printf("%-29s\n", ""); + continue; + + case KKST_STATE_STACKOK: + break; + + default: + printf("%-29s\n", ""); + continue; + } + + /* + * The kernel generates a trace with carriage returns between + * entries, but for a more compact view, we convert carriage + * returns to spaces. + */ + kstack_cleanup(kkstp->kkst_trace, trace, kflag); + printf("%-29s\n", trace); + } + free(kip_free); + free(kkstp_free); +} Index: usr.bin/procstat/procstat_threads.c =================================================================== RCS file: usr.bin/procstat/procstat_threads.c diff -N usr.bin/procstat/procstat_threads.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/procstat_threads.c 17 Jan 2008 19:30:46 -0000 @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/usr.bin/procstat/procstat_threads.c,v 1.2 2007/12/03 21:21:15 rwatson Exp $ + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "procstat.h" + +void +procstat_threads(pid_t pid, struct kinfo_proc *kipp) +{ + struct kinfo_proc *kip; + int error, i, name[4]; + const char *str; + size_t len; + + if (!hflag) + printf("%5s %6s %-16s %-16s %2s %4s %-7s %-9s\n", "PID", + "TID", "COMM", "TDNAME", "CPU", "PRI", "STATE", "WCHAN"); + + /* + * We need to re-query for thread information, so don't use *kipp. + */ + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD; + name[3] = pid; + + len = 0; + error = sysctl(name, 4, NULL, &len, NULL, 0); + if (error < 0 && errno != ESRCH) { + warn("sysctl: kern.proc.pid: %d", pid); + return; + } + if (error < 0) + return; + + kip = malloc(len); + if (kip == NULL) + err(-1, "malloc"); + + if (sysctl(name, 4, kip, &len, NULL, 0) < 0) { + warn("sysctl: kern.proc.pid: %d", pid); + free(kip); + return; + } + + kinfo_proc_sort(kip, len / sizeof(*kipp)); + for (i = 0; i < len / sizeof(*kipp); i++) { + kipp = &kip[i]; + printf("%5d ", pid); + printf("%6d ", kipp->ki_tid); + printf("%-16s ", strlen(kipp->ki_comm) ? + kipp->ki_comm : "-"); + printf("%-16s ", (strlen(kipp->ki_ocomm) && + (strcmp(kipp->ki_comm, kipp->ki_ocomm) != 0)) ? + kipp->ki_ocomm : "-"); + if (kipp->ki_oncpu != 255) + printf("%3d ", kipp->ki_oncpu); + else if (kipp->ki_lastcpu != 255) + printf("%3d ", kipp->ki_lastcpu); + else + printf("%3s ", "-"); + printf("%4d ", kipp->ki_pri.pri_level); + switch (kipp->ki_stat) { + case SRUN: + str = "run"; + break; + + case SSTOP: + str = "stop"; + break; + + case SSLEEP: + str = "sleep"; + break; + + case SLOCK: + str = "lock"; + break; + + case SWAIT: + str = "wait"; + break; + + case SZOMB: + str = "zomb"; + break; + + case SIDL: + str = "idle"; + break; + + default: + str = "??"; + break; + } + printf("%-7s ", str); + if (kipp->ki_kiflag & KI_LOCKBLOCK) { + printf("*%-8s ", strlen(kipp->ki_lockname) ? + kipp->ki_lockname : "-"); + } else { + printf("%-9s ", strlen(kipp->ki_wmesg) ? + kipp->ki_wmesg : "-"); + } + printf("\n"); + } + free(kip); +} Index: usr.bin/procstat/procstat_vm.c =================================================================== RCS file: usr.bin/procstat/procstat_vm.c diff -N usr.bin/procstat/procstat_vm.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/procstat/procstat_vm.c 17 Jan 2008 19:30:46 -0000 @@ -0,0 +1,130 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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