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