[Lldb-commits] [lldb] 07b9e6e - [lldb] Fix handling of cfi_restore in the unwinder

Jaroslav Sevcik via lldb-commits lldb-commits at lists.llvm.org
Thu Jun 15 23:03:26 PDT 2023


Author: Jaroslav Sevcik
Date: 2023-06-16T08:01:29+02:00
New Revision: 07b9e6ed0db206912b99c153a6bcfcb41f792cc5

URL: https://github.com/llvm/llvm-project/commit/07b9e6ed0db206912b99c153a6bcfcb41f792cc5
DIFF: https://github.com/llvm/llvm-project/commit/07b9e6ed0db206912b99c153a6bcfcb41f792cc5.diff

LOG: [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

Added: 
    lldb/test/Shell/Unwind/Inputs/eh-frame-dwarf-unwind-abort.s
    lldb/test/Shell/Unwind/eh-frame-dwarf-unwind-abort.test

Modified: 
    lldb/source/Symbol/DWARFCallFrameInfo.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/lldb/source/Symbol/DWARFCallFrameInfo.cpp
index be9f64356b4e0..dc54d13ae23cb 100644
--- a/lldb/source/Symbol/DWARFCallFrameInfo.cpp
+++ b/lldb/source/Symbol/DWARFCallFrameInfo.cpp
@@ -674,6 +674,11 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
               unwind_plan.GetRowAtIndex(0)->GetRegisterInfo(reg_num,
                                                             reg_location))
             row->SetRegisterInfo(reg_num, reg_location);
+          else {
+            // If the register was not set in the first row, remove the
+            // register info to keep the unmodified value from the caller.
+            row->RemoveRegisterInfo(reg_num);
+          }
           break;
         }
         }

diff  --git a/lldb/test/Shell/Unwind/Inputs/eh-frame-dwarf-unwind-abort.s b/lldb/test/Shell/Unwind/Inputs/eh-frame-dwarf-unwind-abort.s
new file mode 100644
index 0000000000000..e03a69f67f8f9
--- /dev/null
+++ b/lldb/test/Shell/Unwind/Inputs/eh-frame-dwarf-unwind-abort.s
@@ -0,0 +1,25 @@
+        .text
+        .globl  asm_main
+asm_main:
+        .cfi_startproc
+        cmpb $0x0, g_hard_abort(%rip)
+        jne .L
+
+        pushq   %rbp
+        .cfi_def_cfa_offset 16
+        .cfi_offset 6, -16
+        movq    %rsp, %rbp
+        .cfi_def_cfa_register 6
+        callq   abort
+.L:
+        .cfi_def_cfa 7, 8
+        .cfi_restore 6
+        int3
+        ud2
+        .cfi_endproc
+
+	.data
+	.globl  g_hard_abort
+g_hard_abort:
+	.byte   1
+	.size   g_hard_abort, 1
\ No newline at end of file

diff  --git a/lldb/test/Shell/Unwind/eh-frame-dwarf-unwind-abort.test b/lldb/test/Shell/Unwind/eh-frame-dwarf-unwind-abort.test
new file mode 100644
index 0000000000000..ccf973d9313c2
--- /dev/null
+++ b/lldb/test/Shell/Unwind/eh-frame-dwarf-unwind-abort.test
@@ -0,0 +1,21 @@
+# Test restoring of register values.
+
+# UNSUPPORTED: system-windows
+# REQUIRES: target-x86_64, native
+
+# RUN: %clang_host %p/Inputs/call-asm.c %p/Inputs/eh-frame-dwarf-unwind-abort.s -o %t
+# RUN: %lldb %t -s %s -o exit | FileCheck %s
+
+process launch
+# CHECK: stop reason = signal SIGTRAP
+
+thread backtrace
+# CHECK: frame #0: {{.*}}`asm_main + 23
+# CHECK: frame #1: {{.*}}`main + {{.*}}
+
+target modules show-unwind -n asm_main
+# CHECK: eh_frame UnwindPlan:
+# CHECK: row[0]:    0: CFA=rsp +8 => rip=[CFA-8]
+# CHECK: row[1]:   14: CFA=rsp+16 => rbp=[CFA-16] rip=[CFA-8]
+# CHECK: row[2]:   17: CFA=rbp+16 => rbp=[CFA-16] rip=[CFA-8]
+# CHECK: row[3]:   22: CFA=rsp +8 => rip=[CFA-8]


        


More information about the lldb-commits mailing list