查找损坏的共享库错误的原因(Qt5 C++)
Finding cause of corrupted shared library error (Qt5 C++)
我有一段相当简单的代码可以启动 QProcess:
launchResultCode = ELaunchOk;
QDateTime beginTimeStamp = QDateTime::currentDateTime();
command->start(commandpath, myParameters);
if (command->waitForStarted(waitToStart)) {
if (!myStdIn.isEmpty()) command->write(myStdIn.toLatin1());
command->closeWriteChannel();
qDebug() << "P1";
if (command->waitForFinished(waitToFinish)) {
myStdOut = command->readAllStandardOutput();
myStdErr = command->readAllStandardError();
} else {
launchResultCode = ELaunchFinishFailed;
}
} else {
launchResultCode = ELaunchStartFailed;
}
qDebug() << "postcorrupt";
它导致共享库损坏错误。当我 运行 这段代码时,我从下面的 gdb 得到输出。我试图找出错误中提到的任一内存位置的内容,但那里没有变量!有人可以帮助我了解这里出了什么问题吗?
(gdb) c
Continuing.
precorrupt
Detaching after fork from child process 21667.
P1
warning: Corrupted shared library list: 0x7fffe8008970 != 0x7ffff691b000
postcorrupt
[New Thread 0x7fffed453700 (LWP 21668)]
Breakpoint 1, RunProcessWorker::run (this=0x7fffffffcc30, whichMutex=RunProcessWorker::EMutexIP, activityID=..., commandFriendlyName=..., commandpath=...,
enableDebug=true, showDebugCommandLine=true, debugFilenameTemplate=..., myEnvironment=..., myParameters=..., myStdIn=..., myStdOut=..., myStdErr=...,
waitToStart=5000, waitToFinish=5000, actualRunTime=@0x7fffffffca58: 85, launchResultCode=@0x7fffffffca54: RunProcessWorker::ELaunchOk,
qprocessErrorCode=@0x7fffffffca50: QProcess::UnknownError, qprocessesExitCode=@0x7fffffffca6c: 0)
at ../../src/external-sharedfiles/systemcommands/runprocessworker.cpp:292
292 command->deleteLater();
(gdb) info symbol 0x7fffe8008970
No symbol matches 0x7fffe8008970.
(gdb) info symbol 0x7ffff691b000
No symbol matches 0x7ffff691b000.
(gdb)
请注意,错误有时会出现在我的 P1 输出之前,所以它是那个区域的东西,但我无法弄清楚是什么!派生的进程是一个 Qt 库,所以我看不到那个库(并且可能无法理解它)...这是否意味着它是 Qt 库中的一个错误?
可能相关,但 valgrind 显示内存在 QProcess 启动函数上丢失:
30 (24 direct, 6 indirect) bytes in 1 blocks are definitely lost in loss record 837 of 2,936
in RunProcessWorker::run(RunProcessWorker::EMutex, QString, QString, QString, bool, bool, QString, QStringList, QStringList, QString, QString&, QString&, unsigned int, unsigned int, unsigned long long&, RunProcessWorker::ELaunchResultCodes&, QProcess::ProcessError&, int&) in /mnt/lserver2/data/development/sharedfiles/systemcommands/runprocessworker.cpp:241
1: operator new[](unsigned long) in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so
2: /opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1
3: /opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1
4: QProcess::start(QString const&, QStringList const&, QFlags<QIODevice::OpenModeFlag>) in /opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1
请注意,您的错误消息不是 "corrupted shared library",而是 "corrupted shared library list"。也就是说,进程内存中的共享库列表 space 是损坏的,而不是共享库本身。所以我怀疑不是你有一个损坏的共享库,而是某些东西正在覆盖你程序内存中的内存 space 并导致恰好损坏该列表的损坏。
同样有趣的是,您的调试器将此指定为崩溃位置:
292 command->deleteLater();
如您所知,deleteLater() 是一种 Qt 方法,用于导致稍后删除 QObject(即在 Qt 事件循环的下一次迭代中)。程序在这里崩溃的最可能原因是调用该方法的(命令)指针无效(NULL 或悬空)。在这种情况下, (command) 是与您在发布的示例代码中调用的对象相同的 QProcess 对象吗?如果是这样,您是否可能已经在某处删除了该 QProcess 对象,从而使上面的崩溃代码带有悬空指针? (如果你不确定,你可以子类化 QProcess 并在你的子类的析构函数中放置一个 qDebug() 语句,这样你就可以在你的 stdout/stderr 输出中看到 QProcess 对象被销毁的位置和时间......和如果调试打印发生在崩溃之前,那么这是崩溃发生原因的一个很好的线索。
另一个可能的问题是,如果您 运行 上面的代码 "stand-alone",没有 QApplication(或 QThread)对象在同一个线程中执行 exec()。由于 deleteLater() 向 Qt 事件循环发送消息,如果不存在 Qt 事件循环并在同一线程中执行,它将无法正常工作。
我有一段相当简单的代码可以启动 QProcess:
launchResultCode = ELaunchOk;
QDateTime beginTimeStamp = QDateTime::currentDateTime();
command->start(commandpath, myParameters);
if (command->waitForStarted(waitToStart)) {
if (!myStdIn.isEmpty()) command->write(myStdIn.toLatin1());
command->closeWriteChannel();
qDebug() << "P1";
if (command->waitForFinished(waitToFinish)) {
myStdOut = command->readAllStandardOutput();
myStdErr = command->readAllStandardError();
} else {
launchResultCode = ELaunchFinishFailed;
}
} else {
launchResultCode = ELaunchStartFailed;
}
qDebug() << "postcorrupt";
它导致共享库损坏错误。当我 运行 这段代码时,我从下面的 gdb 得到输出。我试图找出错误中提到的任一内存位置的内容,但那里没有变量!有人可以帮助我了解这里出了什么问题吗?
(gdb) c
Continuing.
precorrupt
Detaching after fork from child process 21667.
P1
warning: Corrupted shared library list: 0x7fffe8008970 != 0x7ffff691b000
postcorrupt
[New Thread 0x7fffed453700 (LWP 21668)]
Breakpoint 1, RunProcessWorker::run (this=0x7fffffffcc30, whichMutex=RunProcessWorker::EMutexIP, activityID=..., commandFriendlyName=..., commandpath=...,
enableDebug=true, showDebugCommandLine=true, debugFilenameTemplate=..., myEnvironment=..., myParameters=..., myStdIn=..., myStdOut=..., myStdErr=...,
waitToStart=5000, waitToFinish=5000, actualRunTime=@0x7fffffffca58: 85, launchResultCode=@0x7fffffffca54: RunProcessWorker::ELaunchOk,
qprocessErrorCode=@0x7fffffffca50: QProcess::UnknownError, qprocessesExitCode=@0x7fffffffca6c: 0)
at ../../src/external-sharedfiles/systemcommands/runprocessworker.cpp:292
292 command->deleteLater();
(gdb) info symbol 0x7fffe8008970
No symbol matches 0x7fffe8008970.
(gdb) info symbol 0x7ffff691b000
No symbol matches 0x7ffff691b000.
(gdb)
请注意,错误有时会出现在我的 P1 输出之前,所以它是那个区域的东西,但我无法弄清楚是什么!派生的进程是一个 Qt 库,所以我看不到那个库(并且可能无法理解它)...这是否意味着它是 Qt 库中的一个错误?
可能相关,但 valgrind 显示内存在 QProcess 启动函数上丢失:
30 (24 direct, 6 indirect) bytes in 1 blocks are definitely lost in loss record 837 of 2,936
in RunProcessWorker::run(RunProcessWorker::EMutex, QString, QString, QString, bool, bool, QString, QStringList, QStringList, QString, QString&, QString&, unsigned int, unsigned int, unsigned long long&, RunProcessWorker::ELaunchResultCodes&, QProcess::ProcessError&, int&) in /mnt/lserver2/data/development/sharedfiles/systemcommands/runprocessworker.cpp:241
1: operator new[](unsigned long) in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so
2: /opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1
3: /opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1
4: QProcess::start(QString const&, QStringList const&, QFlags<QIODevice::OpenModeFlag>) in /opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1
请注意,您的错误消息不是 "corrupted shared library",而是 "corrupted shared library list"。也就是说,进程内存中的共享库列表 space 是损坏的,而不是共享库本身。所以我怀疑不是你有一个损坏的共享库,而是某些东西正在覆盖你程序内存中的内存 space 并导致恰好损坏该列表的损坏。
同样有趣的是,您的调试器将此指定为崩溃位置:
292 command->deleteLater();
如您所知,deleteLater() 是一种 Qt 方法,用于导致稍后删除 QObject(即在 Qt 事件循环的下一次迭代中)。程序在这里崩溃的最可能原因是调用该方法的(命令)指针无效(NULL 或悬空)。在这种情况下, (command) 是与您在发布的示例代码中调用的对象相同的 QProcess 对象吗?如果是这样,您是否可能已经在某处删除了该 QProcess 对象,从而使上面的崩溃代码带有悬空指针? (如果你不确定,你可以子类化 QProcess 并在你的子类的析构函数中放置一个 qDebug() 语句,这样你就可以在你的 stdout/stderr 输出中看到 QProcess 对象被销毁的位置和时间......和如果调试打印发生在崩溃之前,那么这是崩溃发生原因的一个很好的线索。
另一个可能的问题是,如果您 运行 上面的代码 "stand-alone",没有 QApplication(或 QThread)对象在同一个线程中执行 exec()。由于 deleteLater() 向 Qt 事件循环发送消息,如果不存在 Qt 事件循环并在同一线程中执行,它将无法正常工作。