Reputation: 11
I've recently moved from an Intel Mac to an M1 (arm64). AddressSanitizer seems to work the same, with Homebrew clang
, except that the stack traces only show the functions in the stack that are in the same source file as the call that threw the signal. This wasn't the case on Intel Macs or on Linux. I feel like I'm missing something obvious, but can't find it.
a.c
:
void bar(void) {
*(volatile char *)0 = 0;
}
void foo(void) {
bar();
}
int main(void) {
foo();
}
Compile, link, and symbolize:
$ /opt/homebrew/opt/llvm/bin/clang -c -fsanitize=address -O1 -g -fno-omit-frame-pointer a.c -o a.o
$ /opt/homebrew/opt/llvm/bin/clang -fsanitize=address a.o -o a.out
$ dsymutil a.out
Run:
$ ./a.out
AddressSanitizer:DEADLYSIGNAL
=================================================================
==31187==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00010050bf5c bp 0x00010054d08c sp 0x00016f8f7660 T0)
==31187==The signal is caused by a UNKNOWN memory access.
==31187==Hint: address points to the zero page.
#0 0x10050bf5c in bar /Users/jpc/src/asantest/a.c:2:23
#1 0x10050bf5c in foo /Users/jpc/src/asantest/a.c:6:3
#2 0x10050bf5c in main /Users/jpc/src/asantest/a.c:10:3
==31187==Register values:
x[0] = 0x0000000000000001 x[1] = 0x000000016f8f77d0 x[2] = 0x000000016f8f77e0 x[3] = 0x000000016f8f78f8
x[4] = 0x0000000000000000 x[5] = 0x0000000000000000 x[6] = 0x0000000000000000 x[7] = 0x0000000000000000
x[8] = 0x0000000000000000 x[9] = 0x0000000000000002 x[10] = 0x0000000000000000 x[11] = 0x0000000000000002
x[12] = 0x0000000000000002 x[13] = 0x0000000000000000 x[14] = 0x0000000000000020 x[15] = 0x0000000000000000
x[16] = 0x0000000300fd7088 x[17] = 0x6ae100016f8f6a70 x[18] = 0x0000000000000000 x[19] = 0x00000001005fc060
x[20] = 0x000000010050bf34 x[21] = 0x00000001005a8070 x[22] = 0x0000000000000000 x[23] = 0x0000000000000000
x[24] = 0x0000000000000000 x[25] = 0x0000000000000000 x[26] = 0x0000000000000000 x[27] = 0x0000000000000000
x[28] = 0x0000000000000000 fp = 0x000000016f8f7660 lr = 0x000000010054d08c sp = 0x000000016f8f7660
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /Users/jpc/src/asantest/a.c:2:23 in bar
==31187==ABORTING
zsh: abort ./a.out
All three functions in the stack are shown in the trace, as expected.
b1.c
:
void bar(void);
void foo(void) {
bar();
}
int main(void) {
foo();
}
b2.c
:
void bar(void) {
*(volatile char *)0 = 0;
}
Compile, link, and symbolize:
$ /opt/homebrew/opt/llvm/bin/clang -c -fsanitize=address -O1 -g -fno-omit-frame-pointer b1.c -o b1.o
$ /opt/homebrew/opt/llvm/bin/clang -c -fsanitize=address -O1 -g -fno-omit-frame-pointer b2.c -o b2.o
$ /opt/homebrew/opt/llvm/bin/clang -fsanitize=address b1.o b2.o -o b.out
$ dsymutil b.out
Run:
$ ./b.out
AddressSanitizer:DEADLYSIGNAL
=================================================================
==31297==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000102afff5c bp 0x000102afff10 sp 0x00016d303650 T0)
==31297==The signal is caused by a UNKNOWN memory access.
==31297==Hint: address points to the zero page.
#0 0x102afff5c in bar /Users/jpc/src/asantest/b2.c:2:23
==31297==Register values:
x[0] = 0x0000000000000001 x[1] = 0x000000016d3037d0 x[2] = 0x000000016d3037e0 x[3] = 0x000000016d3038f8
x[4] = 0x0000000000000000 x[5] = 0x0000000000000000 x[6] = 0x0000000000000000 x[7] = 0x0000000000000000
x[8] = 0x0000000000000000 x[9] = 0x0000000000000002 x[10] = 0x0000000000000000 x[11] = 0x0000000000000002
x[12] = 0x0000000000000002 x[13] = 0x0000000000000000 x[14] = 0x0000000000000020 x[15] = 0x0000000000000000
x[16] = 0x00000003074e7088 x[17] = 0x6ae100016d302a70 x[18] = 0x0000000000000000 x[19] = 0x0000000102b08060
x[20] = 0x0000000102afff04 x[21] = 0x0000000102cb8070 x[22] = 0x0000000000000000 x[23] = 0x0000000000000000
x[24] = 0x0000000000000000 x[25] = 0x0000000000000000 x[26] = 0x0000000000000000 x[27] = 0x0000000000000000
x[28] = 0x0000000000000000 fp = 0x000000016d303650 lr = 0x0000000102afff10 sp = 0x000000016d303650
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /Users/jpc/src/asantest/b2.c:2:23 in bar
==31297==ABORTING
zsh: abort ./b.out
The violating function bar
in b2.c
is shown in the stack trace, but the two calling functions in the stack, main
and foo
in b1.c
, are not. On Intel Macs or Linux the whole stack trace would be shown, from whichever source files they came from.
Upvotes: 0
Views: 1582
Reputation: 11
It looks like this is simply a bug in the current arm64 implementation; I've filed this bug report. Running the same commands as above on the same machine but under Rosetta, under which Brew installs in /usr/local/bin/
:
$ ./a.out
AddressSanitizer:DEADLYSIGNAL
=================================================================
==3697==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000102e0ff43 bp 0x000309fa86c0 sp 0x000309fa86c0 T0)
==3697==The signal is caused by a WRITE memory access.
==3697==Hint: address points to the zero page.
#0 0x102e0ff43 in bar /Users/jpc/src/asantest/a.c:2:23
#1 0x102e0ff43 in foo /Users/jpc/src/asantest/a.c:6:3
#2 0x102e0ff43 in main /Users/jpc/src/asantest/a.c:10:3
#3 0x2030ea51d in start (/usr/lib/dyld:x86_64+0x551d)
#4 0x2030e4fff (<unknown module>)
==3697==Register values:
rax = 0x0000100000000000 rbx = 0x000000010b343060 rcx = 0x0000000309fa8938 rdx = 0x0000000309fa8808
rdi = 0x0000000000000001 rsi = 0x0000000309fa87f8 rbp = 0x0000000309fa86c0 rsp = 0x0000000309fa86c0
r8 = 0x0000000000145e7b r9 = 0xffffffff00000000 r10 = 0x0000000000000000 r11 = 0x000000020312001a
r12 = 0x00000002031653a0 r13 = 0x0000000309fa8778 r14 = 0x0000000102e0ff30 r15 = 0x0000000203151010
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /Users/jpc/src/asantest/a.c:2:23 in bar
==3697==ABORTING
zsh: abort ./a.out
$ ./b.out
AddressSanitizer:DEADLYSIGNAL
=================================================================
==3847==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000100329f43 bp 0x0003047ad6b0 sp 0x0003047ad6b0 T0)
==3847==The signal is caused by a WRITE memory access.
==3847==Hint: address points to the zero page.
#0 0x100329f43 in bar /Users/jpc/src/asantest/b2.c:2:23
#1 0x100329f18 in foo /Users/jpc/src/asantest/b1.c:4:3
#2 0x100329f18 in main /Users/jpc/src/asantest/b1.c:8:3
#3 0x2003d551d in start (/usr/lib/dyld:x86_64+0x551d)
#4 0x2003cffff (<unknown module>)
==3847==Register values:
rax = 0x0000100000000000 rbx = 0x000000010885d060 rcx = 0x00000003047ad938 rdx = 0x00000003047ad808
rdi = 0x0000000000000001 rsi = 0x00000003047ad7f8 rbp = 0x00000003047ad6b0 rsp = 0x00000003047ad6b0
r8 = 0x00000000001460cd r9 = 0xffffffff00000000 r10 = 0x0000000000000000 r11 = 0x000000020040b01a
r12 = 0x00000002004503a0 r13 = 0x00000003047ad778 r14 = 0x0000000100329f10 r15 = 0x000000020043c010
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /Users/jpc/src/asantest/b2.c:2:23 in bar
==3847==ABORTING
zsh: abort ./b.out
Upvotes: 1