Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global ctor ordering causes crashes #49

Closed
mdavidsaver opened this issue Dec 28, 2017 · 5 comments
Closed

Global ctor ordering causes crashes #49

mdavidsaver opened this issue Dec 28, 2017 · 5 comments
Assignees
Milestone

Comments

@mdavidsaver
Copy link
Member

@MarkRivers reports

I rebuilt the windows-x64-static architecture with HOST_OPT=NO so I could get a stack trace in the example application.  Here it is:

>          test.exe!epicsMutex::lock()  Line 273 + 0x5 bytes     C++
           test.exe!epics::pvData::Lock::Lock(epicsMutex & m={...})  Line 45 + 0x46 bytes  C++
           test.exe!epics::pvData::FieldCreate::getFieldCreate()  Line 1459 + 0x12 bytes        C++
           test.exe!epics::pvData::getFieldCreate()  Line 1230  C++
           test.exe!epics::pvData::PVDataCreate::PVDataCreate()  Line 358 + 0x23 bytes     C++
           test.exe!epics::pvData::PVDataCreate::getPVDataCreate()  Line 617 + 0x21 bytes            C++
           test.exe!epics::pvData::getPVDataCreate()  Line 1656          C++
           test.exe!epics::pvAccess::`dynamic initializer for 'pvDataCreate''()  Line 58 + 0x1a bytes   C++
           test.exe!_initterm(void (void)* * pfbegin=0x000000013f6ada00, void (void)* * fend=0x000000013f6adf48)  Line 873        C
           test.exe!_cinit(int initFloatingPrecision=1)  Line 301            C
           test.exe!__tmainCRTStartup()  Line 262 + 0xa bytes            C
           test.exe!mainCRTStartup()  Line 189 C
           kernel32.dll!00000000775259cd()    
            [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]         
           ntdll.dll!000000007775a561()            ''

In epicsMutex::lock this=0. 

That is called from this code in lock.h
    explicit Lock(Mutex &m)
    : mutexPtr(m), locked(true)
    { mutexPtr.lock();}

In that code the debugger tells me that "m id=???", Error CXX0030 Expression cannot be evaluated.

This is Visual Studio 2010.
@mdavidsaver
Copy link
Member Author

43ee4b9 doesn't address the larger issue, but does make getFieldCreate() and getPVDataCreate() safe to be called at any time. This should at least fix this particular crash.

@mdavidsaver
Copy link
Member Author

@MarkRivers confirms that he no longer sees this crash.

@mdavidsaver
Copy link
Member Author

I made an attempt at to quantify the issue with a script examples/find_global_ctors.py in https://github.com/mdavidsaver/pyelftools which attempts to analyze G++ 6.3 produced object files to find code run from global constructors/destructors.

This finds that w/ libpvData.so at least, the problem is not as bad as I had feared. The global ctors are mostly calls to getFieldCreate() and getPVDataCreate(), which are now safe, lots of global std::string instances use in error/exception messages, and a few other such global "constants". The strings are insidious as they aren't used unless something goes wrong. So inadvertent use before main() might work normally, but blow up if something goes wrong and an exception needs to be constructed.

The offenders are: createRequest.cpp, FieldCreateFactory.cpp, pvAlarm.cpp, pvControl.cpp, pvDisplay.cpp, pvEnumerated.cpp, pvTimeStamp.cpp, and PVUnion.cpp.

It will be worthwhile to go through these simply to cleanup amateur stuff like:

static string emptyStringtring;

return emptyStringtring;

@mdavidsaver
Copy link
Member Author

See also epics-base/pvAccessCPP#80

@mdavidsaver
Copy link
Member Author

Released with Base 7.0.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant