日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

栈回溯技术arm_v5t_le版

發(fā)布時間:2024/3/26 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 栈回溯技术arm_v5t_le版 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

棧回溯技術(shù)arm_v5t_le

From:韋東山?2007.04.03棧回溯技術(shù)及uClibc的堆實現(xiàn)原理.doc

1.??? 前言

段錯誤、非法地址訪問等問題導致程序崩潰的現(xiàn)象屢屢發(fā)生,如果能找到發(fā)生錯誤的函數(shù),往往一眼就能看出BUG所在——對于這類比較簡單的問題,比如使用空指針進行讀寫等,利用棧回溯技術(shù)可以很快定位。但是對于數(shù)組溢出、內(nèi)存泄漏等問題導致的程序錯誤,往往隱藏很深,它們并不當場發(fā)作,即使我們一步一步跟蹤到發(fā)生錯誤的語句時,也經(jīng)常會讓人覺得“這個地方根本不可能出錯啊”——錯誤在很早以前就隱藏下來了,只不過是這個“不可能出錯的語句”觸發(fā)了它。了解棧的作用、堆的實現(xiàn),可以讓我們腦中對程序的運行、函數(shù)的調(diào)用、變量的操作有個感官的了解,對解決這類問題會有所幫助。

?

???????關(guān)鍵詞:堆棧回溯堆實現(xiàn)棧作用

2.??? 棧的作用

一個程序包含代碼段、數(shù)據(jù)段、BSS段、堆、棧;其中數(shù)據(jù)段用來中存儲初始值不為0的全局數(shù)據(jù),BSS段用來存儲初始值為0的全局數(shù)據(jù),堆用于動態(tài)內(nèi)存分配,棧用于實現(xiàn)函數(shù)調(diào)用、存儲局部變量。比如對于如下程序:

程序1 section.c

01 #include <stdlib.h>

02 #include <string.h>

03 #include <stdio.h>

04

05 int *g_pBuf;

06 int g_iCount = 10;

07

08 int main(int argc, char **argv)

09 {

10 ????char str[2];

11 ????g_pBuf = malloc(g_iCount);

12? ???printf("Address of main?????? = 0x%08x\n", (unsigned int)main);

13? ???printf("Address of g_pBuf???? = 0x%08x\n", (unsigned int)&g_pBuf);

14 ????printf("Address of g_iCount?? = 0x%08x\n", (unsigned int)&g_iCount);

15 ????printf("Address of malloc buf ?= 0x%08x\n", (unsigned int)g_pBuf);

16 ????printf("Address of local buf str ?= 0x%08x\n", (unsigned int)str);

17

18?? ??return 0;

19 }

使用如下命令編譯得到可執(zhí)行文件section,反匯編文件section.dis

arm_v5t_le-gcc? -o? section? section.c -static

arm_v5t_le-objdump -D section > section.dis

?

PU S980上的linux環(huán)境下,這個程序的輸出結(jié)果為:

Address of main?????? = 0x000082b8

Address of g_pBuf???? = 0x00082998

Address of g_iCount?? = 0x00080bd0

Address of malloc buf? = 0x00083f80

Address of local buf str? = 0xbec80b36

?

????????其中main函數(shù)的地址為0x000082b8,它處于代碼段中;全局變量g_pBuf位于BSS段;全局變量g_iCount位于數(shù)據(jù)段;使用malloc分配出來的內(nèi)存地址為0x00083f80,它位于堆中;局部變量str數(shù)組的開始地址為0xbec80b36,位于棧中。它們的分布圖示如下:

1?程序各段示意圖

?

棧的作用有二:

?????保存調(diào)用者的環(huán)境——某些寄存器的值、返回地址

?????存儲局部變量

?

現(xiàn)在通過一個簡單的例子來說明棧的作用:

程序2 call.c

01 #include <stdlib.h>

02 #include <string.h>

03 #include <stdio.h>

04

05 void A(int a);

06 void B(int b);

07 void C(int c);

08

09 void A(int a)

10 {

11???? printf("%d: A call B\n", a);

12???? B(2);

13 }

14

15 void B(int b)

16 {

17???? printf("%d: B call C\n", b);

18???? C(3);

19 }

20

21 void C(int c)

22 {

23???? printf("%d: function C\n", c);

24 }

25

26 int main(int argc, char **argv)

27 {??

28???? A(1);

29???? return 0;

30 }

?

使用如下命令編譯得到可執(zhí)行文件call,反匯編文件call.dis

arm_v5t_le-gcc -o? call? call.c? -static

arm_v5t_le-objdump -D call > call.dis

?

此程序的調(diào)用關(guān)系為main > A > B > C,現(xiàn)在來看看棧如何變化:

?

2?函數(shù)調(diào)用中棧的變化

?

???????上圖中,mainABC四個函數(shù)的棧大小都是16字節(jié),返回地址都存在棧偏移地址為16的地方。我們是如何知道這點的呢?需要閱讀反匯編代碼:

……

000082b8 <A>:

????82b8:?????? e92d4800??????? push??? {fp, lr}

??? 82bc:?????? e28db004??????? add???? fp, sp, #4????? ; 0x4

????82c0:?????? e24dd008??????? sub???? sp, sp, #8????? ; 0x8

??? 82c4:?????? e50b0008??????? str???? r0, [fp, #-8]

??? 82c8:?????? e59f0014??????? ldr???? r0, [pc, #20]?? ; 82e4 <A+0x2c>

??? 82cc:?????? e51b1008??????? ldr???? r1, [fp, #-8]

??? 82d0:?????? eb0003f8??????? bl????? 92b8 <_IO_printf>

??? 82d4:?????? e3a00002??????? mov???? r0, #2? ; 0x2

??? 82d8:?????? eb000002??????? bl????? 82e8 <B>

??? 82dc:?????? e24bd004??????? sub???? sp, fp, #4????? ; 0x4

????82e0:?????? e8bd8800??????? pop???? {fp, pc}

??? 82e4:?????? 00064584??????? .word?? 0x00064584

?

000082e8 <B>:

????82e8:?????? e92d4800??????? push??? {fp, lr}

??? 82ec:?????? e28db004??????? add???? fp, sp, #4????? ; 0x4

????82f0:?????? e24dd008??????? sub???? sp, sp, #8????? ; 0x8

??? 82f4:?????? e50b0008??????? str???? r0, [fp, #-8]

??? 82f8:?????? e59f0014??????? ldr???? r0, [pc, #20]?? ; 8314 <B+0x2c>

??? 82fc:?????? e51b1008??????? ldr???? r1, [fp, #-8]

??? 8300:?????? eb0003ec??????? bl????? 92b8 <_IO_printf>

??? 8304:?????? e3a00003??????? mov???? r0, #3? ; 0x3

??? 8308:?????? eb000002??????? bl????? 8318 <C>

??? 830c:?????? e24bd004??????? sub???? sp, fp, #4????? ; 0x4

????8310:?????? e8bd8800??????? pop???? {fp, pc}

??? 8314:?????? 00064594??????? .word?? 0x00064594

?

00008318 <C>:

????8318:?????? e92d4800??????? push??? {fp, lr}

??? 831c:?????? e28db004??????? add???? fp, sp, #4????? ; 0x4

????8320:??? ???e24dd008??????? sub???? sp, sp, #8????? ; 0x8

??? 8324:?????? e50b0008??????? str???? r0, [fp, #-8]

??? 8328:?????? e59f000c??????? ldr???? r0, [pc, #12]?? ; 833c <C+0x24>

??? 832c:?????? e51b1008??????? ldr???? r1, [fp, #-8]

??? 8330:?????? eb0003e0?? ?????bl????? 92b8 <_IO_printf>

??? 8334:?????? e24bd004??????? sub???? sp, fp, #4????? ; 0x4

????8338:?????? e8bd8800??????? pop???? {fp, pc}

??? 833c:?????? 000645a4??????? .word?? 0x000645a4

?

00008340 <main>:

????8340:?????? e92d4800??????? push??? {fp, lr}

??? 8344:?????? e28db004??????? add???? fp, sp, #4????? ; 0x4

????8348:?????? e24dd008??????? sub???? sp, sp, #8????? ; 0x8

??? 834c:?????? e50b0008??????? str???? r0, [fp, #-8]

??? 8350:?????? e50b100c??????? str???? r1, [fp, #-12]

8354:?????? e3a00001??????? mov???? r0, #1? ; 0x1

8358:?????? ebffffd6??????? bl????? 82b8 <A>

835c:?????? e3a03000??????? mov???? r3, #0? ; 0x0

8360:?????? e1a00003??????? mov???? r0, r3

8364:?????? e24bd004??????? sub???? sp, fp, #4????? ; 0x4

8368:???????e8bd8800??????? pop???? {fp, pc}

?

???????上面紅色的指令:

push????{fp, lr}”表示將fp,lr?寄存器進行壓棧,同時?sp – 4×2,即向下移動?8?個字節(jié)。

sub?????sp, sp, #8”表示將?sp?寄存器的值減?8,即向下移動?8?個字節(jié)。

pop?????{fp, pc}”表示彈出棧頂值到?fp?lr?寄存器,同時?sp+4×2,即向上移動?8?個字節(jié)。

???????局部變量也是存儲在棧中,當一個函數(shù)的局部變量越多,它的棧越大。

?

???????從上圖可知:棧中保存著函數(shù)的返回地址、局部變量等,那么我們可以從這些返回地址來確定函數(shù)的調(diào)用關(guān)系、調(diào)用順序。這就是下節(jié)介紹的棧回溯。

3.??? 棧回溯

將程序2稍加修改,見程序323243032四行:

程序3 stack.c

01 #include <stdlib.h>

02 #include <string.h>

03 #include <stdio.h>

04

05 void A(int a);

06 void B(int b);

07 void C(int c);

08

09 void A(int a)

10 {

11???? printf("%d: A call B\n", a);

12???? B(2);

13 }

14

15 void B(int b)

16 {

17???? printf("%d: B call C\n", b);

18???? C(3);

19 }

20

21 void C(int c)

22 {

23?????char *p = (char *)c;

24?????*p = ‘A’;

25???? printf("%d: function C\n", c);

26 }

27

28 int main(int argc, char **argv)

29 {? ?

30??????char a;

31???? A(1);

32?????C(&a);

33???? return 0;

34 }

?

???????2324兩行必然導致段錯誤而使得程序崩潰,linux內(nèi)核當發(fā)現(xiàn)發(fā)生段錯誤時,會打印出棧信息。我們可以使用棧回溯的方法找到發(fā)生錯誤的原因。

使用如下命令編譯得到可執(zhí)行文件stack,反匯編文件stack.dis

?????? arm_v5t_le-gcc -g -o stack stack.c -static

?????? arm_v5t_le-objdump -dS stack > stack.dis

?

運行結(jié)果如下(注意:如果你是通過telnet來運行程序,可以使用dmesg命令看到這些棧信息)

/ # ./stack

1: A call B

2: B call C

<2>stack: unhandled page fault (11) at 0x00000003, code 0x817

<1>pgd = c3ca0000

<1>[00000003] *pgd=81b86031, *pte=00000000, *ppte=00000000

<4>

<4>Pid: 662, comm:??????????????? stack

<4>CPU: 0

<4>PC is at 0x8338

<4>LR is at 0x830c

<4>pc : [<00008338>]??? lr : [<0000830c>]??? Not tainted

<4>sp : be897af0? ip : 00000001? fp : be897b04

<4>r10: 00000000? r9 : 00008ac8? r8 : 00008b10

<4>r7 : 00000000? r6 : 00000000? r5 : 00081fe8? r4 : 00000000

<4>r3 : 00000041? r2 : 00000003? r1 : 00000000? r0 : 00000003

<4>Flags: nZCv? IRQs on? FIQs on? Mode USER_32? Segment user

<4>Control: 5317F

<4>Table: 83CA0000? DAC: 00000015

<4>usr stack info

<4>stack mem: sp = be897af0

4> be897b24 03000000 b4450600 03000000 147b89be 0000830c a4450600 02000000

?? 247b89be 000082dc 00000000 01000000 3c7b89be 00008370 647e89be 01000000

?? 00000000 108b0000 00000000 000085b4 00000000 647e89be 01000000 00008354

?? 00004c69 6e757800 000000

<4> be897b24 03be897b 0003be89 000003be 00000003 b4000000 45b40000 0645b400

<4> 000645b4 03000645 00030006 00000300 00000003 14000000 7b140000 897b1400

<4> be897b14 0cbe897b 830cbe89 00830cbe 0000830c a4000083 45a40000 0645a400

……

<4>Backtrace: [<000082fc>] (0x82fc) from [<be897b14>] (0xbe897b14)

<4>Backtrace aborted due to bad frame pointer <000645b4>

<4>Code: e51b3010 e50b3008 e51b2008 e3a03041 (e5c23000)

~ $

?

上面的藍色部分

<4>PC is at 0x8338

<4>LR is at 0x830c

表示導致崩潰的指令的地址為0x8338,返回地址為0x830c。一個典型的進程的地址空間為:

~ $ cat /proc/660/maps

00008000-00112000 r-xp 00000000 1f:07 27???????? /bin/busybox

0011a000-0011b000 rw-p 0010a000 1f:07 27???????? /bin/busybox

0011b000-001ce000 rwxp 0011b000 00:00 0????????? [heap]

40000000-40001000 rw-p 40000000 00:00 0

bea24000-bea4e000 rwxp bea24000 00:00 0????????? [stack]

?

linux-S980:/home/sanya/yjt/bt # arm_v5t_le-addr2line 0x8338 -f -e stack

C

/home/sanya/yjt/bt/stack.c:24

linux-S980:/home/sanya/yjt/bt #

?

結(jié)合此程序的反匯編程序進行回溯:

PC is at 0x8338所在函數(shù)的部分反匯編代碼摘錄如下:

00008318 <C>:

?

void C(int c)

{

????8318:?????? e92d4800??????? push??? {fp, lr}

??? 831c:?????? e28db004??????? add???? fp, sp, #4????? ; 0x4

????8320:???????e24dd010??????? sub???? sp, sp, #16???? ; 0x10

??? 8324:?????? e50b0010??????? str???? r0, [fp, #-16]

??? char *p = (char *)c;

??? 8328:?????? e51b3010??????? ldr???? r3, [fp, #-16]

??? 832c:?????? e50b3008??????? str???? r3, [fp, #-8]

??? *p = 'A';

??? 8330:?????? e51b2008??????? ldr???? r2, [fp, #-8]

??? 8334:?????? e3a03041??????? mov???? r3, #65 ; 0x41

PC->8338:???????e5c23000??????? strb??? r3, [r2]

??? printf("%d: function C\n", c);

??? 833c:?????? e59f000c??????? ldr???? r0, [pc, #12]?? ; 8350 <C+0x38>

??? 8340:?????? e51b1010??????? ldr???? r1, [fp, #-16]

??? 8344:?????? eb0003e3??????? bl????? 92d8 <_IO_printf>

}

??? 8348:?????? e24bd004??????? sub???? sp, fp, #4????? ; 0x4

??? 834c:?????? e8bd8800??????? pop???? {fp, pc}

8350:?????? 000645c4??????? .word?? 0x000645c4

?

下面對涉及的每個函數(shù)進行分析:

1.??函數(shù)C的堆棧:

??8318:?????? e92d4800??????? push??? {fp, lr}

? 831c:?????? e28db004??????? add???? fp, sp, #4????? ; 0x4

??8320:?????? e24dd010??????? sub???? sp, sp, #16???? ; 0x10

be897b24 03000000 b4450600 03000000 147b89be 0000830c?a4450600 02000000

247b89be 000082dc 00000000 01000000 3c7b89be 00008370 647e89be 01000000

00000000 108b0000 00000000 000085b4 00000000 647e89be 01000000 54830000

00004c69 6e757800 000000

?

可知 lr 為 0x0000830c,根據(jù)這個地址值,

linux-S980:/home/sanya/yjt/bt # arm_v5t_le-addr2line 0x830c -f -e stack

B

/home/sanya/yjt/bt/stack.c:19

linux-S980:/home/sanya/yjt/bt #

在stack.dis中可以再次找到這個地址處于函數(shù)B的范圍內(nèi)。

?

2. 函數(shù)B的堆棧:

函數(shù)B的匯編指令如下:

void B(int b)

{

????82e8:???????e92d4800??????? push??? {fp, lr}

??? 82ec:?????? e28db004??????? add???? fp, sp, #4????? ; 0x4

????82f0:???????e24dd008??????? sub???? sp, sp, #8????? ; 0x8

??? 82f4:?????? e50b0008??????? str???? r0, [fp, #-8]

??? printf("%d: B call C\n", b);

??? 82f8:?????? e59f0014??????? ldr???? r0, [pc, #20]?? ; 8314 <B+0x2c>

??? 82fc:?????? e51b1008??????? ldr???? r1, [fp, #-8]

??? 8300:?????? eb0003f4??????? bl????? 92d8 <_IO_printf>

??? C(3);

??? 8304:?????? e3a00003??????? mov???? r0, #3? ; 0x3

??? 8308:?????? eb000002??????? bl????? 8318 <C>

}

????830c:?????? e24bd004??????? sub???? sp, fp, #4????? ; 0x4

??? 8310:?????? e8bd8800??????? pop???? {fp, pc}

8314:?????? 000645b4??????? .word?? 0x000645b4

?

?

???????

82e8:???????e92d4800??????? push??? {fp, lr}

??? 82ec:?????? e28db004??????? add???? fp, sp, #4????? ; 0x4

82f0:???????e24dd008??????? sub???? sp, sp, #8????? ; 0x8

可知函數(shù)B的堆棧大小為16字節(jié),函數(shù)B執(zhí)行完后的返回地址?lr?存儲在其堆棧偏移地址最外層。函數(shù)B棧的的數(shù)據(jù)緊挨著函數(shù)C的棧,取出羅列如下:

be897b24 03000000 b4450600 03000000 147b89be 0000830c?a4450600 02000000

247b89be 000082dc?00000000 01000000 3c7b89be 00008370 647e89be 01000000

00000000 108b0000 00000000 000085b4 00000000 647e89be 01000000 54830000

00004c69 6e757800 000000

從上面信息可以知道,函數(shù)B的返回地址lr 為?000082dc,根據(jù)這個地址值,

linux-S980:/home/sanya/yjt/bt # arm_v5t_le-addr2line 0x82dc -f -e stack

A

/home/sanya/yjt/bt/stack.c:13

stack.dis可知處于函數(shù)A的地址范圍內(nèi)。

?

3. 函數(shù)A的堆棧:

函數(shù)A的匯編指令如下:

void A(int a)

{

????82b8:?????? e92d4800??????? push??? {fp, lr}

??? 82bc:?????? e28db004??????? add???? fp, sp, #4????? ; 0x4

????82c0: ??????e24dd008??????? sub???? sp, sp, #8????? ; 0x8

??? 82c4:?????? e50b0008??????? str???? r0, [fp, #-8]

??? printf("%d: A call B\n", a);

??? 82c8:?????? e59f0014??????? ldr???? r0, [pc, #20]?? ; 82e4 <A+0x2c>

??? 82cc:?????? e51b1008??????? ldr???? r1, [fp, #-8]

??? 82d0:?????? eb000400??????? bl????? 92d8 <_IO_printf>

??? B(2);

??? 82d4:?????? e3a00002??????? mov???? r0, #2? ; 0x2

??? 82d8:?????? eb000002??????? bl????? 82e8 <B>

}

????82dc:?????? e24bd004??????? sub???? sp, fp, #4????? ; 0x4

??? 82e0:?? ????e8bd8800??????? pop???? {fp, pc}

??? 82e4:?????? 000645a4??????? .word?? 0x000645a4

?

???????

82b8:???????e92d4800??????? push??? {fp, lr}

??? 82bc:?????? e28db004??????? add???? fp, sp, #4????? ; 0x4

????82c0:???????e24dd008??????? sub???? sp, sp, #8????? ; 0x8

可知函數(shù)A的堆棧大小為16字節(jié),函數(shù)B執(zhí)行完后的返回地址?lr?存儲在其堆棧偏移地址最外層。函數(shù)A棧的的數(shù)據(jù)緊挨著函數(shù)B的棧,取出羅列如下:

be897b24 03000000 b4450600 03000000 147b89be 0000830c?a4450600 02000000

247b89be 000082dc?00000000 01000000 3c7b89be 00008370?647e89be 01000000

00000000 108b0000 00000000 000085b4 00000000 647e89be 01000000 54830000

00004c69 6e757800 000000

???????從上面信息可以知道,函數(shù)A的返回地址為0x00008370

linux-S980:/home/sanya/yjt/bt # arm_v5t_le-addr2line 0x8370 -f -e stack

main

/home/sanya/yjt/bt/stack.c:32

linux-S980:/home/sanya/yjt/bt #

stack.dis可知處于函數(shù)main的地址范圍內(nèi)。

?

???????至此,可以知道main調(diào)用AA調(diào)用BB再調(diào)用C時,在函數(shù)C中導致程序崩潰。現(xiàn)在認真看一下函數(shù)C

21 void C(int c)

22 {

23?????char *p = (char *)c;

24?????*p = ‘A’;

25???? printf("%d: function C\n", c);

26 }

???????這個函數(shù)太過簡單,可以一眼就知道第2324行代碼有問題。但是如果函數(shù)C有上千行代碼呢?除了睜大眼睛檢查C代碼外,我們還可以根據(jù)它的反匯編碼來差錯——內(nèi)核打印出來的棧信息的前面還有些有用的信息:

<2>stack: unhandled page fault (11) at 0x00000003, code 0x817

<1>pgd = c3ca0000

<1>[00000003] *pgd=81b86031, *pte=00000000, *ppte=00000000

<4>

<4>Pid: 662, comm:??????????????? stack

<4>CPU: 0

<4>PC is at 0x8338

<4>LR is at 0x830c

<4>pc : [<00008338>]??? lr : [<0000830c>]??? Not tainted

<4>sp : be897af0? ip : 00000001? fp : be897b04

<4>r10: 00000000? r9 : 00008ac8? r8 : 00008b10

<4>r7 : 00000000? r6 : 00000000? r5 : 00081fe8? r4 : 00000000

<4>r3 : 00000041? r2 : 00000003? r1 : 00000000? r0 : 00000003

<4>Flags: nZCv? IRQs on? FIQs on? Mode USER_32? Segment user

<4>Control: 5317F

?

???????現(xiàn)在回過頭來看看函數(shù)C的反匯編碼,從中找出出錯的原因:

00008318 <C>:

?

void C(int c)

{

????8318:?????? e92d4800??????? push??? {fp, lr}

??? 831c:?????? e28db004??????? add???? fp, sp, #4????? ; 0x4

????8320:?????? e24dd010??????? sub???? sp, sp, #16???? ; 0x10

??? 8324:?????? e50b0010??????? str???? r0, [fp, #-16]

??? char *p = (char *)c;

??? 8328:?????? e51b3010??????? ldr???? r3, [fp, #-16]

??? 832c:?????? e50b3008??????? str???? r3, [fp, #-8]

??? *p = 'A';

??? 8330:?????? e51b2008??????? ldr???? r2, [fp, #-8]

??? 8334:?????? e3a03041??????? mov???? r3, #65 ; 0x41

????8338:?????? e5c23000??????? strb??? r3, [r2]

??? printf("%d: function C\n", c);

??? 833c:?????? e59f000c??????? ldr???? r0, [pc, #12]?? ; 8350 <C+0x38>

??? 8340:?????? e51b1010??????? ldr???? r1, [fp, #-16]

??? 8344:?????? eb0003e3??????? bl????? 92d8 <_IO_printf>

}

??? 8348:?????? e24bd004??????? sub???? sp, fp, #4????? ; 0x4

??? 834c:?????? e8bd8800??????? pop???? {fp, pc}

8350: ??????000645c4??????? .word?? 0x000645c4

?

???????出錯的指令為“8338:???????e5c23000??????? strb??? r3, [r2]”,它將寄存器r3的值存到地址(r2)中,只存儲1個字節(jié)。根據(jù)內(nèi)核打印出來的寄存器值可知r3 : 00000041? r2 : 00000003,寫地址為0x03,當然<2>stack: unhandled page fault (11) at?0x00000003, code 0x817

——這不是可寫的地址。

???????閱讀匯編代碼是件困難的事情,沒有其他辦法時再用這方法吧。

總結(jié)

以上是生活随笔為你收集整理的栈回溯技术arm_v5t_le版的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。