Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Apr 2011 08:45:11 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-current@freebsd.org
Cc:        Justin Hibbits <chmeeedalf@gmail.com>, Navdeep Parhar <nparhar@gmail.com>, FreeBSD Current <current@freebsd.org>
Subject:   Re: KGDB stack traces in the kernel.
Message-ID:  <201104060845.11771.jhb@freebsd.org>
In-Reply-To: <BANLkTinPdVUac6YGwf4GvOE7gtndbQERaQ@mail.gmail.com>
References:  <4D9A4CE5.5090900@freebsd.org> <4D9B7C92.6030901@freebsd.org> <BANLkTinPdVUac6YGwf4GvOE7gtndbQERaQ@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tuesday, April 05, 2011 4:35:44 pm Navdeep Parhar wrote:
> On Tue, Apr 5, 2011 at 1:33 PM, Julian Elischer <julian@freebsd.org> wrote:
> > On 4/4/11 6:04 PM, Justin Hibbits wrote:
> >>
> >> On Apr 4, 2011, at 6:57 PM, Julian Elischer wrote:
> >>>
> >>> is there anyone here with enough gdb/kgdb source experience to know what
> >>> we would need to put on the stack at fork_exit() to make it stop when it
> >>> gets there?
> >>>
> >>> not only is it annoying but it slows down debugging because kgdb and the
> >>> ddd
> >>> front end ask for stacks a LOT. sometimes it actually just hangs as the
> >>> stack
> >>> goes into a loop and never ends.
> >>>
> >>> I had a quick look but didn't spot how gdb decides it has reached the 
end
> >>> of a stack.
> >>>
> >>> Julian
> >>
> >> From my experience, it checks for a NULL stack chain pointer.  Once that
> >> reaches NULL, it's the end of the stack.
> >>
> >> - Justin
> >>
> > I'll try adding NULL when we build the intial stack up.
> > :-)
> 
> What does ddb do?  It always seems to get this stuff correct.

ddb knows to stop when it gets to a non-kernel address, and it uses string
compares on function names to identify trap frames.  For example in 
sys/amd64/amd64/db_trace.c:


                if (strcmp(name, "calltrap") == 0 ||
                    strcmp(name, "fork_trampoline") == 0 ||
                    strcmp(name, "nmi_calltrap") == 0 ||
                    strcmp(name, "Xdblfault") == 0)
                        frame_type = TRAP;

Hah, kgdb just needs to be updated (this is from trgt_amd64.c):

const struct frame_unwind *
kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame)
{
        char *pname;
        CORE_ADDR pc;

        pc = frame_pc_unwind(next_frame);
        pname = NULL;
        find_pc_partial_function(pc, &pname, NULL, NULL);
        if (pname == NULL)
                return (NULL);
        if (strcmp(pname, "calltrap") == 0 ||
            strcmp(pname, "nmi_calltrap") == 0 ||
            (pname[0] == 'X' && pname[1] != '_'))
                return (&kgdb_trgt_trapframe_unwind);
        /* printf("%s: %lx =%s\n", __func__, pc, pname); */
        return (NULL);
}

Can probably just add 'fork_trampoline' to that conditional.  I think i386 
needs a similar fix in kgdb.  Not sure about other architectures:

Index: trgt_amd64.c
===================================================================
--- trgt_amd64.c	(revision 220190)
+++ trgt_amd64.c	(working copy)
@@ -184,6 +184,7 @@
 	if (pname == NULL)
 		return (NULL);
 	if (strcmp(pname, "calltrap") == 0 ||
+	    strcmp(pname, "fork_trampoline") == 0 ||
 	    strcmp(pname, "nmi_calltrap") == 0 ||
 	    (pname[0] == 'X' && pname[1] != '_'))
 		return (&kgdb_trgt_trapframe_unwind);
Index: trgt_i386.c
===================================================================
--- trgt_i386.c	(revision 220190)
+++ trgt_i386.c	(working copy)
@@ -374,6 +374,7 @@
 	if (strcmp(pname, "dblfault_handler") == 0)
 		return (&kgdb_trgt_dblfault_unwind);
 	if (strcmp(pname, "calltrap") == 0 ||
+	    strcmp(pname, "fork_trampoline") == 0 ||
 	    (pname[0] == 'X' && pname[1] != '_'))
 		return (&kgdb_trgt_trapframe_unwind);
 	/* printf("%s: %llx =%s\n", __func__, pc, pname); */

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104060845.11771.jhb>