From: Daniel Jacobowitz <drow@mvista.com>
To: Jon Ringle <jon.ringle@comdial.com>
Cc: gdb@sources.redhat.com
Subject: Re: Infinite backtrace on arm
Date: Mon, 27 Oct 2003 14:53:00 -0000 [thread overview]
Message-ID: <20031027145320.GA26422@nevyn.them.org> (raw)
In-Reply-To: <200310260028.13745.jon.ringle@comdial.com>
On Sun, Oct 26, 2003 at 12:28:13AM -0400, Jon Ringle wrote:
> Hi,
>
> I backported arm kgdb to run in an embedded arm target running 2.2.16 kernel.
> I can debug the the target for the most part with gdb-5.3 over a serial
> connection. However, sometimes when I ask for a backtrace, the bt gets stuck
> recursing at the bottom of the bt. Here is an example:
>
> Breakpoint 9, dimp_proc_bring_dsp_down (p_dsp=0x1022dc00, reason=7) at
> common/micro/dim/dimutl.c:247
> (gdb) bt
> #0 dimp_proc_bring_dsp_down (p_dsp=0x1022dc00, reason=7) at
> common/micro/dim/dimutl.c:247
> #1 0x1005dff4 in dimp_bring_dsp_down (p_dsp=0x1022dc00,
> reason=DIM_DSP_ERR_OK) at common/micro/dim/dimutl.c:74
> #2 0x1005ae20 in dimp_check_dsp_msgs () at common/micro/dim/dimdsp.c:1831
> #3 0x100557a8 in dim_process_poll () at common/micro/dim/dimcomm.c:107
> #4 0x10067d78 in dsp_timer1intHandler (irq=0, dev_id=0x0, regs=0x1018a820) at
> dspdriver.c:169
> #5 0x1000c004 in do_IRQ (irq=1, regs=0x10ffdfa8) at irq.c:247
> #6 0x1000b200 in linux_VECTOR_IRQ ()
> #7 0x1000b200 in linux_VECTOR_IRQ ()
> #8 0x1000b200 in linux_VECTOR_IRQ ()
> [repeated ad infinitum...]
>
> I found the following code check at blockframe.c:496 that is supposed to trap
> this situation:
>
> /* If ->frame and ->pc are unchanged, we are in the process of getting
> ourselves into an infinite backtrace. Some architectures check this
> in FRAME_CHAIN or thereabouts, but it seems like there is no reason
> this can't be an architecture-independent check. */
> if (next_frame != NULL)
> {
> if (prev->frame == next_frame->frame
> && prev->pc == next_frame->pc)
> {
> next_frame->prev = NULL;
> obstack_free (&frame_cache_obstack, prev);
> return NULL;
> }
> }
>
> However, I found by debugging gdb that frame was changing by framesize. I
> think (but not confirmed) that this is happening because this is not caught
> by arm_frame_chain() and it is returning with:
> return fi->frame + fi->extra_info->framesize;
>
> I fixed my problem with the following:
> --- gdb/blockframe.c~ 2003-10-26 00:17:13.000000000 -0400
> +++ gdb/blockframe.c 2003-10-26 00:17:53.000000000 -0400
> @@ -499,8 +499,7 @@
> this can't be an architecture-independent check. */
> if (next_frame != NULL)
> {
> - if (prev->frame == next_frame->frame
> - && prev->pc == next_frame->pc)
> + if (prev->pc == next_frame->pc)
> {
> next_frame->prev = NULL;
> obstack_free (&frame_cache_obstack, prev);
>
> I don't think this is the right thing to do, and that a fix is really needed
> in arm_frame_chain(). But I'm not sure what that might be. Does anyone have a
> suggestion?
Well, for starters, I can tell you what the long-term "correct" thing
to do is:
- Use a CVS version of GDB
- Enable DWARF2-based unwinding for ARM; it's disabled in GDB because
of some problems with Thumb unwind info. I'll be working on this
sometime soon.
- Use a version of binutils which supports .cfi_* directives
on ARM - I have patches for this but haven't posted them yet, I'll
try again to do it this week.
- Find a convention for unwind info that should tell GDB to terminate
the backtrace. I don't think there is one right now.
- Annotate your copy of linux_VECTOR_IRQ, which is presumably an
assembly stub, with information to make the backtrace stop. Or to
continue to its caller if it has one and isn't just called through
an interrupt handler.
The problem is that there's not much GDB can do with hand-coded
assembly functions.
However, GDB ought to be able to detect and stop that loop without any
of this. It seems to me that the problem is not two frames with the
same PC, but two frames with their PC "saved" in the same place - i.e.
GDB failing to figure out where the PC is saved. This is made a little
tricky in current versions of GDB, because the PC is normally unwound
using frame_pc_unwind (which doesn't tell us where it was saved, since
the interface doesn't assume it's a single normal register), and the
core code doesn't have a concept of a "PC register" any more.
Andrew, any idea on how to do this?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
next prev parent reply other threads:[~2003-10-27 14:53 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-10-26 4:28 Jon Ringle
2003-10-27 14:53 ` Daniel Jacobowitz [this message]
2003-10-27 15:21 ` Andrew Cagney
2003-10-27 15:23 ` Daniel Jacobowitz
2003-10-27 16:01 Jon Ringle
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20031027145320.GA26422@nevyn.them.org \
--to=drow@mvista.com \
--cc=gdb@sources.redhat.com \
--cc=jon.ringle@comdial.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox