我有一个程序,其中使用new运算符创建了QApplication。它因未知原因崩溃。我使用的是RedHat Linux、G++ 4.8.2和Qt 4.7.2,它们都是用相同的编译器构建的。
这个源代码包含许多看起来无用但无害的部分,例如具有四个未使用参数的“func”函数。如果我尝试删除它们并进一步简化程序,就无法再复现崩溃了,当然这并不意味着问题已经解决。
崩溃发生在strlen函数中,该函数从系统函数XSetCommand调用。添加自己的简单实现使我可以看到strlen接收到了一个损坏的指针,如下所示。
我在Qt文档和互联网上寻找线索,但没有找到。谢谢。
这个源代码包含许多看起来无用但无害的部分,例如具有四个未使用参数的“func”函数。如果我尝试删除它们并进一步简化程序,就无法再复现崩溃了,当然这并不意味着问题已经解决。
崩溃发生在strlen函数中,该函数从系统函数XSetCommand调用。添加自己的简单实现使我可以看到strlen接收到了一个损坏的指针,如下所示。
#include <QApplication>
#include <QMessageBox>
void func(void *, void *, void *, void *) {}
struct Gui
{
QApplication qApplication;
Gui(int argc, char ** argv) : qApplication(argc, argv) {}
};
struct Process
{
Process(const std::string &, int argc, char ** argv) {
func(ptr(), ptr(), ptr(), ptr());
std::string recent;
std::string path = std::string("Hi!");
recent = std::string("Hi!");
m_message = std::string("Hi!");
m_gui = new Gui(argc, argv);
}
~Process() { delete m_gui; }
int exec(void) {
return QMessageBox::warning(0, "Exit", "Sure?", QMessageBox::Ok);
}
void * ptr(void) { return 0; }
Gui * m_gui;
std::string m_message;
};
std::size_t strlen(const char * p) {
std::size_t s = 0;
while (*p++)
s++;
return s;
}
int main(int argc, char ** argv) {
Process process("SomeString", argc, argv);
return process.exec();
}
崩溃回溯:
#0 0x0000000000400f13 in strlen (p=0x11 <Address 0x11 out of bounds>) at /home/alex/test/megaCrash/myprog.cpp:39
#1 0x0000003880a41922 in XSetCommand () from /usr/lib64/libX11.so.6
#2 0x0000003880a45fa6 in XSetWMProperties () from /usr/lib64/libX11.so.6
#3 0x00002aaaaad2e5ea in QWidgetPrivate::create_sys(unsigned long, bool, bool) () from /usr/local/Trolltech/Qt-4.7.2/lib/libQtGui.so.4
#4 0x00002aaaaace735d in QWidget::create(unsigned long, bool, bool) () from /usr/local/Trolltech/Qt-4.7.2/lib/libQtGui.so.4
#5 0x00002aaaaacef73a in QWidget::setVisible(bool) () from /usr/local/Trolltech/Qt-4.7.2/lib/libQtGui.so.4
#6 0x00002aaaab11de5e in QDialog::setVisible(bool) () from /usr/local/Trolltech/Qt-4.7.2/lib/libQtGui.so.4
#7 0x00002aaaab11d9e6 in QDialog::exec() () from /usr/local/Trolltech/Qt-4.7.2/lib/libQtGui.so.4
#8 0x00002aaaab13bb40 in ?? () from /usr/local/Trolltech/Qt-4.7.2/lib/libQtGui.so.4
#9 0x00002aaaab13bc7f in QMessageBox::warning(QWidget*, QString const&, QString const&, QFlags<QMessageBox::StandardButton>, QMessageBox::StandardButton) () from /usr/local/Trolltech/Qt-4.7.2/lib/libQtGui.so.4
#10 0x0000000000401514 in Process::exec (this=0x7fffffffe4e0) at /home/alex/test/megaCrash/myprog.cpp:27
#11 0x0000000000400fb6 in main (argc=1, argv=0x7fffffffe5f8) at /home/alex/test/megaCrash/myprog.cpp:47
正如您所见,这发生在strlen中。这就是为什么我包含了自己的实现方式。它的参数p指向无处。我尝试使用Qt的调试版本进行复制,但没有成功。所有这些让我想到存在着恶意内存损坏。但是它可能发生在哪里呢?我只是在这里做了一些无辜的事情。
我使用CMake来构建它:
cmake_minimum_required (VERSION 2.8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused-local-typedefs -fpic -fvisibility=hidden -m64")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb -DDEBUG -gdwarf-2 -fstack-protector-all")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
find_package(Qt4 REQUIRED)
include(${QT_USE_FILE})
add_executable(myprog myprog.cpp)
target_link_libraries(myprog ${QT_LIBRARIES})
我在Qt文档和互联网上寻找线索,但没有找到。谢谢。
strlen
的代码吗?为什么你在strlen
中不检查p != 0
? - Dmitry Sazonov