1

My dev env is: Ubuntu 16.04 64bit. g++ 5.4.0 64bit toolchain. I am porting some code from Windows to Linux that invloves ASIO lib.In some places I have to a logic to catch exceptions from asio::read() and asio::write(). And those are not being caught by try...catch() neither in release nor in debug modes. So to understand if the problem with ASIO or my usage of it I just put this code in my main.cpp:

  class  Foo
  {
   public:
      Foo(){}
      void ThrowExc()
      {
        throw std::runtime_error("I am exception!");
      }
  };

  int main(int argc, char *argv[])
  {

    Foo f;
    try
    {
       f.ThrowExc();
    }
    catch(std::exception &e)
    {
       std::cout<<"Exception caught" << std::endl;
    }

It doesn't work.The program crashes with the call stack looking like this:

0 0x00007ffff57188bd __cxa_throw

1 0x000000000040e5ab Foo::ThrowExc /main.cpp 32

2 0x000000000040d16c main main.cpp 45

My C++ compiler flags are: -g;-std=c++14;-Wall;-fexceptions;-fPIC

UPDATE:

Some commenters pointed out that the issue can be with my project's code somewhere else. So I created a new empty project from scratch, main.cpp only. With the code shown above. Still the same problem.

UPDATE 1:

I am still not sure what was the exact issue.But It looks like my GNU version tool-chains were not set correctly. I had gcc from version x and g++ from version Y. So I reinstalled the compilers and reset their symlinks. Used this page for manual.

Michael IV
  • 11,016
  • 12
  • 92
  • 223
  • Alway use a `const` reference to catch: `catch(const std::exception &e)` – user0042 Aug 26 '17 at 13:04
  • 2
    How I like those downvoters. Const is not an issue here. Thanks for the tip. Nasty place SO has become to ask stuff. – Michael IV Aug 26 '17 at 13:05
  • @user0042 why do you think OP have to use const reference? – W.F. Aug 26 '17 at 13:06
  • 1
    @MichaelIvanov can you reproduce e.g. on https://wandbox.org/ ? – W.F. Aug 26 '17 at 13:07
  • @W.F. Exceptions always should be caught as const references. – user0042 Aug 26 '17 at 13:07
  • 2
    @user0042 not true. c.f. [this](https://stackoverflow.com/questions/2145147/why-catch-an-exception-as-reference-to-const) – W.F. Aug 26 '17 at 13:07
  • @W.F. Can you tell me a use case when not? – user0042 Aug 26 '17 at 13:08
  • @user0042 e.g. when you want to rethrow – W.F. Aug 26 '17 at 13:09
  • @WF You can rethrow with a const reference, or simply use `throw;`. – user0042 Aug 26 '17 at 13:11
  • 2
    @user0042 but you may want to add some important information to the exception before rethrowing – W.F. Aug 26 '17 at 13:12
  • 1
    @MichaelIvanov [No repro](http://coliru.stacked-crooked.com/a/6998967d6031d684). – user0042 Aug 26 '17 at 13:13
  • 2
    @user0042 - Would have been better to use all of the OP's compiler flags. [But yes, no reproducing it with them as well](http://coliru.stacked-crooked.com/a/eeeb0f5135f4385c). – StoryTeller - Unslander Monica Aug 26 '17 at 13:27
  • I don't use `gcc` but as options are different, I guess that OP options are not compatible with exceptions. Although `const` should not be necessary, you might try to add it anyway (**sometime compiler are bugged**) or try by value or try to catch the derived class and see if you get the problem anyway. You could also try a `catch(...)`. – Phil1970 Aug 26 '17 at 13:28
  • @Phil1970 No OP's compiler flags are fine. The problem must be elsewhere in code not shown. The example is oversimplified and not a [MCVE]. – user0042 Aug 26 '17 at 13:29
  • @MichaelIvanov - As you can see, newer versions of GCC do not reproduce the issue. Can you upgrade from g++ 5.4.0? It may be a compiler bug. – StoryTeller - Unslander Monica Aug 26 '17 at 13:29
  • @W.F. _"but you may want to add some important information"_ In such case I'd throw another new exception maybe with the original one passed in the constructor. Changing exceptions in `catch` clauses is bad design, period. – user0042 Aug 26 '17 at 13:31
  • 3
    @user0042 - Arguments that rely on a "period" are bad arguments. They mostly show you can't back up your claims factually, and thus need to rely on dogma. – StoryTeller - Unslander Monica Aug 26 '17 at 13:33
  • Tried const etc, no go.But now I will try a brand new prog from scratch. – Michael IV Aug 26 '17 at 13:35
  • @user42 Well, I am not sure if by rethrowing another exception one can loose some informations that might be useful for debugging purpose... the same way it is preferable to rethrow an existing exception than a copy. One might want to more or less do a stack trace or capture the state of some variables when a problem occurs and the information is not available at the point where the exception is thrown. **Although in theory I agree with you, sometime in practice extra information might be useful. So it is better to modify original exception or create a copy with some information changed?** – Phil1970 Aug 26 '17 at 13:39
  • @Phil I didn't mean an exact copy, sorry. In such case I'd use an exception class that has something like a `const std::exception& innerException;` so you can pile them up when going through different layers of your application. – user0042 Aug 26 '17 at 13:45
  • Tried running that code in a completely new project. Same problem. – Michael IV Aug 26 '17 at 15:19
  • Old compiler isn't the issue. On Ubuntu 64 14.04 LTS, with gcc 4.8.4, I added some #includes and a closing bracket, compiled with "gcc main.cpp -lstdc++" and ran the program. It printed out "Exception caught". It also works with all the options you mentioned except not -std=c++14 obviously, because that version only went up to c++11 – Kenny Ostrom Aug 26 '17 at 15:56
  • 1
    Well, guys, in order to solve that I had to learn a little bit more regarding sym links and compilers config. It loos like my version toolchain wasn't set correctly. I had gcc from version x and g++ from version Y. So I reinstalled the compilers and reset their symlinks. Used this page for help: https://askubuntu.com/questions/26498/choose-gcc-and-g-version – Michael IV Aug 26 '17 at 17:19

1 Answers1

0

To be catchable exception thrown must be declared in header. Try this

class  Foo {
public:
  Foo(){}
  void ThrowExc() throw (std::exception) {
     throw std::runtime_error("I am exception!");
  }
};

int main(int argc, char *argv[]) {
  Foo f;
  try  {
    f.ThrowExc();
  }
  catch(std::exception &e) {
    std::cout<<"Exception caught" << std::endl;
  }
}
Saint-Martin
  • 306
  • 3
  • 16
  • 1
    Dynamic `throw` specifications are obsolete and deprecated. This won't help. – Quentin Aug 28 '17 at 14:36
  • "throw specifications are obsolete and deprecated" ??? Do you mean now, all exceptions are catchable ? – Saint-Martin Aug 29 '17 at 07:34
  • Not sure what you mean by that. Dynamic exception specifications have been replaced with `noexcept` specifications. – Quentin Aug 29 '17 at 07:37
  • All exceptions were always catchable. What Dynamic throw specifications did was to call std::terminate() if something else was thrown – sp2danny Sep 01 '17 at 13:32