Static variable (Class) in the static function is getting re-initialized when called from another/shared Lib

Hi,
Facing the typical issue on the AIX compiler/linker/server.  Please check the code below.


//  say in module 1 I have class (libmod1.so)
======================================================================================
     in file  MyErrorHandlerSmptr.h
=======================================================================================       
class MyErrorHandlerSmptr
{

public:

    MyErrorHandlerSmptr (baseErrorHandler *p)
	{
		MyErrorHandler::instance().setErrorHandler(p);
	}

    ~MyErrorHandlerSmptr()
	{
	    MyErrorHandler::instance().setErrorHandler(NULL);      
	}

};

Open in new window

======================================================================================
======================================================================================
     in file  MyErrorHandler.h
=======================================================================================       
   
   
typedef enum
    {
        SUCCESS,      /**< Success */
        WARNINGS,     /**< Warning */
        ERRORS        /**< Error   */
    } MyErrorStatus;
	
class  MyErrorHandler
{
    friend class MyErrorHandlerSmptr;
	// 

private:
    MyErrorHandler()
	: errorHandler(NULL), errorStatus(SUCCESS), last_fail_value(0)
	{   
		printf("\n 11 :: default constructor ");	
		printf("\n address of the class is   --- > %p ", this );	
	}

    MyErrorHandler(const MyErrorHandler &)
	{
	 // code like constructor 
	}


    void setErrorHandler(BaseErrorHandler* handler)
	{
		printf("\n 33 : Set error handler");	
		printf("\n address of the class is   --- > %p ",(void *) this );

		errorHandler = handler;
		errorStatus = SUCCESS;
		last_fail_value = 100;

	}

    BaseErrorHandler* errorHandler;
    MyErrorStatus errorStatus;
    int last_fail_value;

public:
    static MyErrorHandler& instance()
    {
		printf("\n ## : in singleton instance");	
        static MyErrorHandler inst;
        return inst;
    }


    bool hasErrorHandler() const
    {
		printf("\n 44 : check error handler");	
		printf("\n address of the class is   --- > %p ",(void *) this );
        return errorHandler ? true:false;
    }
	
	~MyErrorHandler();
};

Open in new window


now When from Module 1. I initialize MyErrorHandlerSmptr(..) properly and MyErrorHandler class
works properly.

Now from another module say from module 2, When i check for error handler, like this.
bool ok_handler = MyErrorHandler::instance().hasErrorHandler();

Open in new window


Some how AIX calls the default constructor again from singleton instance function and saying no error handler is set.

Is there any solution, how to fix this?

Thanks in advance.
Ganesh NAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sarabandeCommented:
friend class MyErrorHandlerSmptr;

Open in new window


with the code you posted only friend class could/would be able to call the default constructor.

i don't know why the MyErrorHandler is using class baseErrorHandler. if once instance() function is called the static instance of MyErrorHandler would be instantiated, but could not used before the baseErrorHandler was set. surely this is not a good design.

Sara
0
Ganesh NAuthor Commented:
Hi sarabande,
   It is a part of code from my product. I just tried to demo it.

Problem is specific to AIX compiler/linker.

friend class is used only to make sure that no one else could set the error handler. and Not calling default constructor.
So in start I have set the error handler. i.e also initialized the class.  ( Please see friend class declaration)

My main concern is that ,  When I add below line to another module,.

bool ok_handler = MyErrorHandler::instance().hasErrorHandler();

Open in new window


control calls instance function, But instead of returning me already initialized reference. It is re-initializing the
inst
and returning me reference at other location.
From same .so (DLL) file it is working as expected.

On all other OS Windows/Linux/Solaris this is working fine. Strange thing is happening only in AIX OS.  I have asked what are the compiler option(s) they have used for AIX, from my release team. They are still finding.
0
sarabandeCommented:
bool ok_handler = MyErrorHandler::instance().hasErrorHandler();

if this uses private constructor twice, the calls were made in different modules (for example in the main executable and second in a shared object files with extension .so).

are you using fork processes?

Sara
0
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

sarabandeCommented:
you could solve the issue by moving the class into a separate .so and import the class in other modules.

Sara
0
Ganesh NAuthor Commented:
Hi Sara,
yes, Private constructor is used twice.
and
NO we are not using fork process.

The process is sequential, even not multithrading at that level.

  however   below line is in catch block of try/catch section and this try/catch block is in different module. Is that forking?

bool ok_handler = MyErrorHandler::instance().hasErrorHandler(); 

Open in new window


Ganesh
0
Ganesh NAuthor Commented:
>> you could solve the issue by moving the class into a separate .so and import the class in other modules.

 No can not do that.
Is there nay better way than this? if I move I need to modify many other files. which are using this class.
0
sarabandeCommented:
Is there nay better way than this?

perhaps. since the the error handling is done by baseErrorHandler, you would need to make sure that all instances of your MyErrorHandler were using the same pointer. then in the error handling functions of baseErrorHandler you need to use a mutex if shared resources (for example the error log file) were used. thus all critical paths would run exclusively.

actually a shared error handler class most likely is the simpler way. you even could think of a daemon which does the error handling and gets ist requests by using tcp sockets.

Sara
0
Ganesh NAuthor Commented:
Hi Experts,
The issues is sorted by updating the name of static function from
 static MyErrorHandler& instance() 

Open in new window

to any other name, like
 static MyErrorHandler& my_singleton().

Open in new window



It is very strange but this is the solution.

Can anyone find the reason for it?
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Ganesh NAuthor Commented:
sara,
You believe it or not. Changing the name of function sorts my issue in AIX. Same code was working fine in Winows/Linux/Solaris.  we ship the product for these 4 OS. and the problem was reported by a customer to us.
I have also checked with AIX compiler option, we use xlC option .

complete code is in real time complex production env.  
Since the changing the function name would force immanence recompile in our case, we need to write a wrapper to get away and changing only at the places needed.

Thanks,
Ganesh
0
sarabandeCommented:
Why did you object to delete the question? I can't help with closing the question as already stated.

If you can't give more information and can't do further investigation as requested by me, you should close the question by accepting your own comment with 0 points.

Sara
0
Ganesh NAuthor Commented:
Tried it in production env of my company.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.