0

The application in question was written using Qt 5.7 and in VS2015. A strange problem cropped up last week and I am desperately trying to sort this out. We have enough logging I thought but does not look like it. Then again this problem was seen only on a couple of the user's machine.

We have made sure the deployment works well on all the Windows machines and the application did work well until last week on those machines. Now it refuses to open but however shows up in the taskbar.

The user's machine has the pre-requisites installed, which is VC++ 2015. All the necessary Qt DLLs are also present. The application works without any hiccups on every other machine. So I assume the problem is with the machine, however, a restart of the 2 OS (Windows 7 and Windows 2012), clean re-installation of the application, different versions all fails and shows the same issues.

My question now would be

  1. Is there a way to log all the dependencies just when the application starts (Used dependency walker several times but wanted to do something similar to our logs).
  2. How to diagnose this to find out if a watchdog application or antivirus is causing this? Trying to convince users to switch off the antivirus for diagnosing the issue.

I used the windeployqt to get all the dependencies and while testing figured out the rest of the DLL necessary, like the VC++ 2015. Also while building used dependecy walker. Few questions asked like qt application does not start and qt application launch issues all point to missing DLL. I know this is not the case because the application works fine on almost all the windows machine. So I need help and direction to logging the dependencies and also how to diagnose this kind of situations.

I might have missed some information if so lease let me know. I am researching more and I will update the post as I get some additional information.

Also trying to add a lot of logging within the main() function. To see if I can catch something.

int main(int argc, char *argv[])
{
    // Setup signal handlers
#if(defined(USE_SIGNAL_HANDLERS) && !defined(_DEBUG))
    SignalHandlerPointer previousHandler1 = signal (SIGINT, SignalHandler);
    SignalHandlerPointer previousHandler2 = signal (SIGILL, SignalHandler);
    SignalHandlerPointer previousHandler3 = signal (SIGFPE, SignalHandler);
    SignalHandlerPointer previousHandler4 = signal (SIGSEGV, SignalHandler);
    SignalHandlerPointer previousHandler5 = signal (SIGTERM, SignalHandler);
#ifdef Q_OS_WIN32
    SignalHandlerPointer previousHandler6 = signal (SIGBREAK, SignalHandler);
#endif
    SignalHandlerPointer previousHandler7 = signal (SIGABRT, SignalHandler);
#ifdef Q_OS_WIN32
    SignalHandlerPointer previousHandler8 = signal (SIGABRT_COMPAT, SignalHandler);
#endif
#endif      //USE_SIGNAL_HANDLERS

#if QT_VERSION >= 0x050000
    //QT5 fix
#else
    QApplication::setGraphicsSystem("raster");
#endif
#ifdef Q_OS_WIN
    // MAC_OS: Windows only function
    CoInitialize(NULL);
#endif
    QApplication::setAttribute(Qt::AA_UseOpenGLES);
    MyApplicationApplication a(argc, argv);

    // We put the dumps in the appdata:
    QString ard_path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
    QDir dir(ard_path);
    if (!dir.exists())
        dir.mkpath(ard_path);
#ifdef DEBUG
    //Setting crash dump path
    QBreakpadInstance.setDumpPath(ard_path);
#endif // DEBUG

    QtWebEngine::initialize();


    MyApplication *vtf = 0;

    bool allowFiles = true;
    bool isLicensed = false;
    QString errMsg = QString();
    QErrorMessage *error = new QErrorMessage();
    error->resize(300, 300);

    START_EASYLOGGINGPP(argc, argv);

    el::Loggers::setDefaultConfigurations(baseConfiguration(), true);

    QApplication::setWindowIcon(QIcon(":/Resources/images/VTF-iconx4.png"));
    QCoreApplication::setOrganizationName(VER_COMPANYNAME_STR);
    QCoreApplication::setApplicationName(VER_PRODUCTNAME_STR);
    QCoreApplication::setApplicationVersion(VER_PRODUCTVERSION_STR);


    //part of ERGT-1038
    QFont appFont = QApplication::font();
    //Default is 8
    appFont.setPointSize(10);
    QApplication::setFont(appFont);

    QTime time = QTime::currentTime();
    qsrand((uint)time.msec());

#ifdef ENABLE_MULTILANGUAGE
    // Load a language using string from the settings applied by the dialog
    InstallTranslation("qt_", a);
    InstallTranslation("MyApplication_", a);
    InstallTranslation("qtbase_", a);

#endif

    bool bTrial = false;
    MyApplicationLicenseInfo *info = new MyApplicationLicenseInfo();
    info->Initialize(LIC_FIRMCODE_AGD, LIC_PRODCODE_AGD, NUMBER_OF_ACTIVATION_SCHEMES, szActivationSchemes);

    if ((info->UsagePeriod() > 0) || info->Error())
    {
        bTrial = false;
        allowFiles = true;      // Trial version
    }

    // Check if it has expired!!
#if(!defined(_DEBUG) && !defined(DISABLE_LOCAL_LICENCE_USAGE_CHECK))
    if (info->UsagePeriod() > 0)
    {
        // Work out the end date
        QDateTime dt = QDateTime::fromString(info->StartDate(), "yyyy/MM/dd hh:mm:ss");
        dt = dt.addDays(info->UsagePeriod());
        if (dt < QDateTime::currentDateTime())
        {
            QMessageBox::critical(NULL, VER_PRODUCTNAME_STR, QObject::tr("Your license has expired! Please contact sales."));
            return -1;
        }
    }
#endif

    CommandLineProcessor cmdProc;
    isLicensed = true;
    bool batchMode = false;

    Globals     *glob = NULL;
    int iExec = 0;
    try 
    {

        if(a.arguments().length() > 1)
        {
            if (a.arguments().at(1) == "-batch") {
                batchMode = true;
            } else {
                cmdProc.setLicenseInfo(info);
                if (!cmdProc.ProcessParameters(a.arguments()))
                {
                    // Quit - error!
                    QMessageBox::critical(NULL, VER_PRODUCTNAME_STR, QObject::tr("Error in command line: ") + cmdProc.ErrorMessage() + "\r\n\r\nExiting.", QMessageBox::Ok);
                    return -1;
                }
                else if (!cmdProc.ErrorMessage().isEmpty() && !cmdProc.failedToAuthenticate())
                {
                    QMessageBox::warning(NULL, VER_PRODUCTNAME_STR, QObject::tr("Warning in command line: ") + cmdProc.ErrorMessage(), QMessageBox::Ok);
                }

                // Pass everything back to local variables
                if (cmdProc.HashGiven())    // Note: '=' here is deliberate!!
                {
                    isLicensed = cmdProc.IsLicensed();
                    //bTrial = cmdProc.Trial();
                }
                else
                {
                    isLicensed = true;  // Let WIBU be handled below
                }
            }
        }

        // End of parameter handling

        QString whyItFailed = "";
        bool hasError = info->Error();
        bool wibuPres = info->WibuPresent();
        bool isViewer = info->IsViewer();
        if (isLicensed && !(info->Error() && info->WibuPresent()))
        {
            whyItFailed += "Empty license container";
        }
        if (!wibuPres)
        {
            whyItFailed += "Missing Wibu";
        }
        if(isLicensed && !(info->Error() && info->WibuPresent()))
        {
            QDir::setCurrent(QCoreApplication::applicationDirPath());
            Q_INIT_RESOURCE(MyApplication);
            glob = Globals::createInstance(info, allowFiles, bTrial, cmdProc.HashGiven(), isViewer);


            if (cmdProc.ActionsFile().isEmpty() && !batchMode)
            {
                // Load in GUI mode as normal
                vtf = new MyApplication(glob, NULL);
#ifdef Q_OS_MAC
                QObject::connect(&a,SIGNAL(openFile(const QString &)),vtf,SLOT(openFile(const QString &)));
#endif

                if (cmdProc.Service() != 0)
                    glob->setService(cmdProc.Service());
                else if (cmdProc.failedToAuthenticate())
                {
                    LogInDialog lid(LogInDialog::MyLogin, glob, NULL, NULL, cmdProc.ServiceUrl(), cmdProc.ServiceUser());
                    if (lid.exec() == QDialog::Accepted)
                    {
                        glob->Service()->setCurrentProj(cmdProc.ProjectId());
                        glob->Service()->setCurrentVers(cmdProc.VersionId());
                        glob->Service()->setFirstFlowLevel(cmdProc.LevelId());
                        glob->Service()->setFirstFlowName(cmdProc.FlowName());
                    }
                }

                // ctx->Initialize() fired off inside VisualTestFlow constructor to avoid looped references
                vtf->setWindowState(Qt::WindowMaximized);
                vtf->show();

                // MyApplication window needs to be created first so that the error messages show
                if(!cmdProc.LoadFile().isEmpty())
                {
                    vtf->open(QScopedPointer<FlowLocation>(new FlowLocation(cmdProc.LoadFile())).data());
                }

                if (glob->Service() != NULL)
                {
                    vtf->tryOpenFirstFlow();
                }
                QTimer::singleShot(0, vtf, SLOT(windowInitialized()));


                a.setStyleSheet(glob->Style()->globalStyle());
            }
            else
            {
                glob->SetCommandLine(true);

                if (!batchMode) {
                    // Execute as actions
                    ActionsFileExecutor *exec = new ActionsFileExecutor(cmdProc.ActionsFile(), cmdProc.LogFile(), glob);
                    // Check errors
                    if (!exec->error().isEmpty())
                    {
                        // Logs already gone - let's get out of here!
                        iExec = -1000;
                    }
                    else
                    {
                        // Execute
                        iExec = exec->Execute();
                    }
                    delete exec;
                    exec = NULL;
                } else {
#ifdef Q_OS_WIN
#ifdef USE_CONSOLE
                    AllocConsole();
                    FILE *pFileCon = NULL;
                    pFileCon = freopen("CONOUT$", "w", stdout);

                    COORD coordInfo;
                    coordInfo.X = 130;
                    coordInfo.Y = 9000;

                    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coordInfo);
                    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS);
#endif
#endif
                    BatchScriptCommandProcessor cmdPro(glob);
                    cmdPro.ParseArguments(a.arguments());
                }
            }
        } else {
            LOG(ERROR) << whyItFailed;
            error->setWindowTitle(QObject::tr("Error"));
            if(glob != NULL && glob->Service() != NULL)
            {
                if(glob->Service()->error())
                    error->showMessage(QObject::tr("My service fault:") + "<br/><br/>" + glob->Service()->lastError());
                else
                    error->showMessage(QObject::tr("My service reported that the specified user is not licensed to use %1").arg(VER_PRODUCTNAME_STR));
            }
            else
            {
                //error->showMessage(QObject::tr("This user/machine is not licensed to use %1").arg(VER_PRODUCTNAME_STR));
            }
        }
        if (glob == NULL || !glob->IsCommandLine())
        {
            iExec = a.exec();
        }
    }
    catch (std::runtime_error &ex)
    {
        // Note: this is where we should put in the "Send error report" function        
        // Check if the user wants to save
        if (true) //cmdProc.ActionsFile().isEmpty())
        {
            QString sMessage = QObject::tr("%1 has encountered a fatal error: %2").arg(QString(VER_PRODUCTNAME_STR)).arg(QString(ex.what()));
            QString sTitle = QObject::tr("Runtime Exception");
            LOG(ERROR) << QString(VER_PRODUCTVERSION_STR) << sMessage;

            // GTID-2764: Work out if we can save to file or repository
            int iIndex = 0;
            QList<CrashSaveOptions> listOptions;
            if (glob != NULL)
            {
                if (glob->GetAllowFiles())
                {
                    listOptions.append(CrashSaveOptions(QObject::tr("To File"), iIndex, false, CrashSaveOptions::Yes));
                    iIndex++;
                }
                if (glob->Service() != NULL && glob->Service()->sessionID() > 0)
                {
                    listOptions.append(CrashSaveOptions(QObject::tr("To Repository"), iIndex, true, CrashSaveOptions::Yes));
                }
            }

            if(glob != NULL && glob->ContextList() != NULL && !glob->ContextList()->isEmpty())
            {
                foreach(GlobalContext *ctx, *glob->ContextList())
                    ctx->unlockFlow();

                sMessage += "\r\n\r\n" + QObject::tr("Would you like to attempt to save ");
                foreach(GlobalContext *ctx, *glob->ContextList())
                {
                    if(ctx == NULL || ctx->GetProperties() == NULL || ctx->Scene() == NULL || !ctx->Scene()->changesMade())
                        continue;

                    try
                    {
                        CrashSaveOptions cr = saveOnCrash(sTitle, sMessage + "\"" + ctx->GetProperties()->title() + "\"", listOptions, vtf);
                        if (cr.dosave == CrashSaveOptions::Yes)
                        {
                            if (cr.rep)
                            {
                                ctx->saveRep();
                                ctx->unlockFlow();
                            }
                            else
                            {
                                ctx->saveFile();
                            }
                        }
                        else if(cr.dosave == CrashSaveOptions::NoToAll)
                        {
                            break;
                        }
                    }
                    catch (std::runtime_error &ex)
                    {
                        continue;
                    }
                }
            }
            else
            {
                QMessageBox::critical(NULL, sTitle, sMessage, QMessageBox::Ok);
            }
        }
        else
        {
            // ActionsFileExecutor has its own try...catch for logging

        }
    }

    if(vtf != NULL)
        delete vtf;
    if (glob != NULL)
    {
        Globals::deleteInstance();
        glob = NULL;
    }

    //_CrtDumpMemoryLeaks();
    return iExec;
}
Community
  • 1
  • 1
Vivian Lobo
  • 583
  • 10
  • 29
  • did you perhaps forget to call the `show()` method of your widget? You should probably post some code otherwise this question is OT – bibi Dec 12 '16 at 10:47
  • Sorry, I did not think source was necessary as the application works fine in all the other cases and users with the same OS too. Just these 2 machines which cause the problem. I have updated the question with source. – Vivian Lobo Dec 12 '16 at 11:03

0 Answers0