Skip to content

Commit 01a8f9b

Browse files
committed
[lldb] Cortex-M exception unwind API test cleanup
This test, with a corefile created via yaml2macho-core plus an ObjectFileJSON binary with symbol addresses and ranges, was failing on some machines/CI because the wrong ABI was being picked. The bytes of the functions were not included in the yaml or .json binary. The unwind falls back to using the ABI plugin default unwind plans. We have two armv7 ABIs - the Darwin ABI that always uses r7 as the frame pointer, and the AAPCS ABI which uses r11 code. In reality, armv7 code uses r11 in arm mode, r7 in thumb code. But the ABI ArchDefaultUnwindPlan doesn't have any access to the Target's ArchSpec or Process register state, to determine the correct processor state (arm or thumb). And in fact, on Cortex-M targets, the instructions are always thumb, so the arch default unwind plan (hardcoded r11) is always wrong. The corefile doesn't specify a vendor/os, only a cpu. The object file json specifies the armv7m-apple-* triple, which will select the correct ABI plugin, and the test runs. In some cases, it looks like the Process ABI was fetched after opening the corefile, but before the binary.json was loaded and corrected the Target's ArchSpec. And we never re-evaluate the ABI once it is set, in a Process. When we picked the AAPCS armv7 ABI, we would try to use r11 as frame pointer, and the unwind would stop after one stack frame. I'm stepping around this problem by (1) adding the register bytes of the prologues of every test function in the backtrace, and (2) shortening the function ranges (in binary.json) to specify that the functions are all just long enough for the prologue where execution is stopped. The instruction emulation plugin will fail if it can't get all of the bytes from the function instructions, so I hacked the function sizes in the .json to cover the prologue plus one and changed the addresses in the backtrace to fit within those ranges.
1 parent b7df533 commit 01a8f9b

File tree

3 files changed

+30
-23
lines changed

3 files changed

+30
-23
lines changed

lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,6 @@
1212
class TestCortexMExceptionUnwind(TestBase):
1313
NO_DEBUG_INFO_TESTCASE = True
1414

15-
# on the lldb-remote-linux-ubuntu CI, the binary.json's triple of
16-
# armv7m-apple is not being set in the Target triple, and we're
17-
# picking the wrong ABI plugin, ABISysV_arm.
18-
# ABISysV_arm::CreateDefaultUnwindPlan() doesn't have a way to detect
19-
# arm/thumb for a stack frame, or even the Target's triple for a
20-
# Cortex-M part that is always thumb. It hardcodes r11 as the frame
21-
# pointer register, which is correct for arm code but not thumb.
22-
# It is never correct # on a Cortex-M target.
23-
# The Darwin ABIMacOSX_arm diverges from AAPCS and always uses r7 for
24-
# the frame pointer -- the thumb convention -- whether executing arm or
25-
# thumb. So its CreateDefaultUnwindPlan picks the correct register for
26-
# the frame pointer, and we can walk the stack.
27-
# ABISysV_arm::CreateDefaultUnwindPlan will only get one frame and
28-
# not be able to continue.
29-
@skipIfRemote
3015
def test_no_fpu(self):
3116
"""Test that we can backtrace correctly through an ARM Cortex-M Exception return stack"""
3217

@@ -59,9 +44,8 @@ def test_no_fpu(self):
5944
# frames above that. The topmost two stack frames
6045
# were not interesting for this test, so I didn't
6146
# create symbols for them.
62-
self.assertEqual(thread.GetNumFrames(), 6)
47+
self.assertEqual(thread.GetNumFrames(), 3)
6348
stackframe_names = [
64-
"exception_catcher",
6549
"exception_catcher",
6650
"exception_thrower",
6751
"main",

lldb/test/API/functionalities/unwind/cortex-m-exception/armv7m-nofpu-exception.yaml

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ cpu: armv7m
22
threads:
33
- regsets:
44
- flavor: gpr
5-
registers: [{name: sp, value: 0x2000fe70}, {name: r7, value: 0x2000fe80},
6-
{name: pc, value: 0x0020392c}, {name: lr, value: 0x0020392d}]
5+
registers: [{name: sp, value: 0x2000fe88}, {name: r7, value: 0x2000fe88},
6+
{name: pc, value: 0x00203916}, {name: lr, value: 0x0020392d}]
77
memory-regions:
88
# stack memory fetched via
99
# (lldb) p/x $sp
@@ -14,7 +14,7 @@ memory-regions:
1414
0x0000002a, 0x20010e58, 0x00203923, 0x00000001,
1515
0x2000fe88, 0x00203911, 0x2000ffdc, 0xfffffff9,
1616
0x00000102, 0x00000002, 0x000003f0, 0x0000002a,
17-
0x20012620, 0x00203215, 0x00203366, 0x81000200,
17+
0x20012620, 0x00203215, 0x00202a92, 0x81000200,
1818
0x00203215, 0x200128b0, 0x0024928d, 0x2000fecc,
1919
0x002491ed, 0x20010e58, 0x20010e4c, 0x2000ffa0,
2020
0x200107a0, 0x0000003c, 0x200116e8, 0x200108b0,
@@ -62,3 +62,26 @@ memory-regions:
6262
0x98, 0xae, 0x28, 0x00
6363
]
6464

65+
# exception_thrower
66+
# (lldb) disass -b -c 12 -n exception_thrower
67+
# 0x202a88 <+0>: 0xb5f0 push {r4, r5, r6, r7, lr}
68+
# 0x202a8a <+2>: 0xaf03 add r7, sp, #0xc
69+
# 0x202a8c <+4>: 0xe92d0f00 push.w {r8, r9, r10, r11}
70+
# 0x202a90 <+8>: 0xb0c3 sub sp, #0x10c
71+
# 0x202a92 <+10>: 0xf7ffffd9 bl 0x202a48
72+
- addr: 0x202a88
73+
UInt8: [
74+
0xf0, 0xb5, 0x03, 0xaf, 0x2d, 0xe9, 0x00, 0x0f,
75+
0xc3, 0xb0, 0xff, 0xf7, 0xd9, 0xff, 0xff, 0xf7
76+
]
77+
78+
# main:
79+
# 0x202a7e <+0>: push {r7, lr}
80+
# 0x202a80 <+2>: mov r7, sp
81+
# 0x202a82 <+4>: bl 0x202a88 ; exception_thrower
82+
# 0x202a86 <+8>: nop
83+
- addr: 0x202a7e
84+
UInt8: [
85+
0x80, 0xb5, 0x6f, 0x46, 0x00, 0xf0, 0x01, 0xf8,
86+
0x00, 0xbf
87+
]

lldb/test/API/functionalities/unwind/cortex-m-exception/binary.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"triple": "armv7m-apple",
2+
"triple": "armv7m--",
33
"uuid": "2D157DBA-53C9-3AC7-B5A1-9D336EC831CB",
44
"type": "executable",
55
"sections": [
@@ -28,13 +28,13 @@
2828
{
2929
"name": "exception_catcher",
3030
"type": "code",
31-
"size": 44,
31+
"size": 32,
3232
"address": 2111760
3333
},
3434
{
3535
"name": "exception_thrower",
3636
"type": "code",
37-
"size": 2652,
37+
"size": 16,
3838
"address": 2108040
3939
}
4040
]

0 commit comments

Comments
 (0)