請(qǐng)閱讀【ARM Linux 系統(tǒng)穩(wěn)定性分析專欄導(dǎo)讀】
1.1 gdb 調(diào)試回顧
在GNU調(diào)試器(GDB)中,有許多命令可以幫助我們調(diào)試應(yīng)用程序。gdb
: 這是一個(gè)強(qiáng)大的Unix下的程序調(diào)試工具。以下是使用gdb的一個(gè)簡(jiǎn)單示例:
$ gdb ./test
在這個(gè)例子中,我們啟動(dòng)了gdb
并將我們的程序test
作為參數(shù)傳遞。
可執(zhí)行程序 test
是由下面代碼使用gcc -g -O0 test.c -o test
編譯出來:
#include<stdio.h>
#include<stdlib.h>
static int bar(void)
{
char *p = NULL;
printf("I am bar,I will core dump\n");
printf("%s",p);
*p =0x0;
return 0;
}
static int foo(void)
{
int i ;
printf("I am foo,I will call bar\n");
bar();
return 0;
}
int main(void)
{
printf("I am main, I wll can foo\n");
foo();
return 0;
}
1.1.1 gdb list 命令介紹
llist: llist
命令用于顯示當(dāng)前源代碼的行列表,包括當(dāng)前行以及周圍的幾行代碼。這對(duì)于查看代碼的上下文非常有用。
例如,你可以使用llist命令來顯示當(dāng)前行及周圍的10
行代碼:
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...
(gdb) list 10
5 {
6 char *p = NULL;
7
8 printf("I am bar,I will core dump\n");
9 printf("%s", p);
10
11 *p = 0x0;
12
13 return 0;
14 }
(gdb)
這將顯示源代碼的當(dāng)前行周圍的文本。
1.2 反匯編命令 dis 介紹
dis/disassemble: 這個(gè)命令用于查看匯編代碼。例如,我們可以使用以下命令查看當(dāng)前函數(shù)的匯編代碼:
(gdb) disassemble
或者查看指定函數(shù)的匯編代碼:
[11:01:22]sam@codingcos-sam-laptop (*^~^*) ~/test> gdb test
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...
(gdb) dis foo
Bad breakpoint number 'foo'
(gdb)
從上面的信息可以看到gdb并沒有對(duì)函數(shù) foo
進(jìn)行反匯編,而是報(bào)出錯(cuò)誤:“Bad breakpoint number ‘foo’”,甚是疑惑!??!, 網(wǎng)上搜了一大圈也沒找到原因!!
后來發(fā)現(xiàn)是在使用gdb
時(shí)沒有設(shè)置斷點(diǎn)導(dǎo)致的,如果按照下面方式,則可以進(jìn)行反匯編
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...
(gdb) b foo
Breakpoint 1 at 0x11bd: file test.c, line 19.
(gdb) dis foo
Bad breakpoint number 'foo'
(gdb) disassemble foo
Dump of assembler code for function foo:
0x00000000000011b5 <+0>: endbr64
0x00000000000011b9 <+4>: push %rbp
0x00000000000011ba <+5>: mov %rsp,%rbp
0x00000000000011bd <+8>: lea 0xe5f(%rip),%rax # 0x2023
0x00000000000011c4 <+15>: mov %rax,%rdi
0x00000000000011c7 <+18>: call 0x1060 <puts@plt>
0x00000000000011cc <+23>: call 0x1169 <bar>
0x00000000000011d1 <+28>: mov $0x0,%eax
0x00000000000011d6 <+33>: pop %rbp
0x00000000000011d7 <+34>: ret
End of assembler dump.
但是目前還不清楚為何使用 dis
命令不生效。
如下是使用 arm gdb 的反匯編示例(前提要有arm gcc 編譯出來的 .o
文件):
arm-none-eabi-gdb ./build/bsp/sam/sam_demo/common/soc.o
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi".
Reading symbols from ./build/bsp/sam/sam_demo/common/soc.o...
(gdb) b reboot
Breakpoint 1 at 0x214: file /mnt/user_home/sam/rt-thread/bsp/sam/sam_demo/common/soc.c, line 36.
(gdb) disassemble reboot
Dump of assembler code for function reboot:
0x00000208 <+0>: push {r7}
0x0000020a <+2>: sub sp, #20
0x0000020c <+4>: add r7, sp, #0
0x0000020e <+6>: mov r3, r0
0x00000210 <+8>: str r1, [r7, #0]
0x00000212 <+10>: strb r3, [r7, #7]
0x00000214 <+12>: ldr r3, [pc, #24] ; (0x230 <reboot+40>)
0x00000216 <+14>: str r3, [r7, #12]
0x00000218 <+16>: dmb sy
0x0000021c <+20>: ldr r2, [pc, #20] ; (0x234 <reboot+44>)
0x0000021e <+22>: ldr r3, [r7, #12]
0x00000220 <+24>: str r3, [r2, #0]
0x00000222 <+26>: nop
0x00000224 <+28>: adds r7, #20
0x00000226 <+30>: mov sp, r7
0x00000228 <+32>: ldr.w r7, [sp], #4
0x0000022c <+36>: bx lr
0x0000022e <+38>: nop
0x00000230 <+40>: lsls r3, r4, #12
0x00000232 <+42>: movs r0, #33 ; 0x21
0x00000234 <+44>: asrs r0, r0, #2
0x00000236 <+46>: mov r1, r0
End of assembler dump.
(gdb)
另外一種查看匯編代碼的方式是使用 x
命令,如下顯示 pc
開始的 3
條指令:
Breakpoint 1, foo () at test.c:19
19 printf("I am foo,I will call bar\n");
(gdb) x/3i $pc
=> 0x5555555551bd <foo+8>: lea 0xe5f(%rip),%rax # 0x555555556023
0x5555555551c4 <foo+15>: mov %rax,%rdi
0x5555555551c7 <foo+18>: call 0x555555555060 <puts@plt>
(gdb)
arm gdb 反匯編示例:
查看0x0
地址開始后面的10
條匯編:
arm-none-eabi-gdb ./build/bsp/sam/sam_demo/common/soc.o
...
(gdb) x/3i 0x0
0x0 <__NVIC_SetPriority>: push {r7}
0x2 <__NVIC_SetPriority+2>: sub sp, #12
0x4 <__NVIC_SetPriority+4>: add r7, sp, #0
(gdb) x/10i 0x00000000
0x0 <__NVIC_SetPriority>: push {r7}
0x2 <__NVIC_SetPriority+2>: sub sp, #12
0x4 <__NVIC_SetPriority+4>: add r7, sp, #0
0x6 <__NVIC_SetPriority+6>: mov r3, r0
0x8 <__NVIC_SetPriority+8>: str r1, [r7, #0]
0xa <__NVIC_SetPriority+10>: strh r3, [r7, #6]
0xc <__NVIC_SetPriority+12>: ldrsh.w r3, [r7, #6]
0x10 <__NVIC_SetPriority+16>: cmp r3, #0
0x12 <__NVIC_SetPriority+18>: blt.n 0x2a <__NVIC_SetPriority+42>
0x14 <__NVIC_SetPriority+20>: ldr r3, [r7, #0]
(gdb)
1.2.1 如何設(shè)置 gdb 匯編代碼的格式
GDB 主要支持兩種匯編代碼格式:
-
AT&T
風(fēng)格:這是GDB的默認(rèn)匯編代碼格式,是在Unix和GNU系統(tǒng)中常見的格式。在AT&T
風(fēng)格的匯編代碼中,操作數(shù)的順序是“源,目標(biāo)”,立即數(shù)和絕對(duì)地址值以美元符號(hào)"$"
作為前綴,寄存器名稱以百分號(hào)"%"
作為前綴。 -
Intel
風(fēng)格:這是在Intel文檔和Windows環(huán)境中常見的格式。在Intel風(fēng)格的匯編代碼中,操作數(shù)的順序是“目標(biāo),源”,立即數(shù)和絕對(duì)地址值沒有特殊的前綴,寄存器名稱也沒有特殊的前綴。
可以使用 show disassembly-flavor
命令查看當(dāng)前的匯編代碼風(fēng)格。例如:
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...
(gdb) dis foo
Bad breakpoint number 'foo'
(gdb) show disassembly-flavor
The disassembly flavor is "att".
(gdb)
可以看到默認(rèn)是 AT&T風(fēng)格。
如果你想要改變匯編代碼風(fēng)格,你可以使用 set disassembly-flavor
命令來設(shè)置新的風(fēng)格。例如,如果你想要設(shè)置成Intel風(fēng)格,你可以這樣做:文章來源:http://www.zghlxwxcb.cn/news/detail-670611.html
(gdb) set disassembly-flavor intel
如果你想要設(shè)置成AT&T風(fēng)格,你可以這樣做:文章來源地址http://www.zghlxwxcb.cn/news/detail-670611.html
(gdb) set disassembly-flavor att
到了這里,關(guān)于ARM Linux 系統(tǒng)穩(wěn)定性分析入門及漸進(jìn) 13 -- gdb 反匯編 disassemble 命令詳細(xì)介紹及舉例】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!