Search code examples
c++qtactivex

Invoking QCoreApplication::arguments() crashes using an ActiveX server


We are building a library that contains a few QObjects and QWidgets. The idea is to provide COM objects using ActiveX (QAxContainer) so they can be embedded and used in conjunction with other languages (in this case, managed C#).

Some of the objects that we are using will integrate with Qt Quick and to do this we are using QQuickWidget. During the QQuickWidget construction it will invoke QCoreApplication::arguments() which leads to an access violation reading: Exception thrown at 0x00007ffc43f12fc0 (ucrtbased.dll) in WinClient.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff

Exporting the following class to an ActiveX widget will lead to the crash:

#include <QWidget>
#include <ActiveQt/QAxBindable>

class TestAxWidget: public QWidget, public QAxBindable
{
  Q_OBJECT

  Q_CLASSINFO("ClassID",        "{377794ac-85f2-4e2c-be17-f2852d85fa61}")
  Q_CLASSINFO("InterfaceID",    "{8b3a6ef3-9d17-47f7-99a8-cd96d0d922dd}")
  Q_CLASSINFO("EventsID",       "{12e9000e-017e-454e-a641-73c9p8349d77}")
  Q_CLASSINFO("CoClassAlias",   "TestAxWidget")
  Q_CLASSINFO("RegisterObject", "yes")

  public:
    explicit TestAxWidget(QWidget * parent = Q_NULLPTR) 
      : QWidget(parent)
    {
      QCoreApplication::arguments();
    }
      Q_DISABLE_COPY(TestAxWidget)
};

And stack trace:

ucrtbased.dll!strlen()  + 0x10 bytes    
Qt5Cored.dll!QString::fromLocal8Bit(const char * str, int size)  Line 539 + 0x19 bytes  C++
Qt5Cored.dll!QCoreApplication::arguments()  Line 2313 + 0x1e bytes  C++

Any suggestions on how to solve this?


Update

After some further debugging using the Qt sources I've found that the argc given to the QCoreApplication() is initialized to 0 (zero).

When QCoreApplication::arguments() is invoked the value of argc has changed to some random high value != 0, which will obviously lead to an exception.

I've used a Data Breakpoint in VS2015 to identify when the value of argc is changed and it seems to periodically be changed by clr.dll. How can I prevent this? am I doing something fundamentally wrong?

Currently using Qt 5.6.2 on Windows 10 x64 VS2015


Solution

  • Apparently there is a bug when the QApplication is instansiated in QAxServerBase.cpp, by function CreateInstanceHelper:

    ...
    if (!qApp) {
      qax_ownQApp = true;
      int argc = 0;
      new QApplication(argc, 0);
    }
    ...
    

    The application crashes since the passed in argument argc is created on the stack and doesn't outlive the QApplication-instance.

    There is a bug-fix for this in version 5.9.0: https://bugreports.qt.io/browse/QTBUG-59047