This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Fix handling of cfi_restore in the unwinder
ClosedPublic

Authored by jarin on Jun 15 2023, 9:30 AM.

Details

Summary

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.

This patch changes handling of cfi_restore to reset the location if
the first unwind table row does not map the restored register.

Diff Detail

Event Timeline

jarin created this revision.Jun 15 2023, 9:30 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 15 2023, 9:30 AM
jarin requested review of this revision.Jun 15 2023, 9:30 AM
jasonmolenda accepted this revision.Jun 15 2023, 4:13 PM
jasonmolenda added a subscriber: jasonmolenda.

I can see why the existing code is written as it is, given the dwarf spec for DW_CFA_restore: "The DW_CFA_restore instruction takes a single operand (encoded with the opcode) that represents a register number. The required action is to change the rule for the indicated register to the rule assigned it by the initial_instructions in the CIE". The mistake in the current code is that any register not mentioned in the CIE state (the unwind rules at Row 0 in this UnwindPlan) is the unmodified value of the caller.

This patch is correct; the register was not mentioned in the CIE so should say there is no unwind rule for this register - it is the unmodified value of the caller function. I probably would have added a comment to this new line in the else block saying that explicitly, but that's just a personal preference.

This revision is now accepted and ready to land.Jun 15 2023, 4:13 PM
jarin updated this revision to Diff 531987.Jun 15 2023, 10:21 PM

Added a comment explaining that we are restoring the caller's value of the register.

This revision was automatically updated to reflect the committed changes.

Looks like this is failing on the Darwin x86_64 buildbots: https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/56510/execution/node/74/log/

Exit Code: 1

Command Output (stderr):
--
clang: warning: argument unused during compilation: '-fmodules-cache-path=/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/lldb-test-build.noindex/module-cache-clang/lldb-shell' [-Wunused-command-line-argument]
/Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/lldb/test/Shell/Unwind/Inputs/eh-frame-dwarf-unwind-abort.s:25:2: error: unknown directive
 .size g_hard_abort, 1
 ^

********************
Failed Tests (1):
  lldb-shell :: Unwind/eh-frame-dwarf-unwind-abort.test
jarin added a comment.Jun 16 2023, 3:50 AM

Looks like this is failing on the Darwin x86_64 buildbots: https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/56510/execution/node/74/log/

Exit Code: 1

Command Output (stderr):
--
clang: warning: argument unused during compilation: '-fmodules-cache-path=/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/lldb-test-build.noindex/module-cache-clang/lldb-shell' [-Wunused-command-line-argument]
/Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/lldb/test/Shell/Unwind/Inputs/eh-frame-dwarf-unwind-abort.s:25:2: error: unknown directive
 .size g_hard_abort, 1
 ^

********************
Failed Tests (1):
  lldb-shell :: Unwind/eh-frame-dwarf-unwind-abort.test

I removed the offending directive. Feel free to revert all this if there are still problems.

This is now failing with:

clang: warning: argument unused during compilation: '-fmodules-cache-path=/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/lldb-test-build.noindex/module-cache-clang/lldb-shell' [-Wunused-command-line-argument]
Undefined symbols for architecture x86_64:
  "abort", referenced from:
      asm_main in eh-frame-dwarf-unwind-abort-edbc93.o
     (maybe you meant: g_hard_abort)
ld: symbol(s) not found for architecture x86_64

https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/56648/execution/node/74/log/?consoleFull