Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
353 views
in Technique[技术] by (71.8m points)

c++ - Why can a thrown exception with hidden visibility still be caught

I'm having a CI failure of my program which uses Boost.ProgramOptions. It fails to catch an exception thrown inside the Boost shared library. But this only happens on OSX.

The problem boils down to cross-boundary exception handling with shared objects and hidden visibility.

What happens is:

  • Boost is build with hidden visibility, the exception thrown is marked with default visibility
  • When consumed the exception in the Boost header is not marked with anything
  • When the consuming program is build with default visibility all works as expected
  • When building the consuming program with hidden visibility it fails to catch the exception on OSX only (windows and Linux work across multiple compilers)

I found: https://gcc.gnu.org/wiki/Visibility

Symbol visibility is "default" by default but if the linker encounters just one definition with it hidden - just one - that typeinfo symbol becomes permanently hidden (remember the C++ standard's ODR - one definition rule).

So this (and the rest of the C++ exception paragraph) says, that the OSX behavior is what is expected.

This should also be shown by "Version 3" of http://www.ce.unipr.it/people/medici/visibility_and_shared_object.html which is basically an MWE:

my_hidden_exception.h

class my_exception {
  public:
  virtual ~my_exception() throw() { }
  virtual const char*
          what() const throw() { return "my_exception"; }
};

main.cpp:

#include <iostream>
#include "my_hidden_exception.h"

int my_object();

int main()
{
  try{
    my_object();
  }
  catch(my_exception & e)
  {
    std::cout << e.what() << std::endl;
  }
}

shared.cpp:

#include "my_hidden_exception.h"

int __attribute__ ((visibility("default"))) my_object()
{
  throw my_exception();
}

Compile and run with

g++ -shared -o libshared.so shared.cpp -fvisibility=hidden -fvisibility-inlines-hidden
g++ -o main main.cpp -lshared -L. -fvisibility=hidden -fvisibility-inlines-hidden
./main 

My problem now is that I'm unable to reproduce this with any GCC (7, 10) or Clang (6, 9) I tested, in all cases the exception is successfully caught which according to all sources shouldn't be possible.

Can anyone explain what I'm missing here? How can I "force" the correct behavior on Linux for better testing (OSX testers are hard(er) to come by)?

question from:https://stackoverflow.com/questions/65951466/why-can-a-thrown-exception-with-hidden-visibility-still-be-caught

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...