2018-01-16 18:18 GMT+08:00 Tim Northover <t.p.northover at gmail.com>:> On 15 January 2018 at 12:49, 陳韋任 via llvm-dev <llvm-dev at lists.llvm.org> > wrote: > > - CFI directives: > > > > This is for .eh_frame section. Basically all the targets insert CFI > > directives in FrameLowering, but I am not sure exactly when/where I > should > > do so. > > The directives are there to describe where the unwinder should look to > find out what each register's value was when this function was called > (well, each register that the caller expected to be preserved). So the > directives have to have been emitted by the time any instruction is > executed that could cause an exception to be thrown (typically either > a call to another function or a compiler-generated call to __cxa_throw > or similar when the source code itself contains "throw X"). > > So normally the directives are emitted in the prologue when the > registers actually get saved. Sometimes all in a bunch, sometimes > interspersed with the saves, but it usually doesn't matter which. As > you've discovered that happens in XYZFrameLoweringDo we have to emit directives in the epilogue, too? One of my test case fail due to the directives in the epilogue have been executed. After remov ing them from epilogue, the exception is caught as expected. Also, the directives are also for debug purpose (.debug_frame), right? I guess I only have to make sure directives work for exception handling, then debug works as well? -- Wei-Ren Chen (陳韋任) Homepage: https://people.cs.nctu.edu.tw/~chenwj -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180116/fedda1a7/attachment.html>
Tim Northover via llvm-dev
2018-Jan-16 13:03 UTC
[llvm-dev] Exception handling support for a target
On 16 January 2018 at 12:23, 陳韋任 <chenwj.cs97g at g2.nctu.edu.tw> wrote:> Do we have to emit directives in the epilogue, too? One of my test case fail > due to the directives in the epilogue have been executed. After removing > them from epilogue, the exception is caught as expected.Emitting directives in the epilogue is hard because the directives apply to all instructions after in program-counter order. So if you have an epilogue in the middle of a function and emit CFI directives saying the registers are back where they were then the unwinder will think that applies to the rest of the function too. To fix that you'd have to emit yet more directives in the basic block immeditately following the epilogue. Most people don't bother with either because you'd only really need it if you expected to have to catch an exception in the epilogue (which is impossible on most platforms).> Also, the > directives are also for debug purpose (.debug_frame), right? I guess I only > have to make sure directives work for exception handling, then debug works > as well?Yep. Technically you can stop the debugger in the middle of a prologue or epilogue, at which point having more fine-grained directives can help. In practice there's no real reason to do that so people don't emit directives for it (at least not as a high priority). Cheers. Tim.
2018-01-16 21:03 GMT+08:00 Tim Northover <t.p.northover at gmail.com>:> On 16 January 2018 at 12:23, 陳韋任 <chenwj.cs97g at g2.nctu.edu.tw> wrote: > > Do we have to emit directives in the epilogue, too? One of my test case > fail > > due to the directives in the epilogue have been executed. After removing > > them from epilogue, the exception is caught as expected. > > Emitting directives in the epilogue is hard because the directives > apply to all instructions after in program-counter order. So if you > have an epilogue in the middle of a function and emit CFI directives > saying the registers are back where they were then the unwinder will > think that applies to the rest of the function too. > > To fix that you'd have to emit yet more directives in the basic block > immeditately following the epilogue. Most people don't bother with > either because you'd only really need it if you expected to have to > catch an exception in the epilogue (which is impossible on most > platforms).My test case is: void foo() { throw 0; } void bar() { try { foo(); } catch (...) { throw 0; } } int main() { try { bar(); } catch (...) { return 0; // fail to catch exception thrown by bar } return 0; } , and the assembly of bar looks like bar: .cfi_def_cfa_offset 16 epilogue _Unwind_Resume The lookup phase of exception handling is fine. However, something goes wrong in cleanup phase. The reason is the unwinder evaluates CFI directives until _Unwind_Resume, and `.cfi_def_cfa_offset 16` is the culprit. I think this is what you were saying "have an epilogue in the middle of a function", right? -- Wei-Ren Chen (陳韋任) Homepage: https://people.cs.nctu.edu.tw/~chenwj -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180116/2ed0f8f9/attachment.html>