查看完整版本: [-- arm下程序调用外部程序更新后再加载程序失败 --]

QTCN开发网 -> Qt嵌入式开发 -> arm下程序调用外部程序更新后再加载程序失败 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

pamire 2016-05-17 17:04

arm下程序调用外部程序更新后再加载程序失败

开发环境:
ubuntu15 x64 + qte 4.8.6 + arm
Linux EmbedSky 3.0.35 #46 SMP PREEMPT Tue Mar 29 17:26:50 CST 2016 armv7l GNU/Linux(天嵌开发板)
1. 现象:
主程序A调用外部程序B,并且A退出, B解压 更新程序后再次加载A,则加载A失败。
原因不明,也写不了日志。
2.现象:
若直接运行B, B解压 更新程序后加载A,则加载A成功,写不了日志(笔误)
3.现象:
在xp下测试反复循环加载正常,能写日志。

B程序主要代码:

QString g_currentPath;
int DoUnzip(QString sUpdatePackName, QString sUnzipPackPath)
{

    qDebug() << sUpdatePackName << sUnzipPackPath;
    int ret_value = doUncompress(sUpdatePackName.toLocal8Bit(), sUnzipPackPath.toLocal8Bit());

    return ret_value;
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QFile *fp = NULL;
    do
    {        
        //_asm{ int 3 };
        g_currentPath = QDir::currentPath();
        //QString sLogFile = QString("%1/update.log").arg(g_currentPath);
        QString sLogFile = QString("%1/update.log").arg("/mnt/nfs/bin");
        fp = new QFile(sLogFile);
        if (fp == NULL){
            qDebug() << "ImLog fopen error";
            break;
        }
        if (!fp->open(QIODevice::ReadWrite|QIODevice::Append | QIODevice::Text)){
            qDebug() << "ImLog fopen error";
            break;
        }
        int nFileLen = fp->write("UpdateQt xxx ");

        if (argc != 2){
            qDebug() << "input param: xxx.zip!";
            break;
        }

        nFileLen = fp->write(g_currentPath.toLocal8Bit());
        nFileLen = fp->write("\n\r");

        QString sSrc = QString::fromLocal8Bit(argv[1]);
        QString sTmpPath = QString("%1/tmp").arg(g_currentPath);
        QFile sourceDir(sSrc);
        if(!sourceDir.exists()){    /**< 如果目标目录不存在,则进行创建 */
            qDebug() << sSrc << "not exists!";
            nFileLen = fp->write(argv[1]);
            nFileLen = fp->write("not exists!\n\r");
            break;;
        }

        {
            QDir dir(sTmpPath);
            if (!dir.exists(sTmpPath)){
                if (!dir.mkpath(sTmpPath)){
                    qDebug() << "mkpath false";
                    nFileLen = fp->write("mkpath false\n\r");
                    break;
                }
            }

            if (DoUnzip(sSrc, sTmpPath)!=0){
                qDebug() << "Unzip File False";
                nFileLen = fp->write("Unzip File False\n\r");
                break;
            }

            bool bOk = copyDirectoryFiles(sTmpPath, g_currentPath, true);
            if (!bOk){
                qDebug() << "copyDirectoryFiles false!";
                nFileLen = fp->write("copyDirectoryFiles False\n\r");
                break;
            }
        }
        // delete tmp path;
        if (!removeDirectory(sTmpPath)){
            qDebug() << "delDirectoryFiles false!";
            nFileLen = fp->write("delDirectoryFiles False\n\r");
            //break;
        }
        QStringList arguments;
#ifdef _WIN32        
        QString program = QString("%1/E1800.exe").arg(g_currentPath);
        arguments << "";
#else
        QString program = QString("%1/E1800").arg(g_currentPath);
        arguments << "-qws" <<"-font" << "unifont";
#endif
        qDebug() << program;
        nFileLen = fp->write(program.toLocal8Bit());
        nFileLen = fp->write("\n\r");

        QDir::setCurrent(g_currentPath);
        QProcess *myProcess = new QProcess(0);
        myProcess->start(program, arguments);
        //QTest::qSleep(1000*10);
    } while (0);

    if (fp){
        fp->write("UpdateQt End\n\r");
        fp->close();
    }
    return 0;
    //return a.exec();
}
A调用程序代码:

int ImClient::DoUnzip()
{
#ifdef _WIN32        
    QString program = QString("%1/UpdateQt.exe").arg(g_env.filePathInfo.strAppPath);
#else
    QString program = QString("%1/UpdateQt").arg(g_env.filePathInfo.strAppPath);
#endif
    QStringList arguments;
    arguments << m_sUpdatePackName;

    QDir::setCurrent(g_env.filePathInfo.strAppPath);
    LOGFILE("load updateQt.exe");
    LOGSTR((g_env.filePathInfo.strAppPath.toLocal8Bit()));
    QProcess *myProcess = new QProcess(0);
    myProcess->start(program, arguments);

    POST_MESSAGE( new ImEvent(QVariant(0), (QEvent::Type)WM_APP_QUIT));
    return 0;
}


uidab 2016-05-18 09:13
什么叫做 " 能写不了日志"  ????

你用的是start启动的,在linux和xp这种情况是有不同的。


pamire 2016-05-18 10:22
经过反复测试,问题跟踪到
(此拷贝程序反复测试,也找了类似的,基本思路都一样,感觉不应该是程序的事,可能与QProgress调用有关)
//拷贝文件夹:

//拷贝文件夹:
bool copyDirectoryFiles(const QString &fromDir, const QString &toDir, bool coverFileIfExist)
{
    QDir sourceDir(fromDir);
    QDir targetDir(toDir);
    if(!targetDir.exists()){    /**< 如果目标目录不存在,则进行创建 */
        if(!targetDir.mkdir(targetDir.absolutePath()))
            return false;
    }
    QFileInfoList fileInfoList = sourceDir.entryInfoList();
    foreach(QFileInfo fileInfo, fileInfoList){
        if(fileInfo.fileName() == "." || fileInfo.fileName() == "..")
            continue;

        /**< 当为目录时,递归的进行copy */
        if(fileInfo.isDir())
        {    
            if(!copyDirectoryFiles(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()), coverFileIfExist))
                return false;
        }
        else /**< 当允许覆盖操作时,将旧文件进行删除操作 */
        {            
            if(coverFileIfExist && targetDir.exists(fileInfo.fileName())){
                targetDir.remove(fileInfo.fileName());  
            }

            /// 进行文件copy
            if(!QFile::copy(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()))){
                return false;
            }
        }
    }
    return true;
}

只要调用:
targetDir.remove(fileInfo.fileName());  或
if(!QFile::copy(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()))){
程序都会异常退出,还看不到异常信息,若不用QProcess 调用,直接运行没有问题。
测试在if(coverFileIfExist && targetDir.exists(fileInfo.fileName())){ 前加写文件语句
fp->write("abc\n\r");
return true;
加上这么一句,程序也会异常退出,感觉在Arm下不太稳定.

pamire 2016-05-18 11:36
解法方法:
1. 用exec,execl, execv等
#include <uniSTd.h>
  int execl(cONst char *path, const char *arg, ...);
  int execlp(const char *file, const char *arg, ...);
  int execle(const char *path, const char *arg, ..., char *const envp[]);
  int execv(const char *path, char *const argv[]);
  int execvp(const char *file, char *const argv[]);
  int execve(const char *path, char *const argv[], char *const envp[]);

"/mnt/nfs/bin/UpdateQt  /mnt/nfs/bin/update.zip"
QLock::lock(): Invalid argument
QLock::unlock(): Unlock without corresponding lock
QLock::lock(): Invalid argument
QLock::unlock(): Unlock without corresponding lock
QLock::lock(): Invalid argument
QLock::unlock(): Unlock without corresponding lock
用execl出现上面调用失败信息

2.改进调用QProgress
int IClient::DoUnzip()
{
#ifdef _WIN32
    QString progra = QString("%1/UpdateQt.exe").arg(g_env.filePathInfo.strAppPath);
#else
    QString progra = QString("%1/UpdateQt").arg(g_env.filePathInfo.strAppPath);
#endif
    QStringList arguents;
    arguents << _sUpdatePackNae;

    QDir::setCurrent(g_env.filePathInfo.strAppPath);
    QProcess *myProcess = new QProcess(0);
    myProcess->setWorkingDirectory(g_env.filePathInfo.strAppPath);
    myProcess->start(progra, arguents);

    while (! myProcess->waitForFinished(300)) {
        if (myProcess->state() == QProcess::NotRunning) { //process failed
            printf("NotRunning\n");
            return -1;
        }
        qApp->processEvents();
    }

    if (myProcess->exitCode() != 0) { //error when run process
        printf("exitCode\n");
        return false;
    }

    POST_ESSAGE( new IEvent(QVariant(0), (QEvent::Type)W_APP_QUIT));

    return 0;
}
B程序不用改动,改进QProgress,则可正常调用B程序.





查看完整版本: [-- arm下程序调用外部程序更新后再加载程序失败 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled