Skip to content

Commit 4d2288d

Browse files
[compiler-rt] [test] Add test for frame counter out of order. (#154190)
Add test for #148278. This was written with the aide of ChatGPT 5 and tested on Linux x86_64.
1 parent 3ef3b30 commit 4d2288d

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// This test case checks for a bug where anonymous code results in
2+
// out-of-order stack frame numbers.
3+
4+
// UNSUPPORTED: android
5+
// UNSUPPORTED: aarch64
6+
// UNSUPPORTED: darwin
7+
// UNSUPPORTED: ios
8+
// XFAIL: *
9+
10+
// RUN: %clangxx_asan -O0 -g %s -o %t
11+
// RUN: %env_asan_opts=symbolize=0 not %run %t DUMMY_ARG > %t.asan_report 2>&1
12+
// RUN: %asan_symbolize -d --log-level debug --log-dest %t_debug_log_output.txt -l %t.asan_report > %t.asan_report_sym
13+
// RUN: FileCheck --input-file=%t.asan_report_sym %s
14+
15+
#include <cstddef>
16+
#include <cstdint>
17+
#include <cstdio>
18+
#include <cstring>
19+
#include <sys/mman.h>
20+
#include <unistd.h>
21+
22+
static void call_via_anon_page(void (*fn)()) {
23+
const size_t pagesz = static_cast<size_t>(sysconf(_SC_PAGESIZE));
24+
uint8_t *mem =
25+
static_cast<uint8_t *>(mmap(nullptr, pagesz, PROT_READ | PROT_WRITE,
26+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
27+
if (mem == MAP_FAILED)
28+
perror("mmap");
29+
30+
#if defined(__x86_64__)
31+
// x86_64: mov rax, imm64; call rax; ret
32+
// 48 B8 <imm64> FF D0 C3
33+
uint8_t stub[2 + 8 + 2 + 1] = {0x48, 0xB8};
34+
std::memcpy(stub + 2, &fn, sizeof(fn)); // imm64
35+
stub[2 + 8] = 0xFF;
36+
stub[2 + 9] = 0xD0; // call rax
37+
stub[2 + 10] = 0xC3; // ret
38+
#else
39+
# error "unsupported platform"
40+
#endif
41+
42+
std::memcpy(mem, stub, sizeof(stub));
43+
mprotect(mem, pagesz, PROT_READ | PROT_EXEC);
44+
45+
using Thunk = void (*)();
46+
reinterpret_cast<Thunk>(mem)();
47+
48+
munmap(mem, pagesz);
49+
}
50+
51+
static void crash() {
52+
char p[8], *s = p;
53+
54+
// out-of-bounds write to trigger ASan
55+
s[16] = 42;
56+
}
57+
58+
int main() {
59+
call_via_anon_page(crash);
60+
return 0;
61+
}
62+
63+
// Check that the numbering of the stackframes is correct.
64+
65+
// CHECK: AddressSanitizer: stack-buffer-overflow
66+
// CHECK-NEXT: WRITE of size
67+
// CHECK-NEXT: #0 0x{{[0-9a-fA-F]+}} in crash
68+
// CHECK-NEXT: #1 0x{{[0-9a-fA-F]+}}
69+
// CHECK-NEXT: #2 0x{{[0-9a-fA-F]+}} in main

0 commit comments

Comments
 (0)