Skip to content

Commit 07b9e6e

Browse files
author
Jaroslav Sevcik
committed
[lldb] Fix handling of cfi_restore in the unwinder
Currently, lldb's unwinder ignores cfi_restore opcodes for registers that are not set in the first row of the unwinding info. This prevents unwinding of failed assertion in Chrome/v8 (https://github.com/v8/v8). The attached test is an x64 copy of v8's function that failed to unwind correctly (V8_Fatal). This patch changes handling of cfi_restore to reset the location if the first unwind table row does not map the restored register. Differential Revision: https://reviews.llvm.org/D153043
1 parent c0a986a commit 07b9e6e

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

lldb/source/Symbol/DWARFCallFrameInfo.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,11 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
674674
unwind_plan.GetRowAtIndex(0)->GetRegisterInfo(reg_num,
675675
reg_location))
676676
row->SetRegisterInfo(reg_num, reg_location);
677+
else {
678+
// If the register was not set in the first row, remove the
679+
// register info to keep the unmodified value from the caller.
680+
row->RemoveRegisterInfo(reg_num);
681+
}
677682
break;
678683
}
679684
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
.text
2+
.globl asm_main
3+
asm_main:
4+
.cfi_startproc
5+
cmpb $0x0, g_hard_abort(%rip)
6+
jne .L
7+
8+
pushq %rbp
9+
.cfi_def_cfa_offset 16
10+
.cfi_offset 6, -16
11+
movq %rsp, %rbp
12+
.cfi_def_cfa_register 6
13+
callq abort
14+
.L:
15+
.cfi_def_cfa 7, 8
16+
.cfi_restore 6
17+
int3
18+
ud2
19+
.cfi_endproc
20+
21+
.data
22+
.globl g_hard_abort
23+
g_hard_abort:
24+
.byte 1
25+
.size g_hard_abort, 1
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Test restoring of register values.
2+
3+
# UNSUPPORTED: system-windows
4+
# REQUIRES: target-x86_64, native
5+
6+
# RUN: %clang_host %p/Inputs/call-asm.c %p/Inputs/eh-frame-dwarf-unwind-abort.s -o %t
7+
# RUN: %lldb %t -s %s -o exit | FileCheck %s
8+
9+
process launch
10+
# CHECK: stop reason = signal SIGTRAP
11+
12+
thread backtrace
13+
# CHECK: frame #0: {{.*}}`asm_main + 23
14+
# CHECK: frame #1: {{.*}}`main + {{.*}}
15+
16+
target modules show-unwind -n asm_main
17+
# CHECK: eh_frame UnwindPlan:
18+
# CHECK: row[0]: 0: CFA=rsp +8 => rip=[CFA-8]
19+
# CHECK: row[1]: 14: CFA=rsp+16 => rbp=[CFA-16] rip=[CFA-8]
20+
# CHECK: row[2]: 17: CFA=rbp+16 => rbp=[CFA-16] rip=[CFA-8]
21+
# CHECK: row[3]: 22: CFA=rsp +8 => rip=[CFA-8]

0 commit comments

Comments
 (0)