Static thread_local std :: unique_ptr crash on program exit

I have a local single-threaded thread class that looks something like this:

//UserActionManager.hh

class UserActionManager
{
public:
    static UserActionManager* GetUserActionManager();

    ~UserActionManager() { std::cout << "UAM destructor called.\n"; }

    static thread_local std::unique_ptr<UserActionManager> theInstance;
};

//UserActionManager.cc

thread_local std::unique_ptr<UserActionManager> UserActionManager::theSafeInstance = nullptr;

UserActionManager*
UserActionManager::
GetUserActionManager()
{
    if (nullptr == theInstance)
    {
        theInstance.reset(new UserActionManager());
        std::cout << "theInstance = " << theInstance.get() << "\n";
    }

    return theInstance.get();
}

I need to use dynamic allocation for the instance because the UserActionManager must be created after the other steps have been completed in my program.

When I run the program, it works fine until the program exits. I get an error message:

simple(57724,0x10b647000) malloc: *** error for object 0x7fc64ce79460: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
simple(57724,0x10d64d000) malloc: *** error for object 0x7fc64ce7b140: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
simple(57724,0x10c64a000) malloc: *** error for object 0x7fc64ce7b8e0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

 *** Break *** illegal instruction

 *** Break *** illegal instruction

 *** Break *** illegal instruction

If I run the program in lldb, I get this message that tells me that the crash occurs by default to delete my thread_local UserActionManager instance.

// lldb output

Process 57201 stopped
* thread #2: tid = 0x8d5d1, 0x0000000105a2eed7 libGex.dylib`std::default_delete<gex::ua::UserActionManager>::operator()(gex::ua::UserActionManager*) const + 27, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x0000000105a2eed7 libGex.dylib`std::default_delete<gex::ua::UserActionManager>::operator()(gex::ua::UserActionManager*) const + 27
libGex.dylib`std::default_delete<gex::ua::UserActionManager>::operator()(gex::ua::UserActionManager*) const + 27:
-> 0x105a2eed7:  movq   (%rax), %rax
   0x105a2eeda:  addq   $0x48, %rax
   0x105a2eede:  movq   (%rax), %rax
   0x105a2eee1:  movq   -0x10(%rbp), %rdx

However, if you look at pointers printed by code for local instances of the stream, and pointers that are freed without allocation, they do not match:

//, GetUserActionManager():

0x7fc650948300
0x7fc64a4de670
0x7fc650b33480
0x7fc650c19f90

//, :

0x7fc64ce79460
0x7fc64ce7b140
0x7fc64ce7b8e0

? . g++ 4.9.1 MacOSX ++ 14 . UserActionManager , , , , , . grepped , theInstance , , , . , "".

? !

EDIT:

:

?

UserActionManager , "simple" . ( ) . ? "

+4

All Articles