Problem with GDB when debugging IRQ handlers
Dmitry Eremin-Solenikov
dbaryshkov at gmail.com
Tue Jun 28 10:54:11 EDT 2011
On 6/28/11, Dmitry Eremin-Solenikov <dbaryshkov at gmail.com> wrote:
> On 6/28/11, Catalin Marinas <catalin.marinas at arm.com> wrote:
>> On Tue, Jun 28, 2011 at 03:20:45PM +0100, Catalin Marinas wrote:
>>> On Tue, Jun 28, 2011 at 04:06:11PM +0400, Dmitry Eremin-Solenikov wrote:
>>> > On 6/28/11, Russell King - ARM Linux <linux at arm.linux.org.uk> wrote:
>>> > I did some checks. It seems, the problem isn't related to unwinder. At
>>> > least
>>> > it looks like kernel has all necessary unwinding subops. It looks like
>>> > the
>>> > problem is really related to the lack of necessary .cfi information.
>>> > At
>>> > least
>>> > when i added .cfi_startproc/.cfi_endproc annotations to entry-armv.S
>>> > code,
>>> > gdb stopped decoding backtrace with the "previous frame identical to
>>> > this frame"
>>> > error. Unfortunately I don't have enough knowledge to add .cfi
>>> > annotations to
>>> > irq handlers.
>>>
>>> I think it may have stopped decoding because of some information it
>>> reads from the stack doesn't look sane. But I wonder whether we could
>>> get it looping again depending on the register values in the interrupted
>>> context.
>>>
>>> > diff --git a/arch/arm/kernel/entry-armv.S
>>> > b/arch/arm/kernel/entry-armv.S
>>> > index e8d8856..d77f9d7 100644
>>> > --- a/arch/arm/kernel/entry-armv.S
>>> > +++ b/arch/arm/kernel/entry-armv.S
>>> > @@ -28,6 +28,7 @@
>>> > #include "entry-header.S"
>>> > #include <asm/entry-macro-multi.S>
>>> >
>>> > + .cfi_sections .debug_frame
>>> > /*
>>> > * Interrupt handling. Preserves r7, r8, r9
>>> > */
>>> > @@ -113,6 +114,7 @@ ENDPROC(__und_invalid)
>>> >
>>> > .macro svc_entry, stack_hole=0
>>> > UNWIND(.fnstart )
>>> > + .cfi_startproc
>>> > UNWIND(.save {r0 - pc} )
>>> > sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
>>>
>>> Could you add some directives like below in the svc_entry macro (after
>>> "sub sp...", not sure if it matters) and check whether gdb behaves
>>> better:
>>>
>>> .cfi_def_cfa_offset S_PC
>>> .cfi_offset 14, -4
>>
>> Actually since the return address is in S_PC (which maybe gdb assumes it
>> would be the saved LR), this is probably not be correct. After SVC
>> entry, we have he following structure on the stack:
>>
>> ORIG_r0
>> CPSR
>> <--- assuming this is the Call Frame Address (SP+S_PC+4)
>> PC <--- CFA - 4
>> LR <--- don't care
>> SP <--- CFA - 12
>> ...
>>
>>
>> So we tell gdb about this with something like below (untested):
>>
>> .cfi_def_cfa_offset S_PC + 4
>> .cfi_offset 14, -4
>> .cfi_offset 13, -12
>
> This brings "unknown CFA rule" gdb exception, but it seems I got your idea.
No, this seems to work, it was my fault. I got more or less reasonable
backtrace now.
--
With best wishes
Dmitry
More information about the linux-arm-kernel
mailing list