(Sending this to the main mail list due to the lack of response from gcc-help, 
sorry for the inconvenience.)

Hi GCC folks!
Question regarding the 
docs<https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html> on linkage:
On systems that provide libgcc as a shared library, these options force the use 
of either the shared or static version, respectively. If no shared version of 
libgcc was built when the compiler was configured, these options have no effect.

There are several situations in which an application should use the shared 
libgcc instead of the static version. The most common of these is when the 
application wishes to throw and catch exceptions across different shared 
libraries. In that case, each of the libraries as well as the application 
itself should use the shared libgcc.

Therefore, the G++ driver automatically adds -shared-libgcc whenever you build 
a shared library or a main executable, because C++ programs typically use 
exceptions, so this is the right thing to do.

If, instead, you use the GCC driver to create shared libraries, you may find 
that they are not always linked with the shared libgcc. If GCC finds, at its 
configuration time, that you have a non-GNU linker or a GNU linker that does 
not support option --eh-frame-hdr, it links the shared version of libgcc into 
shared libraries by default. Otherwise, it takes advantage of the linker and 
optimizes away the linking with the shared version of libgcc, linking with the 
static version of libgcc by default. This allows exceptions to propagate 
through such shared libraries, without incurring relocation costs at library 
load time.

However, if a library or main executable is supposed to throw or catch 
exceptions, you must link it using the G++ driver, or using the option 
-shared-libgcc, such that it is linked with the shared libgcc.
We have trouble understanding and/or replicating these two statements:

  1.
...when the application wishes to throw and catch exceptions across different 
shared libraries. In that case, each of the libraries as well as the 
application itself should use the shared libgcc.
  2.
...if a library or main executable is supposed to throw or catch exceptions, 
you must link it using the G++ driver, or using the option -shared-libgcc, such 
that it is linked with the shared libgcc.

The first statement specifically says you must link libgcc shared in order to 
throw/catch exceptions across library boundaries. The second statement misses 
the boundary criteria and instead broadens the limitation to all exception 
handling. We would like to know which one is truer.

Also, is this a guarantee issue or a feasibility one? I.e. it works sometimes 
or it should never work?
The reason for this question is an attached small sample package of a basic 
scenario where the binary and shared libs are linked with static libgcc and 
even libstdc++, demonstrating successful exception handling across shared 
libraries and also exceptions from STL itself. We would like to know if we "got 
lucky" or it is a non-issue in some cases.
We used GCC 12.2.0. Package is attached, if it does not go through, let me know 
where to upload it.

Just unpack and run under the "exception_handling" folder:
$ make
$ ./build/main

Ultimately, our main questions we seek answers for:

  1.
What is the strictest condition for successful, guaranteed exception handling 
when linking libgcc (and potentially libstdc++) statically?
  2.
Does linking libgcc and potentially libstdc++ statically to shared libraries 
mean undefined behavior from an exception handling perspective?
  3.
If we choose to link libstdc++ as static to our shared libraries too, would it 
potentially break exception catching from STL itself? If not, is it guaranteed?

Thank you all in advance,
Andras

Attachment: exception_handling.tar.bz2
Description: exception_handling.tar.bz2

Reply via email to