Message ID | BANLkTi=dzYV5tdHaZL91oHjMfuVtXUCD5A@mail.gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Jun 28, 2011 at 04:45:52PM +0100, Dmitry Eremin-Solenikov wrote: > Here is a part of gdb log generated using the attached patch: [...] > #11 0xc0033810 in kernel_thread_helper () > #12 0xc0033810 in kernel_thread_helper () > Backtrace stopped: previous frame identical to this frame (corrupt stack?) Maybe you can add something similar to the kernel_thread_helper in arch/arm/kernel/process.c? I'm not sure whether there is something like .cantunwind (as for the kernel unwinding information). > diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S > index e8d8856..44daf40 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) > #ifdef CONFIG_THUMB2_KERNEL > @@ -146,6 +148,24 @@ ENDPROC(__und_invalid) > @ r4 - orig_r0 (see pt_regs definition in ptrace.h) > @ > stmia r5, {r0 - r4} > + .cfi_def_cfa_offset S_PC + 4 > + .cfi_offset 14, -4 > +#define CFI_REG_OFF(r) .cfi_offset r, (r - 16) * 4 > + CFI_REG_OFF(13) > + CFI_REG_OFF(12) > + CFI_REG_OFF(11) > + CFI_REG_OFF(10) > + CFI_REG_OFF(9) > + CFI_REG_OFF(8) > + CFI_REG_OFF(7) > + CFI_REG_OFF(6) > + CFI_REG_OFF(5) > + CFI_REG_OFF(4) > + CFI_REG_OFF(3) > + CFI_REG_OFF(2) > + CFI_REG_OFF(1) > + CFI_REG_OFF(0) > +#undef CFI_REG_OFF > .endm Do we need all the registers in here for gdb stack unwinding? In general we would only need LR, SP and FP.
On 6/28/11, Catalin Marinas <catalin.marinas@arm.com> wrote: > On Tue, Jun 28, 2011 at 04:45:52PM +0100, Dmitry Eremin-Solenikov wrote: >> Here is a part of gdb log generated using the attached patch: > [...] >> #11 0xc0033810 in kernel_thread_helper () >> #12 0xc0033810 in kernel_thread_helper () >> Backtrace stopped: previous frame identical to this frame (corrupt stack?) > > Maybe you can add something similar to the kernel_thread_helper in > arch/arm/kernel/process.c? I'm not sure whether there is something like > .cantunwind (as for the kernel unwinding information). > >> diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S >> index e8d8856..44daf40 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) >> #ifdef CONFIG_THUMB2_KERNEL >> @@ -146,6 +148,24 @@ ENDPROC(__und_invalid) >> @ r4 - orig_r0 (see pt_regs definition in ptrace.h) >> @ >> stmia r5, {r0 - r4} >> + .cfi_def_cfa_offset S_PC + 4 >> + .cfi_offset 14, -4 >> +#define CFI_REG_OFF(r) .cfi_offset r, (r - 16) * 4 >> + CFI_REG_OFF(13) >> + CFI_REG_OFF(12) >> + CFI_REG_OFF(11) >> + CFI_REG_OFF(10) >> + CFI_REG_OFF(9) >> + CFI_REG_OFF(8) >> + CFI_REG_OFF(7) >> + CFI_REG_OFF(6) >> + CFI_REG_OFF(5) >> + CFI_REG_OFF(4) >> + CFI_REG_OFF(3) >> + CFI_REG_OFF(2) >> + CFI_REG_OFF(1) >> + CFI_REG_OFF(0) >> +#undef CFI_REG_OFF >> .endm > > Do we need all the registers in here for gdb stack unwinding? In general > we would only need LR, SP and FP. CFI info isn't only related to stack unwinding. IIUC (I'll have to run more experiments) these instrutions will help me to get correct variables/arguments values in the before-exception stack frames. > > -- > Catalin > >
On Tue, Jun 28, 2011 at 11:26:28PM +0100, Dmitry Eremin-Solenikov wrote: > On 6/28/11, Catalin Marinas <catalin.marinas@arm.com> wrote: > > On Tue, Jun 28, 2011 at 04:45:52PM +0100, Dmitry Eremin-Solenikov wrote: > >> .macro svc_entry, stack_hole=0 > >> UNWIND(.fnstart ) > >> + .cfi_startproc > >> UNWIND(.save {r0 - pc} ) > >> sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4) > >> #ifdef CONFIG_THUMB2_KERNEL > >> @@ -146,6 +148,24 @@ ENDPROC(__und_invalid) > >> @ r4 - orig_r0 (see pt_regs definition in ptrace.h) > >> @ > >> stmia r5, {r0 - r4} > >> + .cfi_def_cfa_offset S_PC + 4 > >> + .cfi_offset 14, -4 > >> +#define CFI_REG_OFF(r) .cfi_offset r, (r - 16) * 4 > >> + CFI_REG_OFF(13) > >> + CFI_REG_OFF(12) > >> + CFI_REG_OFF(11) > >> + CFI_REG_OFF(10) > >> + CFI_REG_OFF(9) > >> + CFI_REG_OFF(8) > >> + CFI_REG_OFF(7) > >> + CFI_REG_OFF(6) > >> + CFI_REG_OFF(5) > >> + CFI_REG_OFF(4) > >> + CFI_REG_OFF(3) > >> + CFI_REG_OFF(2) > >> + CFI_REG_OFF(1) > >> + CFI_REG_OFF(0) > >> +#undef CFI_REG_OFF > >> .endm > > > > Do we need all the registers in here for gdb stack unwinding? In general > > we would only need LR, SP and FP. > > CFI info isn't only related to stack unwinding. IIUC (I'll have to run > more experiments) these instrutions will help me to get correct > variables/arguments values in the before-exception stack frames. OK, in this case we may need to add some annotations. You could actually generate a .s file from and existing C one (including -g) and see what .cfi directives it generates.
On 6/29/11, Catalin Marinas <catalin.marinas@arm.com> wrote: > On Tue, Jun 28, 2011 at 11:26:28PM +0100, Dmitry Eremin-Solenikov wrote: >> On 6/28/11, Catalin Marinas <catalin.marinas@arm.com> wrote: >> > On Tue, Jun 28, 2011 at 04:45:52PM +0100, Dmitry Eremin-Solenikov wrote: >> >> .macro svc_entry, stack_hole=0 >> >> UNWIND(.fnstart ) >> >> + .cfi_startproc >> >> UNWIND(.save {r0 - pc} ) >> >> sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4) >> >> #ifdef CONFIG_THUMB2_KERNEL >> >> @@ -146,6 +148,24 @@ ENDPROC(__und_invalid) >> >> @ r4 - orig_r0 (see pt_regs definition in ptrace.h) >> >> @ >> >> stmia r5, {r0 - r4} >> >> + .cfi_def_cfa_offset S_PC + 4 >> >> + .cfi_offset 14, -4 >> >> +#define CFI_REG_OFF(r) .cfi_offset r, (r - 16) * 4 >> >> + CFI_REG_OFF(13) >> >> + CFI_REG_OFF(12) >> >> + CFI_REG_OFF(11) >> >> + CFI_REG_OFF(10) >> >> + CFI_REG_OFF(9) >> >> + CFI_REG_OFF(8) >> >> + CFI_REG_OFF(7) >> >> + CFI_REG_OFF(6) >> >> + CFI_REG_OFF(5) >> >> + CFI_REG_OFF(4) >> >> + CFI_REG_OFF(3) >> >> + CFI_REG_OFF(2) >> >> + CFI_REG_OFF(1) >> >> + CFI_REG_OFF(0) >> >> +#undef CFI_REG_OFF >> >> .endm >> > >> > Do we need all the registers in here for gdb stack unwinding? In general >> > we would only need LR, SP and FP. >> >> CFI info isn't only related to stack unwinding. IIUC (I'll have to run >> more experiments) these instrutions will help me to get correct >> variables/arguments values in the before-exception stack frames. > > OK, in this case we may need to add some annotations. You could actually > generate a .s file from and existing C one (including -g) and see what > .cfi directives it generates. Yes, that actually gave me some ideas. Unfortunately entry*.S files are a bit ... uncommon, so there are nearly no 1-1 cases. BTW: It seems x86 has .cfi annotations connected to most if not all assembler commands. I think this is a bit too much, but you got the idea.
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index e8d8856..44daf40 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) #ifdef CONFIG_THUMB2_KERNEL @@ -146,6 +148,24 @@ ENDPROC(__und_invalid) @ r4 - orig_r0 (see pt_regs definition in ptrace.h) @ stmia r5, {r0 - r4} + .cfi_def_cfa_offset S_PC + 4 + .cfi_offset 14, -4 +#define CFI_REG_OFF(r) .cfi_offset r, (r - 16) * 4 + CFI_REG_OFF(13) + CFI_REG_OFF(12) + CFI_REG_OFF(11) + CFI_REG_OFF(10) + CFI_REG_OFF(9) + CFI_REG_OFF(8) + CFI_REG_OFF(7) + CFI_REG_OFF(6) + CFI_REG_OFF(5) + CFI_REG_OFF(4) + CFI_REG_OFF(3) + CFI_REG_OFF(2) + CFI_REG_OFF(1) + CFI_REG_OFF(0) +#undef CFI_REG_OFF .endm .align 5 @@ -347,6 +367,7 @@ ENDPROC(__pabt_svc) .macro usr_entry UNWIND(.fnstart ) UNWIND(.cantunwind ) @ don't unwind the user space + .cfi_startproc sub sp, sp, #S_FRAME_SIZE ARM( stmib sp, {r1 - r12} ) THUMB( stmia sp, {r0 - r12} ) @@ -427,6 +448,7 @@ __dabt_usr: mov r2, sp adr lr, BSYM(ret_from_exception) b do_DataAbort + .cfi_endproc UNWIND(.fnend ) ENDPROC(__dabt_usr) @@ -454,6 +476,7 @@ __irq_usr: mov why, #0 b ret_to_user + .cfi_endproc UNWIND(.fnend ) ENDPROC(__irq_usr) @@ -496,6 +519,7 @@ __und_usr: #else b __und_usr_unknown #endif + .cfi_endproc UNWIND(.fnend ) ENDPROC(__und_usr) @@ -691,6 +715,7 @@ __pabt_usr: enable_irq @ Enable interrupts mov r2, sp @ regs bl do_PrefetchAbort @ call abort handler + .cfi_endproc UNWIND(.fnend ) /* fall through */ /* @@ -699,9 +724,11 @@ __pabt_usr: ENTRY(ret_from_exception) UNWIND(.fnstart ) UNWIND(.cantunwind ) + .cfi_startproc get_thread_info tsk mov why, #0 b ret_to_user + .cfi_endproc UNWIND(.fnend ) ENDPROC(__pabt_usr) ENDPROC(ret_from_exception) diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 051166c..5ed13ae 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -86,6 +86,7 @@ #else ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr #endif + .cfi_endproc .endm .macro restore_user_regs, fast = 0, offset = 0