当用新创建QT Qapplication时,分割故障



我有一个程序,其中qapplication与新操作员创建。由于未知原因,它崩溃了。我使用Redhat Linux,G 4.8.2,QT 4.7.2,它是使用相同编译器构建的。

此来源包含许多看起来无用但无害的作品,例如" 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文档和互联网中找到提示 - 没有运气。谢谢

QApplicationargcargv具有特殊的(和IMHO可疑)要求。请参阅文档:

警告: ARGC和ARGV所指的数据必须在Qapplication对象的整个生命周期中保持有效。此外,ARGC必须大于零,并且ARGV必须至少包含一个有效的字符串。

如果argcargv在运行时被破坏,则会发生不确定的行为。它可能在某些平台上工作,而其他平台可能会崩溃。相应地更改您的代码,并检查它是否解决了您的问题。

我遇到了相同的问题,并实现了以下类以坚持命令行参数:

.h:

#pragma once
#include <string>
#include <vector>
using std::string;
using std::vector;
class PersistentArgs
{
protected:
    vector<string> mArgStrs;
public:
    int mArgc;
    vector<char*> mArgv;
    PersistentArgs() = delete;
    PersistentArgs(int argc, char* argv[]);
    virtual ~PersistentArgs();
};

.cpp:

#include "PersistentArgs.h"
PersistentArgs::PersistentArgs(int argc, char* argv[])
{
    mArgc = argc;
    for (int i = 0;  i < argc;  i++)
    {
        string arg(argv[i]);
        mArgStrs.push_back (arg);
    }
    for (int i = 0;  i < argc;  i++)
    {
        mArgv.push_back ((char*)mArgStrs[i].c_str());
    }
    mArgv.push_back (nullptr);
}
PersistentArgs::~PersistentArgs()
{
    mArgv.clear();
    mArgStrs.clear();
}

用法:


PersistentArgs* args;

void atStart (int argc, char* argv[])
{
    args = new PersistentArgs (argc, argv);
    QApplication* qtApp = new QApplication (args->mArgc, &args->mArgv[0]);
}

相关内容

  • 没有找到相关文章

最新更新