2013年9月20日 星期五

Using arm gdb to find crash line of source file

1.
Make sure in default config
#CONFIG_ARM_UNWIND is not set
CONFIG_DEBUG_INFO=y
CONFIG_FRAME_POINTER=y
CONFIG_FRAME_POINTER depend on follows
CONFIG_CC_OPTIMIZE_FOR_SIZE=n
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_DYNAMIC_FTRACE=y

2.check structure~myandroid/kernel_imx/arch/arm/include/uapi/asm/ptrace.h
struct pt_regs
{
  long uregs[18];
};

#define ARM_pc uregs[15]
#define ARM_lr uregs[14]

3.
in ~myandroid/kernel_imx/arch/arm/mm/fault.c
static void __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
/*** begin: issue ***/
    printk(KERN_INFO "arm-linux-eabi-gdb trace last call function of LR-> 0x%x\n", (unsigned int)regs->uregs[14]);
    printk(KERN_INFO "arm-linux-eabi-gdb trace last crash address of PC-> 0x%x\n", (unsigned int)regs->uregs[15]);
/*** end: issue ***/

if (fixup_exception(regs)) //search .text.fixup section and execute them
      return;
.
.
.

}

4.
~myandroid/kernel_imx/arch/arm/mm/extable.c
int fixup_exception(struct pt_regs *regs)
{
    const struct exception_table_entry *fixup;
    fixup = search_exception_tables(instruction_pointer(regs));
    if (fixup)
    {
        regs->ARM_pc = fixup->fixup;
#ifdef CONFIG_THUMB2_KERNEL
        /* Clear the IT state to avoid nasty surprises in the fixup */
        regs->ARM_cpsr &= ~PSR_IT_MASK;
#endif

        /*** begin: issue ***/
        printk(KERN_INFO "arm-linux-eabi-gdb trace remedial section of .text.fixup-> 0x%x\n", (unsigned int)fixup->fixup);
        /*** end: issue ***/
    }

    return fixup != NULL;
}

5.
Assume we get
ureg14 = LR = 0xc0a8bba0
ureg15 = PC = 0xc05c7634

//use arm gdb in cleint console
/mnt/projects/marsh_mnt/myandroid/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-gdb /mnt/projects/marsh_mnt/out/matrix_io/kernel/vmlinux

(gdb) disassemble /m 0xc0a8bba0,0xc0a8bba0+0x32
Dump of assembler code from 0xc0a8bba0 to 0xc0a8bbd2:
413        if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
   0xc0a8bba0 <dev_ioctl+652>:    cmp    r0, #0
   0xc0a8bba4 <dev_ioctl+656>:    beq    0xc0a8bbc0 <dev_ioctl+684>
   0xc0a8bba8 <dev_ioctl+660>:    b    0xc0a8c244 <dev_ioctl+2352>

414            return -EFAULT;
   0xc0a8bbb8 <dev_ioctl+676>:    mvn    r4, #13
   0xc0a8bbbc <dev_ioctl+680>:    b    0xc0a8c28c <dev_ioctl+2424>

415   
416        ifr.ifr_name[IFNAMSIZ-1] = 0;
   0xc0a8bbc0 <dev_ioctl+684>:    mov    r3, #0
   0xc0a8bbc4 <dev_ioctl+688>:    strb    r3, [r11, #-61]    ; 0x3d

417   
418        colon = strchr(ifr.ifr_name, ':');
   0xc0a8bbc8 <dev_ioctl+692>:    sub    r0, r11, #76    ; 0x4c
   0xc0a8bbcc <dev_ioctl+696>:    mov    r1, #58    ; 0x3a
   0xc0a8bbd0 <dev_ioctl+700>:    bl    0xc05c9de0 <strchr>

//and

(gdb) disassemble /m 0xc05c7634,0xc05c7634+0x32
Dump of assembler code from 0xc05c7634 to 0xc05c7666:
135    4:        ldr8w    r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
   0xc05c7634 <__copy_from_user+76>:    ldr    r3, [r1], #4
   0xc05c7638 <__copy_from_user+80>:    ldr    r4, [r1], #4
   0xc05c763c <__copy_from_user+84>:    ldr    r5, [r1], #4
   0xc05c7640 <__copy_from_user+88>:    ldr    r6, [r1], #4
   0xc05c7644 <__copy_from_user+92>:    ldr    r7, [r1], #4
   0xc05c7648 <__copy_from_user+96>:    ldr    r8, [r1], #4
   0xc05c764c <__copy_from_user+100>:    ldr    r12, [r1], #4
   0xc05c7650 <__copy_from_user+104>:    ldr    lr, [r1], #4

136            subs    r2, r2, #32
   0xc05c7654 <__copy_from_user+108>:    subs    r2, r2, #32

137            str8w    r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
   0xc05c7658 <__copy_from_user+112>:    stmia    r0!, {r3, r4, r5, r6, r7, r8, r12, lr}

138            bge    3b
   0xc05c765c <__copy_from_user+116>:    bge    0xc05c7630 <__copy_from_user+72>

139        PLD(    cmn    r2, #96            )
   0xc05c7660 <__copy_from_user+120>:    cmn    r2, #96    ; 0x60

140        PLD(    bge    4b            )
   0xc05c7664 <__copy_from_user+124>:    bge    0xc05c7634 <__copy_from_user+76>

*(gdb) disassemble /m address,address+0x32
*If dump empty then change [0x32] to any other value like 0x16 0x64 0x128

6.
(gdb) info line *0xc0a8bba0
Line 413 of "/mnt/projects/marsh_mnt/myandroid/kernel_imx/net/core/dev_ioctl.c"
   starts at address 0xc0a8bba0 <dev_ioctl+652>
   and ends at 0xc0a8bbac <dev_ioctl+664>.

//and

(gdb) info line *0xc05c7634
Line 135 of "/mnt/projects/marsh_mnt/myandroid/kernel_imx/arch/arm/lib/copy_from_user.S" starts at address 0xc05c7634 <__copy_from_user+76>
   and ends at 0xc05c7654 <__copy_from_user+108>.

7.
find source dev_ioctl.c -> if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))  
find source copy_template.S -> 4: ldr8w  r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f

沒有留言:

張貼留言