From owner-p4-projects@FreeBSD.ORG Mon Mar 29 22:53:13 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DBEAC16A4D0; Mon, 29 Mar 2004 22:53:12 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AFBCA16A4CE for ; Mon, 29 Mar 2004 22:53:12 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7088A43D3F for ; Mon, 29 Mar 2004 22:53:12 -0800 (PST) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.10/8.12.10) with ESMTP id i2U6rCGe009046 for ; Mon, 29 Mar 2004 22:53:12 -0800 (PST) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.10/8.12.10/Submit) id i2U6rB99009043 for perforce@freebsd.org; Mon, 29 Mar 2004 22:53:11 -0800 (PST) (envelope-from marcel@freebsd.org) Date: Mon, 29 Mar 2004 22:53:11 -0800 (PST) Message-Id: <200403300653.i2U6rB99009043@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Subject: PERFORCE change 49942 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 30 Mar 2004 06:53:13 -0000 http://perforce.freebsd.org/chv.cgi?CH=49942 Change 49942 by marcel@marcel_nfs on 2004/03/29 22:53:04 Add kdb_jmpbuf(). Backends use this function to "install" a jmp_buf. The function returns the previous jmp_buf. When the trappable code has completed, the previous jmp_buf can be restored by calling kdb_jmpbuf() again. In trap(), test early for traps from within the debugger. Do not print the trap information. Just call kdb_trap() where recursion is handled by doing a longjmp() for the most recent jmp_buf. Protect memory accesses in gdb_tx_mem() with a jmp_buf. Affected files ... .. //depot/projects/gdb/sys/gdb/gdb_int.h#6 edit .. //depot/projects/gdb/sys/gdb/gdb_packet.c#9 edit .. //depot/projects/gdb/sys/i386/i386/trap.c#7 edit .. //depot/projects/gdb/sys/ia64/ia64/trap.c#6 edit .. //depot/projects/gdb/sys/kern/subr_kdb.c#10 edit .. //depot/projects/gdb/sys/sys/kdb.h#8 edit Differences ... ==== //depot/projects/gdb/sys/gdb/gdb_int.h#6 (text+ko) ==== @@ -54,7 +54,7 @@ void gdb_tx_begin(char); int gdb_tx_end(void); -void gdb_tx_mem(const unsigned char *, size_t); +int gdb_tx_mem(const unsigned char *, size_t); void gdb_tx_reg(int); static __inline void ==== //depot/projects/gdb/sys/gdb/gdb_packet.c#9 (text+ko) ==== @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -224,15 +225,24 @@ return (0); } -void +int gdb_tx_mem(const unsigned char *addr, size_t size) { + void *prev; + jmp_buf jb; + int ret; - while (size-- > 0) { - *gdb_txp++ = N2C(*addr >> 4); - *gdb_txp++ = N2C(*addr & 0x0f); - addr++; + prev = kdb_jmpbuf(jb); + ret = setjmp(jb); + if (ret == 0) { + while (size-- > 0) { + *gdb_txp++ = N2C(*addr >> 4); + *gdb_txp++ = N2C(*addr & 0x0f); + addr++; + } } + (void)kdb_jmpbuf(prev); + return ((ret == 0) ? 1 : 0); } void ==== //depot/projects/gdb/sys/i386/i386/trap.c#7 (text+ko) ==== @@ -46,7 +46,6 @@ #include "opt_clock.h" #include "opt_cpu.h" -#include "opt_ddb.h" #include "opt_isa.h" #include "opt_ktrace.h" #include "opt_npx.h" @@ -55,10 +54,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -97,8 +96,6 @@ #include #endif -#include - extern void trap(struct trapframe frame); #ifdef I386_CPU extern int trapwrite(unsigned addr); @@ -148,10 +145,10 @@ extern int has_f00f_bug; #endif -#ifdef DDB -static int ddb_on_nmi = 1; -SYSCTL_INT(_machdep, OID_AUTO, ddb_on_nmi, CTLFLAG_RW, - &ddb_on_nmi, 0, "Go to DDB on NMI"); +#ifdef KDB +static int kdb_on_nmi = 1; +SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RW, + &kdb_on_nmi, 0, "Go to KDB on NMI"); #endif static int panic_on_nmi = 1; SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW, @@ -191,9 +188,8 @@ td->td_last_frame = &frame; #ifdef KDB - if (kdb_active) { - eva = (type == T_PAGEFLT ? rcr2() : 0); - trap_fatal(&frame, eva); + if (kdb_active && type == T_PAGEFLT) { + kdb_trap(type, 0, &frame); goto out; } #endif @@ -365,16 +361,16 @@ /* machine/parity/power fail/"kitchen sink" faults */ /* XXX Giant */ if (isa_nmi(code) == 0) { -#ifdef DDB +#ifdef KDB /* * NMI can be hooked up to a pushbutton * for debugging. */ - if (ddb_on_nmi) { + if (kdb_on_nmi) { printf ("NMI ... going to debugger\n"); - kdb_trap (type, 0, &frame); + kdb_trap(type, 0, &frame); } -#endif /* DDB */ +#endif /* KDB */ goto userout; } else if (panic_on_nmi) panic("NMI indicates hardware failure"); @@ -573,12 +569,12 @@ */ case T_BPTFLT: /* - * If DDB is enabled, let it handle the debugger trap. + * If KDB is enabled, let it handle the debugger trap. * Otherwise, debugger traps "can't happen". */ -#ifdef DDB +#ifdef KDB /* XXX Giant */ - if (kdb_trap (type, 0, &frame)) + if (kdb_trap(type, 0, &frame)) goto out; #endif break; @@ -598,16 +594,16 @@ /* XXX Giant */ /* machine/parity/power fail/"kitchen sink" faults */ if (isa_nmi(code) == 0) { -#ifdef DDB +#ifdef KDB /* * NMI can be hooked up to a pushbutton * for debugging. */ - if (ddb_on_nmi) { + if (kdb_on_nmi) { printf ("NMI ... going to debugger\n"); - kdb_trap (type, 0, &frame); + kdb_trap(type, 0, &frame); } -#endif /* DDB */ +#endif /* KDB */ goto out; } else if (panic_on_nmi == 0) goto out; @@ -809,7 +805,7 @@ } #ifdef KDB - if ((debugger_on_panic || kdb_active) && kdb_trap(type, 0, frame)) + if (kdb_trap(type, 0, frame)) return; #endif printf("trap number = %d\n", type); ==== //depot/projects/gdb/sys/ia64/ia64/trap.c#6 (text+ko) ==== @@ -76,10 +76,6 @@ #include #endif -#ifdef DDB -#include -#endif - static int print_usertrap = 0; SYSCTL_INT(_machdep, OID_AUTO, print_usertrap, CTLFLAG_RW, &print_usertrap, 0, ""); @@ -378,6 +374,10 @@ sticks = 0; /* XXX bogus -Wuninitialized warning */ KASSERT(cold || td->td_ucred != NULL, ("kernel trap doesn't have ucred")); +#ifdef KDB + if (kdb_active && vector == IA64_VEC_PAGE_NOT_PRESENT) + kdb_trap(vector, 0, tf); +#endif } sig = 0; ==== //depot/projects/gdb/sys/kern/subr_kdb.c#10 (text+ko) ==== @@ -38,6 +38,7 @@ #include int kdb_active = 0; +void *kdb_jmpbufp = NULL; struct kdb_dbbe *kdb_dbbe = NULL; struct thread *kdb_thread = NULL; struct trapframe *kdb_frame = NULL; @@ -102,6 +103,20 @@ } /* + * Handle contexts. + */ + +void * +kdb_jmpbuf(jmp_buf new) +{ + void *old; + + old = kdb_jmpbufp; + kdb_jmpbufp = new; + return (old); +} + +/* * Enter the currently selected debugger. If a message has been provided, * it is printed first. If the debugger does not support the enter method, * it is entered by using breakpoint(), which enters the debugger through @@ -112,7 +127,7 @@ kdb_enter(const char *msg) { - if (kdb_dbbe != NULL) { + if (kdb_dbbe != NULL && kdb_active == 0) { if (msg != NULL) printf("KDB: enter: %s\n", msg); breakpoint(); @@ -189,6 +204,12 @@ critical_enter(); + /* Check for recursion. */ + if (kdb_active && kdb_jmpbufp != NULL) { + critical_exit(); + longjmp(kdb_jmpbufp, 1); + } + kdb_active++; kdb_thread = curthread; kdb_frame = tf; ==== //depot/projects/gdb/sys/sys/kdb.h#8 (text+ko) ==== @@ -29,6 +29,8 @@ #ifndef _SYS_KDB_H_ #define _SYS_KDB_H_ +#include + typedef int dbbe_init_f(void); typedef void dbbe_trace_f(void); typedef int dbbe_trap_f(int, int); @@ -62,6 +64,7 @@ void kdb_backtrace(void); void kdb_enter(const char *); void kdb_init(void); +void * kdb_jmpbuf(jmp_buf); int kdb_set_thread(pid_t); int kdb_trap(int, int, struct trapframe *);