pg打桩调试技术在调用每个函数中增加一个计数器,来统计函数的调用顺序,待进程崩溃时打印出函数的调用顺序进行问题定位分析。
代码
arm-linux-gnueabihf-gcc -c arm_mcount.c -o arm_mcount.o
arm-linux-gnueabihf-gcc -pg arm_mcount.o main.c -o tt
不能直接通过gcc单步把.c文件编译成可执行文件,如:arm-linux-gnueabihf-gcc -pg arm_mcount_thread_v2.c main.c -o tt,因为gcc简化流程后会把自己的打桩函数也打桩,这样跑程序会报崩溃;应该单步编译成.o文件后,再全部链接.o文件成可执行文件。
root@www:~# ./tt 单步编译执行崩溃
pgd = cb294000
[be1acffc] *pgd=8b284835, *pte=00000000, *ppte=00000000
CPU: 0 PID: 791 Comm: tt Not tainted 4.9.11 #4
Hardware name: Freescale i.MX6 UltraLite (Device Tree)
task: c67bf300 task.stack: cb288000
PC is at 0x8610
LR is at 0x8617
pc : [<00008610>] lr : [<00008617>] psr: 400d0030
sp : be1ad000 ip : be9acdb0 fp : 00000000
r10: b6fd6000 r9 : 00000000 r8 : 00000000
r7 : be9acd28 r6 : 00000000 r5 : 00000000 r4 : be9acd48
r3 : 00008961 r2 : be9ace8c r1 : be9ace84 r0 : 00000001
Flags: nZcv IRQs on FIQs on Mode USER_32 ISA Thumb Segment user
Control: 10c53c7d Table: 8b294059 DAC: 00000055
CPU: 0 PID: 791 Comm: tt Not tainted 4.9.11 #4
Hardware name: Freescale i.MX6 UltraLite (Device Tree)
[<c010e540>] (unwind_backtrace) from [<c010b61c>] (show_stack+0x18/0x1c)
[<c010b61c>] (show_stack) from [<c0113300>] (__do_user_fault+0x84/0xcc)
[<c0113300>] (__do_user_fault) from [<c01135b8>] (do_page_fault+0x270/0x314)
[<c01135b8>] (do_page_fault) from [<c0101324>] (do_DataAbort+0x3c/0xbc)
[<c0101324>] (do_DataAbort) from [<c010c41c>] (__dabt_usr+0x3c/0x40)
Exception stack(0xcb289fb0 to 0xcb289ff8)
9fa0: 00000001 be9ace84 be9ace8c 00008961
9fc0: be9acd48 00000000 00000000 be9acd28 00000000 00000000 b6fd6000 00000000
9fe0: be9acdb0 be1ad000 00008617 00008610 400d0030 ffffffff
Segmentation fault
反汇编查看:自己调用了自己导致了问题
00008610 <__gnu_mcount_nc>:
8610: b500 push {lr}
8612: f7ff fffd bl 8610 <__gnu_mcount_nc>
8616: e92d 43ff stmdb sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, lr}
861a: 4673 mov r3, lr
861c: 461d mov r5, r3
861e: 20e0 movs r0, #224 ; 0xe0
8620: f7ff ef22 blx 8468 <_init+0x80>
8624: 4603 mov r3, r0
8626: 4618 mov r0, r3
8628: f7ff ffbe bl 85a8 <find_tstack>
862c: 4604 mov r4, r0
862e: 2c00 cmp r4, #0
8630: d013 beq.n 865a <__gnu_mcount_nc+0x4a>
8632: 6821 ldr r1, [r4, #0]
8634: 6862 ldr r2, [r4, #4]
8636: 1c53 adds r3, r2, #1
8638: 6063 str r3, [r4, #4]
应用测试代码:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
static void signal_bus_err(int sig)
{
printf("Signal Error! Signal is %d \n", sig);
// 调用pg打桩显示函数
mcount_show(NULL);
}
void fun()
{
return;
}
void main()
{
mcount_init(1, NULL);
signal(SIGSEGV, signal_bus_err);
signal(SIGFPE, signal_bus_err);
signal(SIGILL, signal_bus_err);
fun();
}
非法指令错误
typedef unsigned int(*hash_func_t)(unsigned int,void *);
hash_func_t hash_func;
static unsigned int hash_func_tt(unsigned int bucktes, void *key)
{
printf("eason bucktes=%d \n", bucktes);
return 0;
}
void fun()
{
hash_func = 0x8500;
hash_func(1024, NULL);
return;
}
./tt
Signal Error! Signal is 4
cnt:0 Function called by 00000000
cnt:96 Function called by 00000000
cnt:97 Function called by 000087d3
cnt:98 Function called by 000087a3
cnt:99 Function called by 0000877d
end
00008770 <signal_bus_err>:
8770: b580 push {r7, lr}
8772: b082 sub sp, #8
8774: af00 add r7, sp, #0
8776: b500 push {lr}
8778: f7ff ff04 bl 8584 <__gnu_mcount_nc>
877c: 6078 str r0, [r7, #4]
877e: 6879 ldr r1, [r7, #4]
8780: f648 00cc movw r0, #35020 ; 0x88cc
8784: f2c0 0000 movt r0, #0
8788: f7ff ee18 blx 83bc <_init+0x20>
878c: 2000 movs r0, #0
878e: f7ff ff43 bl 8618 <mcount_show>
8792: 3708 adds r7, #8
8794: 46bd mov sp, r7
8796: bd80 pop {r7, pc}
00008798 <fun>:
8798: b580 push {r7, lr}
879a: af00 add r7, sp, #0
879c: b500 push {lr}
879e: f7ff fef1 bl 8584 <__gnu_mcount_nc>
87a2: f640 33b8 movw r3, #3000 ; 0xbb8
87a6: f2c0 0301 movt r3, #1
87aa: f44f 4205 mov.w r2, #34048 ; 0x8500
87ae: 601a str r2, [r3, #0]
87b0: f640 33b8 movw r3, #3000 ; 0xbb8
87b4: f2c0 0301 movt r3, #1
87b8: 681b ldr r3, [r3, #0]
87ba: 2100 movs r1, #0
87bc: f44f 6080 mov.w r0, #1024 ; 0x400
87c0: 4798 blx r3
87c2: bf00 nop
87c4: bd80 pop {r7, pc}
87c6: bf00 nop
000087c8 <main>:
87c8: b580 push {r7, lr}
87ca: af00 add r7, sp, #0
87cc: b500 push {lr}
87ce: f7ff fed9 bl 8584 <__gnu_mcount_nc>
87d2: 2100 movs r1, #0
87d4: 2001 movs r0, #1
87d6: f7ff ff91 bl 86fc <mcount_init>
87da: f248 7171 movw r1, #34673 ; 0x8771
87de: f2c0 0100 movt r1, #0
87e2: 200b movs r0, #11
87e4: f7ff edf6 blx 83d4 <_init+0x38>
87e8: f248 7171 movw r1, #34673 ; 0x8771
87ec: f2c0 0100 movt r1, #0
87f0: 2008 movs r0, #8
87f2: f7ff edf0 blx 83d4 <_init+0x38>
87f6: f248 7171 movw r1, #34673 ; 0x8771
87fa: f2c0 0100 movt r1, #0
87fe: 2004 movs r0, #4
8800: f7ff ede8 blx 83d4 <_init+0x38>
8804: f7ff ffc8 bl 8798 <fun>
8808: bd80 pop {r7, pc}
880a: bf00 nop
可以看到最后一个函数是signal_bus_err,倒数第二个是fun,最后一个是main函数,所以是在fun函数有异常,需要看代码才能确定具体问题。
非法内存
void fun()
{
int *p = NULL;
p[0] = 1;
return;
}
root@www:~# ./tt
Signal Error! Signal is 11
cnt:0 Function called by 00000000
cnt:96 Function called by 00000000
cnt:97 Function called by 000087c7
cnt:98 Function called by 000087a5
cnt:99 Function called by 0000877d
00008770 <signal_bus_err>:
8770: b580 push {r7, lr}
8772: b082 sub sp, #8
8774: af00 add r7, sp, #0
8776: b500 push {lr}
8778: f7ff ff04 bl 8584 <__gnu_mcount_nc>
877c: 6078 str r0, [r7, #4]
877e: 6879 ldr r1, [r7, #4]
8780: f648 00bc movw r0, #35004 ; 0x88bc
8784: f2c0 0000 movt r0, #0
8788: f7ff ee18 blx 83bc <_init+0x20>
878c: 2000 movs r0, #0
878e: f7ff ff43 bl 8618 <mcount_show>
8792: 3708 adds r7, #8
8794: 46bd mov sp, r7
8796: bd80 pop {r7, pc}
00008798 <fun>:
8798: b480 push {r7}
879a: b083 sub sp, #12
879c: af00 add r7, sp, #0
879e: b500 push {lr}
87a0: f7ff fef0 bl 8584 <__gnu_mcount_nc>
87a4: 2300 movs r3, #0
87a6: 607b str r3, [r7, #4]
87a8: 687b ldr r3, [r7, #4]
87aa: 2201 movs r2, #1
87ac: 601a str r2, [r3, #0]
87ae: bf00 nop
87b0: 370c adds r7, #12
87b2: 46bd mov sp, r7
87b4: f85d 7b04 ldr.w r7, [sp], #4
87b8: 4770 bx lr
87ba: bf00 nop
000087bc <main>:
87bc: b580 push {r7, lr}
87be: af00 add r7, sp, #0
87c0: b500 push {lr}
87c2: f7ff fedf bl 8584 <__gnu_mcount_nc>
87c6: 2100 movs r1, #0
87c8: 2001 movs r0, #1
87ca: f7ff ff97 bl 86fc <mcount_init>
87ce: f248 7171 movw r1, #34673 ; 0x8771
87d2: f2c0 0100 movt r1, #0
87d6: 200b movs r0, #11
87d8: f7ff edfc blx 83d4 <_init+0x38>
87dc: f248 7171 movw r1, #34673 ; 0x8771
87e0: f2c0 0100 movt r1, #0
87e4: 2008 movs r0, #8
87e6: f7ff edf6 blx 83d4 <_init+0x38>
87ea: f248 7171 movw r1, #34673 ; 0x8771
87ee: f2c0 0100 movt r1, #0
87f2: 2004 movs r0, #4
87f4: f7ff edee blx 83d4 <_init+0x38>
87f8: f7ff ffce bl 8798 <fun>
87fc: bd80 pop {r7, pc}
87fe: bf00 nop
浮点运算异常
void fun()
{
int a = 10;
int b = 0;
int c = a/b;
return;
}
root@www:~# ./tt
Signal Error! Signal is 8
cnt:0 Function called by 00000000
cnt:96 Function called by 00000000
cnt:97 Function called by 000087fb
cnt:98 Function called by 000087d5
cnt:99 Function called by 000087ad
000087a0 <signal_bus_err>:
87a0: b580 push {r7, lr}
87a2: b082 sub sp, #8
87a4: af00 add r7, sp, #0
87a6: b500 push {lr}
87a8: f7ff ff04 bl 85b4 <__gnu_mcount_nc>
87ac: 6078 str r0, [r7, #4]
87ae: 6879 ldr r1, [r7, #4]
87b0: f648 30b4 movw r0, #35764 ; 0x8bb4
87b4: f2c0 0000 movt r0, #0
87b8: f7ff ee18 blx 83ec <_init+0x2c>
87bc: 2000 movs r0, #0
87be: f7ff ff43 bl 8648 <mcount_show>
87c2: 3708 adds r7, #8
87c4: 46bd mov sp, r7
87c6: bd80 pop {r7, pc}
000087c8 <fun>:
87c8: b580 push {r7, lr}
87ca: b084 sub sp, #16
87cc: af00 add r7, sp, #0
87ce: b500 push {lr}
87d0: f7ff fef0 bl 85b4 <__gnu_mcount_nc>
87d4: 230a movs r3, #10
87d6: 60fb str r3, [r7, #12]
87d8: 2300 movs r3, #0
87da: 60bb str r3, [r7, #8]
87dc: 68b9 ldr r1, [r7, #8]
87de: 68f8 ldr r0, [r7, #12]
87e0: f000 f82a bl 8838 <__aeabi_idiv>
87e4: 4603 mov r3, r0
87e6: 607b str r3, [r7, #4]
87e8: bf00 nop
87ea: 3710 adds r7, #16
87ec: 46bd mov sp, r7
87ee: bd80 pop {r7, pc}
000087f0 <main>:
87f0: b580 push {r7, lr}
87f2: af00 add r7, sp, #0
87f4: b500 push {lr}
87f6: f7ff fedd bl 85b4 <__gnu_mcount_nc>
87fa: 2100 movs r1, #0
87fc: 2001 movs r0, #1
87fe: f7ff ff95 bl 872c <mcount_init>
8802: f248 71a1 movw r1, #34721 ; 0x87a1
8806: f2c0 0100 movt r1, #0
880a: 200b movs r0, #11
880c: f7ff edfa blx 8404 <_init+0x44>
8810: f248 71a1 movw r1, #34721 ; 0x87a1
8814: f2c0 0100 movt r1, #0
8818: 2008 movs r0, #8
881a: f7ff edf4 blx 8404 <_init+0x44>
881e: f248 71a1 movw r1, #34721 ; 0x87a1
8822: f2c0 0100 movt r1, #0
8826: 2004 movs r0, #4
8828: f7ff edec blx 8404 <_init+0x44>
882c: f7ff ffcc bl 87c8 <fun>
8830: bd80 pop {r7, pc}
8832: bf00 nop
8834: 0000 movs r0, r0
...
调试
反汇编参考: