From owner-freebsd-stable@FreeBSD.ORG Fri Aug 19 16:28:08 2011 Return-Path: Delivered-To: freebsd-stable@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 82BE3106566C; Fri, 19 Aug 2011 16:28:08 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from citadel.icyb.net.ua (citadel.icyb.net.ua [212.40.38.140]) by mx1.freebsd.org (Postfix) with ESMTP id 609F08FC17; Fri, 19 Aug 2011 16:28:06 +0000 (UTC) Received: from odyssey.starpoint.kiev.ua (alpha-e.starpoint.kiev.ua [212.40.38.101]) by citadel.icyb.net.ua (8.8.8p3/ICyb-2.3exp) with ESMTP id TAA02123; Fri, 19 Aug 2011 19:28:05 +0300 (EEST) (envelope-from avg@FreeBSD.org) Message-ID: <4E4E8F15.5030301@FreeBSD.org> Date: Fri, 19 Aug 2011 19:28:05 +0300 From: Andriy Gapon User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:5.0) Gecko/20110705 Thunderbird/5.0 MIME-Version: 1.0 To: John Baldwin References: <47F0D04ADF034695BC8B0AC166553371@multiplay.co.uk> <4E4C22D6.6070407@FreeBSD.org> <4E4D717F.3090802@FreeBSD.org> <201108190814.00885.jhb@freebsd.org> In-Reply-To: <201108190814.00885.jhb@freebsd.org> X-Enigmail-Version: 1.2pre Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Cc: freebsd-hackers@FreeBSD.org, freebsd-stable@FreeBSD.org Subject: Re: debugging frequent kernel panics on 8.2-RELEASE X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Aug 2011 16:28:08 -0000 on 19/08/2011 15:14 John Baldwin said the following: > Yes, it is a bug in kgdb that it only walks allproc and not zombproc. Try this: The patch worked perfectly well for me, thank you! > Index: kthr.c > =================================================================== > --- kthr.c (revision 224879) > +++ kthr.c (working copy) > @@ -73,11 +73,52 @@ kgdb_thr_first(void) > return (first); > } > > +static void > +kgdb_thr_add_procs(uintptr_t paddr) > +{ > + struct proc p; > + struct thread td; > + struct kthr *kt; > + CORE_ADDR addr; > + > + while (paddr != 0) { > + if (kvm_read(kvm, paddr, &p, sizeof(p)) != sizeof(p)) { > + warnx("kvm_read: %s", kvm_geterr(kvm)); > + break; > + } > + addr = (uintptr_t)TAILQ_FIRST(&p.p_threads); > + while (addr != 0) { > + if (kvm_read(kvm, addr, &td, sizeof(td)) != > + sizeof(td)) { > + warnx("kvm_read: %s", kvm_geterr(kvm)); > + break; > + } > + kt = malloc(sizeof(*kt)); > + kt->next = first; > + kt->kaddr = addr; > + if (td.td_tid == dumptid) > + kt->pcb = dumppcb; > + else if (td.td_state == TDS_RUNNING && stoppcbs != 0 && > + CPU_ISSET(td.td_oncpu, &stopped_cpus)) > + kt->pcb = (uintptr_t)stoppcbs + > + sizeof(struct pcb) * td.td_oncpu; > + else > + kt->pcb = (uintptr_t)td.td_pcb; > + kt->kstack = td.td_kstack; > + kt->tid = td.td_tid; > + kt->pid = p.p_pid; > + kt->paddr = paddr; > + kt->cpu = td.td_oncpu; > + first = kt; > + addr = (uintptr_t)TAILQ_NEXT(&td, td_plist); > + } > + paddr = (uintptr_t)LIST_NEXT(&p, p_list); > + } > +} > + > struct kthr * > kgdb_thr_init(void) > { > - struct proc p; > - struct thread td; > long cpusetsize; > struct kthr *kt; > CORE_ADDR addr; > @@ -113,37 +154,11 @@ kgdb_thr_init(void) > > stoppcbs = kgdb_lookup("stoppcbs"); > > - while (paddr != 0) { > - if (kvm_read(kvm, paddr, &p, sizeof(p)) != sizeof(p)) { > - warnx("kvm_read: %s", kvm_geterr(kvm)); > - break; > - } > - addr = (uintptr_t)TAILQ_FIRST(&p.p_threads); > - while (addr != 0) { > - if (kvm_read(kvm, addr, &td, sizeof(td)) != > - sizeof(td)) { > - warnx("kvm_read: %s", kvm_geterr(kvm)); > - break; > - } > - kt = malloc(sizeof(*kt)); > - kt->next = first; > - kt->kaddr = addr; > - if (td.td_tid == dumptid) > - kt->pcb = dumppcb; > - else if (td.td_state == TDS_RUNNING && stoppcbs != 0 && > - CPU_ISSET(td.td_oncpu, &stopped_cpus)) > - kt->pcb = (uintptr_t) stoppcbs + sizeof(struct pcb) * td.td_oncpu; > - else > - kt->pcb = (uintptr_t)td.td_pcb; > - kt->kstack = td.td_kstack; > - kt->tid = td.td_tid; > - kt->pid = p.p_pid; > - kt->paddr = paddr; > - kt->cpu = td.td_oncpu; > - first = kt; > - addr = (uintptr_t)TAILQ_NEXT(&td, td_plist); > - } > - paddr = (uintptr_t)LIST_NEXT(&p, p_list); > + kgdb_thr_add_procs(paddr); > + addr = kgdb_lookup("zombproc"); > + if (addr != 0) { > + kvm_read(kvm, addr, &paddr, sizeof(paddr)); > + kgdb_thr_add_procs(paddr); > } > curkthr = kgdb_thr_lookup_tid(dumptid); > if (curkthr == NULL) > >> is there an easy way to examine its stack in this case? > > Hmm, you can use something like this from my kgdb macros. Oh, I completely forgot about them. I hope I will remember where to search for the tricks next time I need them :-) Thank you again! > For amd64: > > # Do a backtrace given %rip and %rbp as args > define bt > set $_rip = $arg0 > set $_rbp = $arg1 > set $i = 0 > while ($_rbp != 0 || $_rip != 0) > printf "%2d: pc ", $i > if ($_rip != 0) > x/1i $_rip > else > printf "\n" > end > if ($_rbp == 0) > set $_rip = 0 > else > set $fr = (struct amd64_frame *)$_rbp > set $_rbp = $fr->f_frame > set $_rip = $fr->f_retaddr > set $i = $i + 1 > end > end > end > > document bt > Given values for %rip and %rbp, perform a manual backtrace. > end > > define btf > bt $arg0.tf_rip $arg0.tf_rbp > end > > document btf > Do a manual backtrace from a specified trapframe. > end > > For i386: > > # Do a backtrace given %eip and %ebp as args > define bt > set $_eip = $arg0 > set $_ebp = $arg1 > set $i = 0 > while ($_ebp != 0 || $_eip != 0) > printf "%2d: pc ", $i > if ($_eip != 0) > x/1i $_eip > else > printf "\n" > end > if ($_ebp == 0) > set $_eip = 0 > else > set $fr = (struct i386_frame *)$_ebp > set $_ebp = $fr->f_frame > set $_eip = $fr->f_retaddr > set $i = $i + 1 > end > end > end > > document bt > Given values for %eip and %ebp, perform a manual backtrace. > end > > define btf > bt $arg0.tf_eip $arg0.tf_ebp > end > > document btf > Do a manual backtrace from a specified trapframe. > end > -- Andriy Gapon