bebbo / amiga-gcc

The GNU C-Compiler with Binutils and other useful tools for cross development for Amiga
GNU General Public License v2.0
313 stars 66 forks source link

Exceptions are not caught with GCC 6.5.0b #218

Closed hitman-codehq closed 3 years ago

hitman-codehq commented 3 years ago

Hello.

I am not sure if this is something you can help with bebbo. But I thought perhaps it is something to do with the linker scripts used in your GCC and I guess for those, you must have edited them to make them work with the Amiga. So here goes with my problem.

I have a problem with exceptions not getting caught when they should. If you have a look at the attached test case, you can see that there is an exception called SocketError that is defined in Exception.h and there are two test cases that use this.

Working.cpp includes Exception.h and then it throws a SocketError exception and catches it successfully (on both Windows and Amiga OS).

Broken.cpp also includes Exception.h, but the exception is thrown in the file Exception.cpp. This example does not catch the exception successfully on Amiga OS! Instead of catching it in "catch (SocketError &exception)" it catches it in "catch (...)". But on Windows it works.

You can build for Windows with a simple "make" and for Amiga OS with "set PREFIX=m68k-amigaos-" and then "make".

Could this be something to do with the linker scripts that your GCC 6.5.0b use? It is as though some type information is being lost so the catch in Broken.cpp cannot determine the type of the exception that is thrown from Exception.cpp. I can't believe that it is only a problem with GCC 6.5.0 (or maybe it is?) but then if it is not a problem with GCC 6.5.0 then it must be something to do with your port. But what?

Sorry, this is maybe a tough bug. I'm not sure if you can do anything to fix it but I thought I would ask!

Exceptions.zip

bebbo commented 3 years ago

that's a linker issue and the same as #156.

=> build for m68k-elf and used elf2hunk

hitman-codehq commented 3 years ago

I'm not sure what you mean. I tried the solution mentioned on that issue of making sure that there was no code defined in the .h file. I moved the definition of the SocketError() constructor and what() method into the .cpp file, but the problem is still happening.

Could you give a bit more details about what you mean by "build for m68k-elf and use elf2hunk"?

bebbo commented 3 years ago

I'm not sure what you mean. I tried the solution mentioned on that issue of making sure that there was no code defined in the .h file. I moved the definition of the SocketError() constructor and what() method into the .cpp file, but the problem is still happening.

The challenge: gcc creates type infos - also for exceptions. That info is more or less complete per object file. To get it work properly the linker has to support weak sections to collect the complete information. Right now the linker picks one version and if that is incomplete a subtype may not be visible and can't be caught.

hitman-codehq commented 3 years ago

Ok I understand now. In my case the problem was that there was no typeinfo. The suggested solution of moving all implementation into the .cpp file and having nothing implemented in the .h file didn't work - there is still no typeinfo. And when I tried the mentioned solution with a class that derived from std::exception it was even worse - it wouldn't link due to a missing typeinfo error!

It turns out that I had to have at least one virtual method in order to generate the typeinfo and then it linked and picked up the correct exception at runtime. This now works:

try { ... } catch (RSocket::Error &exception) { // This works now! }

It was enough to just have an empty implementation of RSocket::~Error() in my .cpp file (the destructor is declared as virtual in std::exception).

Many thanks for the help getting this tricky one sorted out!

bebbo commented 3 years ago

both version are printing now:

Caught a SocketError

please test

hitman-codehq commented 2 years ago

Hi @bebbo. I am trying to test this using a self-built version of the latest GCC on MacOS, but when compiling I get errors with sed and the ndk13 being extracted. Not sure what I am doing wrong as it built fine the last time I tried. I have attached the log file from "log/extract ndk13.log" so perhaps you have seen this problem? It is lots of things like:

sed: 1: "/opt/amiga/m68k-amigaos ...": command a expects \ followed by text

hitman-codehq commented 2 years ago

extract ndk13.log

bebbo commented 2 years ago

Hi @bebbo. I am trying to test this using a self-built version of the latest GCC on MacOS, but when compiling I get errors with sed and the ndk13 being extracted. Not sure what I am doing wrong as it built fine the last time I tried. I have attached the log file from "log/extract ndk13.log" so perhaps you have seen this problem? It is lots of things like:

sed: 1: "/opt/amiga/m68k-amigaos ...": command a expects \ followed by text

Since these message do not appear on Linux, it's probably a MacOS problem. I do not support MacOS - someone else has to provide a patch.

hitman-codehq commented 2 years ago

I am happy to help to support MacOS, patch provided in another issue.

In the meantime I managed to build for MacOS and retested this issue, and can confirm that the exception problem is indeed fixed. Many thanks!