Bug 46097 - Switch to warn of global variables in a C++ shared object
Summary: Switch to warn of global variables in a C++ shared object
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-10-20 14:35 UTC by Jeffrey Walton
Modified: 2014-07-10 00:33 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Test for Load/Unload Crash (3.53 KB, text/x-c++src)
2010-10-22 05:52 UTC, Jeffrey Walton
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jeffrey Walton 2010-10-20 14:35:40 UTC
Feature reqeust only. Not a bug.

C++ shared objects are an interesting beast under certain circumstances (many times, the shared object acts like a generic C module). Interesting includes:
* C++ module
* Shared object
* Shared object throws an exception which will cross module boundaries
* Shared object opened with RTLD_GLOBAL
* Shared object has global objects with destructors

Lots have been said about C++ exceptions, RTTI, type equality for the 'catch(const Exception&)', and RTLD_GLOBAL (versus RTLD_LOCAL) [1,2,3,4,5].

When a module meets the above compile and runtime requirements, a crash can occur in global objects with destructors when more than one process loads and subsequently unloads a shared object.

A switch to warn of global variables in a compilation unit would be very helpful for those who are aware of the issue (and the circumstances to encounter the issue). It appears that GCC does not supply such a switch [6].

The switch would be useful for module writers since its not always feasible to 'hand audit' all project files. And a warning would be exetremely useful for package maintainers who don't write the module - they simply fixup the code and package it for a distribution.

Perhaps -Wglobal-variable?

Jeffrey Walton
Baltimore, MD, US

[1] Minimal GCC/Linux shared lib + EH bug example, http://gcc.gnu.org/ml/gcc/2002-05/msg00866.html
[2] dlopen and placing exception body in .cpp file, http://gcc.gnu.org/ml/gcc-help/2010-08/msg00290.html
[3] Comparing types across SOs (sic), http://groups.google.com/group/cryptopp-users/browse_thread/thread/eb815f228db50380
[4] Errors with multiple loading cryptopp as shared lib on Linux, http://groups.google.com/group/cryptopp-users/browse_thread/thread/68fbc22e8c6e2f48
[5] RTLD_GLOBAL and libcryptopp.so crash, http://groups.google.com/group/cryptopp-users/browse_thread/thread/7eae009a4e02e726
[6] Audit Use of Global Variables in C++ Shared Object (GCC Warning?), GCC-Help mailing list, October, 2010 [not yet indexed].
Comment 1 Jonathan Wakely 2010-10-20 15:52:53 UTC
(In reply to comment #0)
> When a module meets the above compile and runtime requirements, a crash can
> occur in global objects with destructors when more than one process loads and
> subsequently unloads a shared object.

Are you saying independent processes interfere with each other?
Comment 2 Jeffrey Walton 2010-10-20 17:33:43 UTC
(In reply to comment #1)
> (In reply to comment #0)
> > When a module meets the above compile and runtime requirements, a crash can
> > occur in global objects with destructors when more than one process loads and
> > subsequently unloads a shared object.
> Are you saying independent processes interfere with each other?
Yes and No :/

If each process loads the SO with RTLD_LOCAL, then No. If the processes each load with RTLD_GLOBAL (so an exception can be caught) *AND* the SO has an non-trivial global (such as an object with a destructor) then YES.

Crpyto++ has a test case demonstrating the RTLD_GLOBAL crash at [1]. [1] is accompanied by an analysis under GDB at [2]. Unfortunately, the test case is not minimal. It is based on the Crypto++ library and needs intermediate SOs to load the SO of interest. So the final executable never directly loads the Crypto++ shared object.

Based on the demonstartion, Wei Dai modified global objects so that only PODs were global. Non-trivial objects were hidden in a GetGlobalXxx() (some hand waiving). A write up distribution packagers (from our understanding of the moving parts) is available at [3,4].

[1] http://www.cryptopp.com/w/images/8/89/Cryptopp-SO-Test-1.zip
[2] http://groups.google.com/group/cryptopp-users/browse_thread/thread/7eae009a4e02e726
[3] http://www.cryptopp.com/wiki/Linux#Note_for_Shared_Object_Callers
[4] http://www.cryptopp.com/wiki/Linux#Note_for_Distribution_Packagers
Comment 3 Jeffrey Walton 2010-10-20 17:38:59 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > (In reply to comment #0)
> > > When a module meets the above compile and runtime requirements, a crash can
> > > occur in global objects with destructors when more than one process loads and
> > > subsequently unloads a shared object.
> > Are you saying independent processes interfere with each other?
> ...
> Crpyto++ has a test case demonstrating the RTLD_GLOBAL crash at [1]. [1] is
> accompanied by an analysis under GDB at [2]. Unfortunately, the test case is
> not minimal. It is based on the Crypto++ library and needs intermediate SOs to
> load the SO of interest. So the final executable never directly loads the
> Crypto++ shared object.
If a picture is worth a 1000 words, here's the scenario we are trying to accomplist (to verify Crypto++ does not crash when unloaded). But keep in mind that two distinct process will perform what's in the image. http://www.cryptopp.com/wiki/File:Cryptopp-so-test.png
Comment 4 Jonathan Wakely 2010-10-20 22:46:45 UTC
I had a look at Cryptopp-SO-Test-1.zip

building on 32-bit I can reproduce a segfault

it doesn't build on 64-bit at all:

1) you can insert a pointer into an ostream without casting to int (and if you insist on casting, do it to a type that has the same size as a pointer!)

2) that makefile doesn't compile dsotest-1.o and dsotest-2.o with -fPIC

To get it build I had to edit the code and the makefile, and after doing so it doesn't crash. And with the same changes, it doesn't crash on 32-bit either.

So are you sure this isn't just user error?

I can see some value in the warning you want, but it's not going to help if you don't use the compiler correctly (maybe I'm being unfair and you're using it correctly for 32-bit, but my first instinct is that if it fails to build for a different target then *something* is wrong!)
Comment 5 Jonathan Wakely 2010-10-20 22:47:59 UTC
oh, and I only see one process invovled there ... I'm still confused about the claim that more than one process is involved - do you mean more than one thread?!
Comment 6 Jeffrey Walton 2010-10-20 23:18:48 UTC
Hi Johnathon,

(In reply to comment #5)
> oh, and I only see one process invovled there ... I'm still confused about the
> claim that more than one process is involved...
My bad - the image only depicts one process. However, the first thing main() does is a fork to get two processes in play.

> do you mean more than one thread?!
Multiple threads were an artifact of trying to reproduce the original issue (it turned out to be Shared object, RTLD_GLOBAL, and multiple processes). But the multiple threads made for a nice stress test ;)

==============================================

Try crypto++ 5.6.0 (which _had_ global objects) located at http://www.cryptopp.com/cryptopp560.zip. Crypto 5.6.1 fixed the global object problem.
The stress test which should trigger the issue (depicted in the image) is located at http://www.cryptopp.com/w/images/b/be/Cryptopp-SO-Test.zip.

==============================================

Sorry about the poor Linux skills at times. I'm a Windows guy, and its frustrating when I know what I want to say in terms of Windows, but not in terms of Linux.

Jeff
Comment 7 Jonathan Wakely 2010-10-20 23:48:33 UTC
(In reply to comment #6)
> Hi Johnathon,
> (In reply to comment #5)
> > oh, and I only see one process invovled there ... I'm still confused about the
> > claim that more than one process is involved...
> My bad - the image only depicts one process. However, the first thing main()
> does is a fork to get two processes in play.

No fork() in the first zipfile I looked at (from [1] in comment 2), and unless the globals use something inter-process such as semaphores or file locking, there is no way they should interfere with globals in other processes. Using RTLD_GLOBAL, exceptions or RTTI doesn't change the fact that processes have their own memory space.


> Try crypto++ 5.6.0 (which _had_ global objects) located at
> http://www.cryptopp.com/cryptopp560.zip. Crypto 5.6.1 fixed the global object
> problem.
> The stress test which should trigger the issue (depicted in the image) is
> located at http://www.cryptopp.com/w/images/b/be/Cryptopp-SO-Test.zip.

Ah, I tried that stress test against 5.6.1 as that's what my distro provides. That stress test *does* use fork, but didn't crash for me.   If I get time tomorrow I'll try it against 5.6.0

I'm probably taking this enhancement request waaaay off-topic, I just want to convince myself you're not wasting time asking for a warning that won't help prevent user error
Comment 8 Jeffrey Walton 2010-10-21 02:00:51 UTC
(In reply to comment #4)
> I had a look at Cryptopp-SO-Test-1.zip
> 
> <SNIP>
> 
> I can see some value in the warning you want, but it's not going to help if you
> don't use the compiler correctly (maybe I'm being unfair and you're using it
> correctly for 32-bit, but my first instinct is that if it fails to build for a
> different target then *something* is wrong!)

For completeness, while trying to avoid a pissing contest:

I agree the file should have been (and should be) correct wrt x64 (I should have walked it over to an x64 machine and tried it). And I know my *nix skills are rusty - its been over 10 years since I needed them. The last time I used them was circa RedHat shipping a broken compiler, which I believe occurred at RedHat 4.0 or 5.0 (back then, we usually had to rebuild our own kernel due to poor network card support and drivers that were worse). 

Finally, the feature request and the underlying reason for the request are not really related. Despite poor sample code on my part, I believe programmers and package maintainers could benefit from the ability to have GCC issue warnings during compilation, rather than using objdump or nm later to tease out the information later.

Jeff
Comment 9 Jeffrey Walton 2010-10-21 15:04:44 UTC
(In reply to comment #4)
> I had a look at Cryptopp-SO-Test-1.zip
> 
> building on 32-bit I can reproduce a segfault
> 
> it doesn't build on 64-bit at all:
> 
> 1) you can insert a pointer into an ostream without casting to int (and if you
> insist on casting, do it to a type that has the same size as a pointer!)
> 
> 2) that makefile doesn't compile dsotest-1.o and dsotest-2.o with -fPIC
> 
> To get it build I had to edit the code and the makefile, and after doing so it
> doesn't crash. And with the same changes, it doesn't crash on 32-bit either.
> 
> So are you sure this isn't just user error?
> 
> I can see some value in the warning you want, but it's not going to help if you
> don't use the compiler correctly (maybe I'm being unfair and you're using it
> correctly for 32-bit, but my first instinct is that if it fails to build for a
> different target then *something* is wrong!)
Another person just got bit by the C++ global/shared object bug. See "Global variable in static library - double free or corruption error" by Alexey Skidanov. It so 'fresh' that it has not been indexed yet - so I can't provide a link.
Comment 10 Jonathan Wakely 2010-10-21 15:16:48 UTC
you realise you can wait and it will show up?
http://gcc.gnu.org/ml/gcc-help/2010-10/msg00248.html
That, like your case, is an ODR violation, and like your example static.cpp was not compiled with -fPIC

In response to your reply to him, I really don't think a warning about global variables is suitable for -Wall!

could you be a bit less vague about what exactly you want the warning to do?

should it only warn about globally visible objects in shared libraries?
that wouldn't help that case, where the problematic global is in static.o, which isn't compiled with -fPIC or -shared, so the warning would have to come from the linker when static.o is linked to dynamic1.o or dynamic2.o
Comment 11 Jonathan Wakely 2010-10-21 15:22:03 UTC
also, I'm not "the GCC team" and I don't speak for anyone else
Comment 12 Jonathan Wakely 2010-10-21 15:28:05 UTC
I'm not on gcc-help, but I assume Alexey's looking at this report now ...

> I would expect that TWO different instances of the global variable would
> be created in TWO different shared libraries - maybe with name mangling.

No, the compiler can't just add random mangling to symbols, that would mean the linker can't find symbols!

If you want those objects to be distinct, put them in distinct namespaces (possibly anonymous namespaces) to disambiguate them, as mentioned at http://gcc.gnu.org/faq.html#dso
Otherwise you have an ODR violation due to two definitions of the same object.
Comment 13 Jeffrey Walton 2010-10-21 16:10:41 UTC
Hi Jonathon,

(In reply to comment #10)
> you realise you can wait and it will show up?
> http://gcc.gnu.org/ml/gcc-help/2010-10/msg00248.html
I've been known to be impatient at times :/

> That, like your case, is an ODR violation, and like your example static.cpp was
> not compiled with -fPIC
Ah! I was not aware I was violating anything :/ And the packagers were probably not aware they were violating anything (but I can't speak for them).

> In response to your reply to him, I really don't think a warning about global
> variables is suitable for -Wall!
Agreed.

> could you be a bit less vague about what exactly you want the warning to do?
> 
> should it only warn about globally visible objects in shared libraries?
> that wouldn't help that case, where the problematic global is in static.o,
> which isn't compiled with -fPIC or -shared, so the warning would have to come
> from the linker when static.o is linked to dynamic1.o or dynamic2.o

Good point: here's what I would recommend: common sense. Myself, Alexey, a number of packagers across the globe, and untold others have performed this ODR violation. Since you know more about the subject matter than me (I would like to think of you as a SME - subject matter expert), what would you recommend so that folks like myself, Alexey, distribution packagers, and others don't go shooting ourselves in the foot?
Comment 14 Jeffrey Walton 2010-10-21 16:13:36 UTC
(In reply to comment #7)
> (In reply to comment #6)
> > Hi Johnathon,
> > (In reply to comment #5)
> > > oh, and I only see one process invovled there ... I'm still confused about the
> > > claim that more than one process is involved...
> > My bad - the image only depicts one process. However, the first thing main()
> > does is a fork to get two processes in play.
> 
> [SNIP]
> 
> I'm probably taking this enhancement request waaaay off-topic, I just want to
> convince myself you're not wasting time asking for a warning that won't help
> prevent user error

I don't believe this is way of topic considering the number of folks who seem to have a need for the assistance from GCC (including packagers/maintainers). See comment 13 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46097#c13).

Jeff
Comment 15 Jeffrey Walton 2010-10-21 16:15:38 UTC
(In reply to comment #11)
> also, I'm not "the GCC team" and I don't speak for anyone else

My apologies. I made the leap that you were part of the team due to your email address.
Comment 16 Jonathan Wakely 2010-10-21 16:24:18 UTC
(In reply to comment #13)
> 
> Good point: here's what I would recommend: common sense. Myself, Alexey, a
> number of packagers across the globe, and untold others have performed this ODR
> violation. Since you know more about the subject matter than me (I would like
> to think of you as a SME - subject matter expert), what would you recommend so
> that folks like myself, Alexey, distribution packagers, and others don't go
> shooting ourselves in the foot?

There are a number of options for making sure the global is private to the library, thus avoiding multiple definitions of the same object when two copies of the code are linked to.

* You can make the global object have static linkage.

* You can put it in an anonymous namespace.

* You can give it non-global visibility.


(In reply to comment #15)
> (In reply to comment #11)
> > also, I'm not "the GCC team" and I don't speak for anyone else
> 
> My apologies. I made the leap that you were part of the team due to your email
> address.

This is Free Software, I'm just one contributor among many, I don't speak for "the team"
Comment 17 Jeffrey Walton 2010-10-21 16:59:55 UTC
(In reply to comment #16)
> (In reply to comment #13)
> > 
> > Good point: here's what I would recommend: common sense. Myself, Alexey, a
> > number of packagers across the globe, and untold others have performed this ODR
> > violation. Since you know more about the subject matter than me (I would like
> > to think of you as a SME - subject matter expert), what would you recommend so
> > that folks like myself, Alexey, distribution packagers, and others don't go
> > shooting ourselves in the foot?
> 
> There are a number of options for making sure the global is private to the
> library, thus avoiding multiple definitions of the same object when two copies
> of the code are linked to.
> 
> * You can make the global object have static linkage.
> 
> * You can put it in an anonymous namespace.
> 
> * You can give it non-global visibility.
For completeness, Crypto++ used:

GlobalVariable& GetGlobalVariable()
{
    static GlobalVariable globalVariable;
    return globalVariabl
}

And Vladimir Simonov recommended (http://gcc.gnu.org/ml/gcc-help/2010-10/msg00256.html):
-fvisibility=hidden

Lots of good mechanisms. Unfortunately, it's not readily apparent when they need to be used by whom. I think GCC could be of great assistance to the average developer and packager.

You (and most likely other folks at GCC) clearly understand the problem. Can you help us with a reasonable warning to 'save us from ourselves'? After all, a warning can be turned of or ignored. But if a warning does not exist, it does not help at all :/

Jeff
Comment 18 Jeffrey Walton 2010-10-21 17:37:15 UTC
(In reply to comment #13)
> Hi Jonathon,
> 
> (In reply to comment #10)
> > you realise you can wait and it will show up?
> > http://gcc.gnu.org/ml/gcc-help/2010-10/msg00248.html
> I've been known to be impatient at times :/
Slightly off topic, but spot on for my impatience. Before I submitted this request, I sent an email to the gcc-help list titled, "Audit Use of Global Variables in C++ Shared Object (GCC Warning?)"

Three days later and no search results from http://gcc.gnu.org/ml/gcc-help/. It begs the question, what interface/web page are you using to retrieve archived messages so quickly?

(To duplicate my results, paste the title into the search box and click search. Don't use quotes).
Comment 19 Jonathan Wakely 2010-10-21 18:41:20 UTC
Oh, I never use the search, it's always been useless

just click on the first month in the list, http://gcc.gnu.org/ml/gcc-help/2010-10/ shows the messages in date order, they appear almost immediately
Comment 20 Jonathan Wakely 2010-10-21 18:47:03 UTC
I'd forgotten the search was even there - I might suggest removing it, since it's apparently not indexed anything this month, and probably much longer
Comment 21 Jeffrey Walton 2010-10-21 18:49:49 UTC
(In reply to comment #19)
> Oh, I never use the search, it's always been useless
> 
> just click on the first month in the list,
> http://gcc.gnu.org/ml/gcc-help/2010-10/ shows the messages in date order, they
> appear almost immediately

:)
Comment 22 Andrew Pinski 2010-10-21 18:54:26 UTC
(In reply to comment #20)
> I'd forgotten the search was even there - I might suggest removing it, since
> it's apparently not indexed anything this month, and probably much longer

The search issue was just fixed.
Comment 23 Jeffrey Walton 2010-10-21 19:52:12 UTC
Hi Jonathan,

[Sorry about the top post].

I'm going to wrap up my request, and hope you and the GCC team will find that -Wglobal-variable would be useful under some circumstances.

When you and the team examine the merits of the request, remember that we [the dumb users] probably did not know about the finer details of the interactions between shared objects, global objects with destructors (is this c++ specific?), multiple processes, RTLD_GLOBAL, the ABI, and ODR. If we were aware, we probably would not have made the mistake in the first place.

====

The GCC team is probably tired of seeing questions about this issue. So a warning to reduce list chatter might be warranted.

====

Your points about when the warning should be issued are valid. But the warning would be incredibly useful when a "perfect storm" rises (interactions between shared objects, global objects with destructors, multiple processes, RTLD_GLOBAL, the ABI, and ODR.).

I feel history has shown that users and distribution packagers have gotten it wrong too often and too easily.

====

RTFM is great, but I can't help but feel, "what manual should I read" since searching for "shared object crash" and "SO crash" returned the phone book with no real useful information.

Once you pointed out the missing references and pieces, everything fell into place (and I will never make the mistakes again).

====

Wei Dai only provided a static archive of Crypto++. The library was being packaged as a shared object by distributions because of a rule somewhere that that required a system provided library.

The first sign of an issue for Crypto++ was a mailing list post titled, "Errors with multiple loading cryptopp as shared lib on Linux". So Crypto++ was actually collateral damage.

====

The next project to get pinged was Tahoe Least-Authoritative File System (Tahoe LAFS), which used Crypto++. Zooko Wilcox-O'Hearn, one of the project's leads, build bot alerted him of the issue. So Tahoe LAFS was also collateral damage.

===

Finally, crashes due to this issue degrade the user experience, so the user is the ultimate loser (and not just collateral damage).

Jeffrey Walton
Baltimore, MD, US

==============================

(In reply to comment #0)
> Feature reqeust only. Not a bug.
> 
> C++ shared objects are an interesting beast under certain circumstances (many
> times, the shared object acts like a generic C module). Interesting includes:
> * C++ module
> * Shared object
> * Shared object throws an exception which will cross module boundaries
> * Shared object opened with RTLD_GLOBAL
> * Shared object has global objects with destructors
> 
> Lots have been said about C++ exceptions, RTTI, type equality for the
> 'catch(const Exception&)', and RTLD_GLOBAL (versus RTLD_LOCAL) [1,2,3,4,5].
> 
> When a module meets the above compile and runtime requirements, a crash can
> occur in global objects with destructors when more than one process loads and
> subsequently unloads a shared object.
> 
> A switch to warn of global variables in a compilation unit would be very
> helpful for those who are aware of the issue (and the circumstances to
> encounter the issue). It appears that GCC does not supply such a switch [6].
> 
> The switch would be useful for module writers since its not always feasible to
> 'hand audit' all project files. And a warning would be exetremely useful for
> package maintainers who don't write the module - they simply fixup the code and
> package it for a distribution.
> 
> Perhaps -Wglobal-variable?
> 
> Jeffrey Walton
> Baltimore, MD, US
> 
> [1] Minimal GCC/Linux shared lib + EH bug example,
> http://gcc.gnu.org/ml/gcc/2002-05/msg00866.html
> [2] dlopen and placing exception body in .cpp file,
> http://gcc.gnu.org/ml/gcc-help/2010-08/msg00290.html
> [3] Comparing types across SOs (sic),
> http://groups.google.com/group/cryptopp-users/browse_thread/thread/eb815f228db50380
> [4] Errors with multiple loading cryptopp as shared lib on Linux,
> http://groups.google.com/group/cryptopp-users/browse_thread/thread/68fbc22e8c6e2f48
> [5] RTLD_GLOBAL and libcryptopp.so crash,
> http://groups.google.com/group/cryptopp-users/browse_thread/thread/7eae009a4e02e726
> [6] Audit Use of Global Variables in C++ Shared Object (GCC Warning?), GCC-Help
> mailing list, October, 2010 [not yet indexed].
Comment 24 Jeffrey Walton 2010-10-22 01:59:34 UTC
Hi Jonathan,

(In reply to comment #16)
> (In reply to comment #13)
> > 
> > [SNIP]
> 
> There are a number of options for making sure the global is private to the
> library, thus avoiding multiple definitions of the same object when two copies
> of the code are linked to.
>
> ...
> 
> * You can put it in an anonymous namespace.
Would namespaces be via dlmopen? (I've been trying to figure out how a c++ namespace could help, but I think I went down a rabbit hole).

http://linux.die.net/include/dlfcn.h:
/* Like `dlopen', but request object to be allocated in a new namespace. */
extern void *dlmopen (Lmid_t __nsid, __const char *__file, int __mode);

Jeff
Comment 25 Jeffrey Walton 2010-10-22 05:52:07 UTC
Created attachment 22112 [details]
Test for Load/Unload Crash

Attached is a test program similar to the program posted on http://gcc.gnu.org/ml/gcc-help/2010-10/msg00272.html.

This program was modified and ignores shared objects which were known to crash on a load/unload sequence so the audit could be completed. In total, over ***250*** libraries failed the simple load/unload test.

An alarming number of security libraries made the list. What if those security libraries were being used by SELinux and an attacker knew he could take out the subsystem because the development team or packager did not RTFM and observe ODR?

I deeply and sincerely believe that software authors and packagers need GCC's help on this. RTFM is not cutting it.

Jeffrey Walton

/usr/lib/debug/lib/libcrypto.so.0.9.8
/usr/lib/debug/lib/libssl.so.0.9.8
/usr/lib/debug/usr/lib/libcrypto++.so.8.0.0	
/usr/lib/debug/usr/lib/ssl/engines/lib4758cca.so
/usr/lib/debug/usr/lib/ssl/engines/libaep.so	
/usr/lib/debug/usr/lib/ssl/engines/libatalla.so
/usr/lib/debug/usr/lib/ssl/engines/libcapi.so
/usr/lib/debug/usr/lib/ssl/engines/libchil.so
Comment 26 Jonathan Wakely 2010-10-22 07:34:55 UTC
I don't think dlmopen has anything to do with C++ namespaces, but I could be wrong

Are those libraries that crash designed to be used via dlopen, rather than linking to them explicitly?
Comment 27 Jeffrey Walton 2010-10-22 07:37:55 UTC
(In reply to comment #26)
> [SNIP]
> Are those libraries that crash designed to be used via dlopen, rather than
> linking to them explicitly?
I'm not sure. How can one tell?
Comment 28 Jeffrey Walton 2010-10-22 19:49:26 UTC
(In reply to comment #26)
> I don't think dlmopen has anything to do with C++ namespaces, but I could be
> wrong
> 
> Are those libraries that crash designed to be used via dlopen, rather than
> linking to them explicitly?
Apparently they are (the authors would have marked the shared object with the  nodlopen option :/). And in the case of nodlopen, I simply get back NULL, which I can handle.
Comment 29 Jonathan Wakely 2010-10-22 20:36:45 UTC
(In reply to comment #28)
> > Are those libraries that crash designed to be used via dlopen, rather than
> > linking to them explicitly?
> Apparently they are (the authors would have marked the shared object with the 
> nodlopen option :/).

that would imply they RTFM ;)

I'm not sure I can contribute anything more useful to this PR. I think it would be awesome the compiler or linker could diagnose ODR violations, but I have no idea how to go about doing that.  Personally I don't think a warning about using global variables is the right solution unless it can be tuned to only warn about potentially dangerous cases.

I'm not going to close this PR as invalid though, if someone else can see how to make a useful warning then I'd be all for it
Comment 30 Ian Lance Taylor 2010-10-22 23:49:16 UTC
The gold linker has a --detect-odr-violations option, which is reasonably effective when used with C++ code which is compiled with -g and without any optimization.
Comment 31 Ian Lance Taylor 2010-10-22 23:55:44 UTC
As I understand this, this is a request for a warning for any definition of a global variable.  Is that correct?

Such a warning certainly can not be part of -Wall or -Wextra.  Global variables are part of the C/C++ language and it is not incorrect for code to use them.

While global variables are the more common source of problems here, you can also have problems due to multiple functions with the same name.  The proposed option will not help with that case.  For example, you will get multiple functions if you have two different C++ classes with the same name, and each defines a method with the same name (perhaps the constructor or destructor), and the method is declared as inline (perhaps because it was defined within the class definition), and the methods are called, and the calls are not inlined (perhaps because the code was compiled without optimization).

So I do not think that an option warning about global variables is a complete solution for the problem you are describing.  I also think that such a warning would be highly special purpose.

Unless we have a clear sign of demand for the proposed option, I would prefer to see it implemented as a plugin rather than as a general compiler option.
Comment 32 Phil Miller 2014-07-09 21:12:55 UTC
A switch to generate warnings about global variables would be useful to me and my colleagues (http://ppl.cs.illinois.edu/) for a reason totally distinct from ODR violations. We have a parallel programming system that includes a feature for running application code in multiple, nominally independent, user-level threads within a process. A mechanism to call attention to code that may fail or misbehave in this setting would be helpful.

I would definitely agree that this doesn't belong in -Wall or -Wextra, as such. So a -fnote-global-variables might be more appropriate.
Comment 33 Jonathan Wakely 2014-07-10 00:33:17 UTC
Write a plugin. It's trivial using gcc-python-plugin, see http://blog.cuviper.com/2014/01/23/add-new-warnings-to-gcc-with-python/

A custom plugin is far more suitable to your purpose than adding yet another option to GCC that has to be maintained and tested forever when most people aren't interested in it.