-
-
Notifications
You must be signed in to change notification settings - Fork 172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
try/catch not work correctly with i686 dwarf exceptions #8
Comments
Thanks, I'll have a look into this. Is this on i686 or x86_64? |
x86_64 with SEH |
Ok, I'll look into it. I do have regular testing with a simple test program in https://github.com/mstorsjo/llvm-mingw/blob/master/test/hello-exception.cpp, but either that's too simple or there's something else going on. Will look into it. |
I can't reproduce any such issue with x86_64 with SEH, it all runs fine - I tested both with and without optimization and with or without With i686 with dwarf I can reproduce the issue though, both with shared and static libcxx. By switching i686 to SJLJ exceptions (adding |
That's strange... I haven't been able to trigger the error with x86_64/SEH once yet. Is it deterministic so that it always works when linking statically and sometimes works/sometimes fails when linking shared? Or does it seem like that's unrelated? If you have an exe which shows this behaviour, can you share it so I can try if it happens for me as well? Is it built just with |
Are you ok with me including this example in my set of regression tests, like the other ones? What should I write as author for the copyright line? |
I get g++ from x86_64-8.1.0-release-win32-seh-rt_v6-rev0.7z, build |
It's ok,put my nickname is ok. |
Ok, I see that your build often fails, and I see the issues you describe if you run it in gdb. Attached is my current build of it (from latest master branch, built within a clean docker container using Dockerfile.dev), and this one seems to run fine for me, both normally and in gdb. |
Yes, your build always fine. I will try to find out why my build have issue. |
I tried rebuild trunk version, does not have this issue. I confirm that it's my own 7.0 backport version‘s bug. |
Ok, thanks for confirming! I would have expected the 7.0 branch to work for SEH though (for llvm/clang/lld), except for libunwind where the SEH support was added a couple weeks after the 7.0 release was branched. (Originally I used libgcc for SEH exceptions, see 6bff543.) As I changed i686 to sjlj exceptions, I guess the rest of this issue is fixed then? |
I used latest libunwind on 7.0, I backport multiple trunk patches to my own 7.0 version, may be some thing wrong with my backport |
I tried debug i686 dwarf exceptions, and build debug version release
debug
|
Yes, changing debug vs release mode will change things drastically. DWARF for i686 should generally work, more or less. My hypothesis is that this is related to DW_CFA_GNU_args_size. This is an opcode which is generated very seldomly, but seems to be generated mostly in cases with a 4 byte aligned stack. There were another issue with this opcode before, which was discussed and later fixed in https://reviews.llvm.org/D38680. (Before this, hello-exception.cpp didn't work in DWARF mode.) As an example, have a look at the output from this:
The Now if I build the same example with -O2:
In this case, the compiler didn't store the old stack pointer in ebp, but instead continuously keeps track of what the offset is to the return pointer on the stack. The To debug the issue, you'll need to trace through the exact generated code for all functions between the throw and the catch, analyze what libunwind does when it is stepping through the functions, and at what point it gets out of sync with the real frames. From your copypasted response, for the case when it fails, it looks like it is correctly unwinding functions for a while, but then it finally declares The backtrace doesn't contain function names, so it's a bit hard to debug from there. Pass |
Just for the record; I tried debugging this a little bit, by hooking up libgcc to handle the exceptions instead of libunwind, and the same issue persists just as before. Therefore, I would say that the bug is in the unwind data produced by Clang, not in libunwind this time. |
I think you are right,I tried use g++ build exception test and link to libunwind, the test cases run correctly. |
That's a good datapoint, but wouldn't be a definite proof either way. The compiler has got great freedom to generate code in lots of different ways, all which produce the right result when you run it, and it only has to produce unwind info that matches the code that it generated. So any other compiler which happens to generate code differently, not using whatever unwind construct that happens to be broken/wrong, would run fine. And any option to clang to adjust the generated code could also happen to avoid the bug. But in this case, neither libunwind nor libgcc can unwind correctly with the unwind data produced by clang/llvm, so it's pretty definite that the unwind info itself is broken. |
Sorry, I have made a wrong test.
and the result still crash, out put print
if link without libunwind
and then crash, gdb said crash at |
In a similar setup, does libunwind work with my simpler testcase in hello-exception.cpp? Getting all of the Although, as I tried to explain, it's not necessarily the same issue in itself, this only says that libunwind doesn't handle the unwind info generated by the compiler for these functions. The unwind info generated by g++ vs clang for libc++ can be wildly different and exercise completely different features of the dwarf interpreter.
That's pretty strange. I guess this is an issue with your setup of libc++ compiled with g++ then?
Yes, that's probably certainly so - libgcc's dwarf unwinding is in very wide use, while libunwind is used in much smaller scale so far.
There's a very important differences in how they find the unwind data: libgcc uses a special pair of libunwind works differently; it uses However, there's one problem with it. So libunwind won't find the So that means that your tests probably don't say anything about libunwind yet. |
i'm having a problem that I guess is similar (on x86_64). An exception is thrown here: https://github.com/grame-cncm/faust/blob/master-dev/compiler/parser/sourcereader.cpp#L360 and caught here : https://github.com/grame-cncm/faust/blob/master-dev/compiler/libcode.cpp#L2089 If I do a
but if I continue, at some point while unwinding I get a segfault:
(of course the whole codebase is built with the same options, and it's all in the same executable) hope it helps ! |
I have redo g++ test with libc++ and libunwind. I found g++ product |
I am trying to set |
That's a great observation. What does the compiler output ( |
Your issue is totally unrelated (the current issue is about dwarf, your issue is with seh) , can you file it separately? Can you produce a reduced testcase that is easy for me to reproduce? If you replace your libunwind.dll with http://martin.st/temp/libgcc/libunwind.dll (which is built from libgcc), does it still behave the same? |
Here is the compiler output , function name is I have debug the catch code optnone
O3
|
That's great progress! I haven't had time to try to read the compiler output yet to see if there's something strange in it, but knowing that the tricky thing is a rethrow in a catch clause, are you able to create a smaller minimal testcase for debugging the issue further? |
I tried many methods to simulate this throw case but can not reproduce. |
Ok, that's a shame - thanks for trying! |
New discovery disable
enable
I can't find more reasons because of limited knowledge. |
Btw, did you see my last comment on the related llvm patch review? The patch has 2 tests, are they duplicates? Should the binary test be left out? |
I got time to look closer at this issue, and I managed to narrow it down to a few LLVM optimizations that don't work properly together, namely X86 call frame optimization and tail merging. See https://bugs.llvm.org/show_bug.cgi?id=40012 for details. The issue can be avoided by compiling with |
This issue was fixed upstream in LLVM in https://reviews.llvm.org/D61252 (SVN r359496), which now is included in the pinned LLVM version here, and in the latest prebuilt release (that I just made). |
thanks for the info ! |
sismple test program
with static libcxx result
with shared libcxx result
The text was updated successfully, but these errors were encountered: