[M1 Mac, Big Sur 11.6.8, clang 13.0.0, NO IDE]
C言語コードの行単位ではレジスタ値やメモリ値の詳細が追えないので、アセンブリ言語の行単位で追跡する方法を模索しました。
GDBは不可、LLDBでは可能でした。ただし最初にrunコマンドで空実行させないと有効なBreakpointが設定できません。
GDBが仕様及び酷いバグでIntel Macでもまともに使えない状態になっていますが、LLDBのこの程度の不具合ならかわいいものです。
ちなみにGDB導入についてはIntel MacにMacPortsでインストール、ggdbファイルにコード署名、SIP(System Integrity Protection)を–without debugオプションで限定的に解除しても、結局バグに阻まれました。なおApple Siliconには今のところビルド済みファイルは提供されていません。
GCC、GDB共にソースコードからのビルドもまともにできないですし、GNUはMacを軽視しているように思います。だからこそAppleはclangやLLDBの開発に注力しているのでしょう。
LLDBではなんとかできたものの、nextコマンドを使えずアセンブリ言語コード各行をBreakpointとして設定する必要があるのでかなり面倒です。
とりあえずログを載せておきます。
bin $ lldb test
(lldb) target create "test"
Current executable set to /test' (arm64).
(lldb) disass -n main
test`main:
test[0x100003e48] <+0>: sub sp, sp, #0x60 ; =0x60
test[0x100003e4c] <+4>: stp x29, x30, [sp, #0x50]
test[0x100003e50] <+8>: mov w8, #0x0
test[0x100003e54] <+12>: str w8, [sp, #0x2c]
test[0x100003e58] <+16>: str wzr, [sp, #0x4c]
test[0x100003e5c] <+20>: mov w8, #0x3e8
test[0x100003e60] <+24>: str w8, [sp, #0x48]
test[0x100003e64] <+28>: adrp x8, 0
test[0x100003e68] <+32>: add x8, x8, #0xf50 ; =0xf50
test[0x100003e6c] <+36>: ldr w9, [x8]
test[0x100003e70] <+40>: add x10, sp, #0x40 ; =0x40
test[0x100003e74] <+44>: str x10, [sp, #0x10]
test[0x100003e78] <+48>: str w9, [sp, #0x40]
test[0x100003e7c] <+52>: ldrh w8, [x8, #0x4]
test[0x100003e80] <+56>: strh w8, [sp, #0x44]
test[0x100003e84] <+60>: add x8, sp, #0x38 ; =0x38
test[0x100003e88] <+64>: str x8, [sp, #0x18]
test[0x100003e8c] <+68>: mov x8, #0x797a
test[0x100003e90] <+72>: movk x8, #0x78, lsl #16
test[0x100003e94] <+76>: str x8, [sp, #0x38]
test[0x100003e98] <+80>: add x8, sp, #0x30 ; =0x30
test[0x100003e9c] <+84>: str x8, [sp, #0x20]
test[0x100003ea0] <+88>: adrp x8, 0
test[0x100003ea4] <+92>: add x8, x8, #0xf56 ; =0xf56
test[0x100003ea8] <+96>: str x8, [sp, #0x30]
test[0x100003eac] <+100>: ldr w9, [sp, #0x48]
test[0x100003eb0] <+104>: mov x8, x9
test[0x100003eb4] <+108>: adrp x0, 0
test[0x100003eb8] <+112>: add x0, x0, #0xf5a ; =0xf5a
test[0x100003ebc] <+116>: mov x9, sp
test[0x100003ec0] <+120>: str x8, [x9]
test[0x100003ec4] <+124>: bl 0x100003f20 ; symbol stub for: printf
test[0x100003ec8] <+128>: ldr x8, [sp, #0x10]
test[0x100003ecc] <+132>: adrp x0, 0
test[0x100003ed0] <+136>: add x0, x0, #0xf61 ; =0xf61
test[0x100003ed4] <+140>: mov x9, sp
test[0x100003ed8] <+144>: str x8, [x9]
test[0x100003edc] <+148>: bl 0x100003f20 ; symbol stub for: printf
test[0x100003ee0] <+152>: ldr x8, [sp, #0x18]
test[0x100003ee4] <+156>: adrp x0, 0
test[0x100003ee8] <+160>: add x0, x0, #0xf68 ; =0xf68
test[0x100003eec] <+164>: mov x9, sp
test[0x100003ef0] <+168>: str x8, [x9]
test[0x100003ef4] <+172>: bl 0x100003f20 ; symbol stub for: printf
test[0x100003ef8] <+176>: ldr x8, [sp, #0x20]
test[0x100003efc] <+180>: adrp x0, 0
test[0x100003f00] <+184>: add x0, x0, #0xf73 ; =0xf73
test[0x100003f04] <+188>: mov x9, sp
test[0x100003f08] <+192>: str x8, [x9]
test[0x100003f0c] <+196>: bl 0x100003f20 ; symbol stub for: printf
test[0x100003f10] <+200>: ldr w0, [sp, #0x2c]
test[0x100003f14] <+204>: ldp x29, x30, [sp, #0x50]
test[0x100003f18] <+208>: add sp, sp, #0x60 ; =0x60
test[0x100003f1c] <+212>: ret
(lldb) run
Process 21720 launched: '/test' (arm64)
i: 1000
c: abcde
c_ptr: zyx
c_ptr2: V?
Process 21720 exited with status = 0 (0x00000000)
(lldb) disass -n main
test`main:
0x100003e48 <+0>: sub sp, sp, #0x60 ; =0x60
0x100003e4c <+4>: stp x29, x30, [sp, #0x50]
0x100003e50 <+8>: mov w8, #0x0
0x100003e54 <+12>: str w8, [sp, #0x2c]
0x100003e58 <+16>: str wzr, [sp, #0x4c]
0x100003e5c <+20>: mov w8, #0x3e8
0x100003e60 <+24>: str w8, [sp, #0x48]
0x100003e64 <+28>: adrp x8, 0
0x100003e68 <+32>: add x8, x8, #0xf50 ; =0xf50
0x100003e6c <+36>: ldr w9, [x8]
0x100003e70 <+40>: add x10, sp, #0x40 ; =0x40
0x100003e74 <+44>: str x10, [sp, #0x10]
0x100003e78 <+48>: str w9, [sp, #0x40]
0x100003e7c <+52>: ldrh w8, [x8, #0x4]
0x100003e80 <+56>: strh w8, [sp, #0x44]
0x100003e84 <+60>: add x8, sp, #0x38 ; =0x38
0x100003e88 <+64>: str x8, [sp, #0x18]
0x100003e8c <+68>: mov x8, #0x797a
0x100003e90 <+72>: movk x8, #0x78, lsl #16
0x100003e94 <+76>: str x8, [sp, #0x38]
0x100003e98 <+80>: add x8, sp, #0x30 ; =0x30
0x100003e9c <+84>: str x8, [sp, #0x20]
0x100003ea0 <+88>: adrp x8, 0
0x100003ea4 <+92>: add x8, x8, #0xf56 ; =0xf56
0x100003ea8 <+96>: str x8, [sp, #0x30]
0x100003eac <+100>: ldr w9, [sp, #0x48]
0x100003eb0 <+104>: mov x8, x9
0x100003eb4 <+108>: adrp x0, 0
0x100003eb8 <+112>: add x0, x0, #0xf5a ; =0xf5a
0x100003ebc <+116>: mov x9, sp
0x100003ec0 <+120>: str x8, [x9]
0x100003ec4 <+124>: bl 0x100003f20 ; symbol stub for: printf
0x100003ec8 <+128>: ldr x8, [sp, #0x10]
0x100003ecc <+132>: adrp x0, 0
0x100003ed0 <+136>: add x0, x0, #0xf61 ; =0xf61
0x100003ed4 <+140>: mov x9, sp
0x100003ed8 <+144>: str x8, [x9]
0x100003edc <+148>: bl 0x100003f20 ; symbol stub for: printf
0x100003ee0 <+152>: ldr x8, [sp, #0x18]
0x100003ee4 <+156>: adrp x0, 0
0x100003ee8 <+160>: add x0, x0, #0xf68 ; =0xf68
0x100003eec <+164>: mov x9, sp
0x100003ef0 <+168>: str x8, [x9]
0x100003ef4 <+172>: bl 0x100003f20 ; symbol stub for: printf
0x100003ef8 <+176>: ldr x8, [sp, #0x20]
0x100003efc <+180>: adrp x0, 0
0x100003f00 <+184>: add x0, x0, #0xf73 ; =0xf73
0x100003f04 <+188>: mov x9, sp
0x100003f08 <+192>: str x8, [x9]
0x100003f0c <+196>: bl 0x100003f20 ; symbol stub for: printf
0x100003f10 <+200>: ldr w0, [sp, #0x2c]
0x100003f14 <+204>: ldp x29, x30, [sp, #0x50]
0x100003f18 <+208>: add sp, sp, #0x60 ; =0x60
0x100003f1c <+212>: ret
(lldb) b 0x100003e48
Breakpoint 1: where = test`main at test.c:3, address = 0x0000000100003e48
(lldb) b 0x100003e4c
Breakpoint 2: where = test`main + 4 at test.c:3, address = 0x0000000100003e4c
(lldb) b 0x100003e50
Breakpoint 3: where = test`main + 8 at test.c:3, address = 0x0000000100003e50
(lldb) r
Process 22004 launched: '/test' (arm64)
Process 22004 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100003e48 test`main at test.c:3
1 #include <stdio.h>
2
-> 3 int main() {
4 int i = 1000;
5 char c[6] = {'a', 'b', 'c', 'd', 'e'};
6 char* c_ptr = 'xyz';
7 char* c_ptr2 = "stu";
Target 0: (test) stopped.
(lldb) next
Process 22004 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
frame #0: 0x0000000100003e4c test`main at test.c:3
1 #include <stdio.h>
2
-> 3 int main() {
4 int i = 1000;
5 char c[6] = {'a', 'b', 'c', 'd', 'e'};
6 char* c_ptr = 'xyz';
7 char* c_ptr2 = "stu";
Target 0: (test) stopped.