Skip to content
This repository has been archived by the owner on Jul 8, 2022. It is now read-only.

segmentation fault reading attribute (or accessing DevProxy in general) during application shutdown #540

Closed
delleceste opened this issue Mar 8, 2019 · 12 comments
Labels

Comments

@delleceste
Copy link

delleceste commented Mar 8, 2019

Hello.
This sample code represents a Qt class which is created at application startup and then destroyed when the application exists.

CuCustomWidgetCollectionInterface::CuCustomWidgetCollectionInterface(QObject *parent): QObject(parent)
{
    dev = new Tango::DeviceProxy("test/device/4");
    try {
        Tango::DeviceAttribute da;
        da = dev->read_attribute("double_spectrum_ro");
        std::vector<double> vd;
        da >> vd;
    }
    catch(Tango::DevFailed &e) {

    }
}

CuCustomWidgetCollectionInterface::~CuCustomWidgetCollectionInterface()
{
    printf("\e[1;31mo\e[0m ~CuCustomWidgetCollectionInterface %p\n", this);
    try {
        Tango::DeviceAttribute da;
        da = dev->read_attribute("double_spectrum_ro");  // SEGFAULT
        std::vector<double> vd;
        da >> vd;
    }
    catch(Tango::DevFailed &e) {
    }
}

This class is destroyed by Qt at the very end of the application life cycle. It is managed by Qt plugin system, so it is created and free by Qt.
In practise, I would like to accurately free Tango DeviceProxies when the Qt designer releases its resources at close time.

In normal Qt applications, when it's me who decides the proper point when to destroy Tango DeviceProxy references, I do not face the issue.

I guess there is a moment in an application life after which it becomes unsafe to access a DeviceProxy previously instantiated and used.

Can you confirm this?
What is this moment? (I remind from former releases something called the shutdown of the ORB)
Is it possible to fix it?

Thanks in advance.

Giacomo. ELETTRA

@bourtemb
Copy link
Member

bourtemb commented Mar 8, 2019

Hi @delleceste ,

Indeed, if you access DeviceProxy objects after the ORB has been shut down, you will be in trouble.
Do you call
Tango::ApiUtil::cleanup();
somewhere in your code?

Tango::ApiUtil::cleanup() will , among other things, shutdown the ORB.
You should not access DeviceProxy objects after this call.

@t-b
Copy link
Collaborator

t-b commented Mar 8, 2019

@delleceste Could you use code blocks for the code?

@bourtemb
But we could just throw in the DeviceProxy members if orb is a nullptr. It doesn't has to crash.

@delleceste
Copy link
Author

delleceste commented Mar 8, 2019 via email

@bourtemb
Copy link
Member

bourtemb commented Mar 8, 2019

Giacomo,

How is the Qt plugin system managing your classes?
It is loading and unloading dynamic libraries, it seems...

I got some questions recently from someone who was doing something similar on Windows and had trouble when unloading the library using Tango.

The solution was to call
Tango::ApiUtil::cleanup();
to shutdown the orb and release all the CORBA and ZMQ involved resources before unloading the library.

Shutting down the ORB before unloading a dynamic library using CORBA is actually what is recommended in omniORB documentation (section 2.8.6 ORB destruction, page 18), at least when dealing with Windows DLLs.

Could you please try that if that fits your use case?
Cheers,
Reynald

@bourtemb
Copy link
Member

bourtemb commented Mar 8, 2019

@bourtemb
But we could just throw in the DeviceProxy members if orb is a nullptr. It doesn't has to crash.

I made a simple test, trying to use an already created DeviceProxy after the ORB has been shut down.
We get a BAD_INV_ORDER CORBA system exception: BAD_INV_ORDER_ORBHasShutdown exception in this case, as in #449 so it does not crash, at least in this simple case.

@delleceste
Copy link
Author

delleceste commented Mar 8, 2019 via email

@delleceste
Copy link
Author

delleceste commented Mar 11, 2019 via email

@bourtemb
Copy link
Member

@delleceste
Thanks for the backtrace.
What version of cppTango are you using?

I tried to delete a DeviceProxy object after the ORB had been shutdown. No crash, no error.

Could it be that Qt is unloading the Tango library before your library?
Do you load several similar Tango plugins together?

@delleceste
Copy link
Author

delleceste commented Mar 12, 2019 via email

@bourtemb
Copy link
Member

I tried to delete a DeviceProxy object after the ORB had been shutdown. No crash, no error. Could it be that Qt is unloading the Tango library before your library?
That's quite likely. The workaround I described in one of my first emails deletes device proxy earlier in order to avoid the crash. But how would I know exactly when and how Qt unloads Tango library?

That's a very good question... I don't know how Qt deals with the libraries, especially when several plugins depending on a same library are loaded and unloaded.

Do you load several similar Tango plugins together?
Actually maybe the QTango alongside the cumbia one. I could try with one only if you think that makes a difference. Giacomo

I think it's worth a try.

@delleceste
Copy link
Author

delleceste commented Mar 12, 2019 via email

@bourtemb
Copy link
Member

Hi @delleceste ,
Did you try with only one Tango plugin?
Did it crash in that case?

@t-b t-b closed this as completed Feb 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants