加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux – 使用new创建Qt QApplication时的分段错误

发布时间:2020-12-14 02:09:50 所属栏目:Linux 来源:网络整理
导读:我有一个程序,其中使用new运算符创建QApplication.它因未知原因而崩溃.我使用RedHat Linux,G 4.8.2,Qt 4.7.2,它是用相同的编译器构建的. 这个源包含许多看似无用但无害的部分,例如带有四个未使用参数的’func’函数.如果我试图删除它们并进一步简化程序,则崩
我有一个程序,其中使用new运算符创建QApplication.它因未知原因而崩溃.我使用RedHat Linux,G 4.8.2,Qt 4.7.2,它是用相同的编译器构建的.

这个源包含许多看似无用但无害的部分,例如带有四个未使用参数的’func’函数.如果我试图删除它们并进一步简化程序,则崩溃不再可以再现,这当然并不意味着问题已经解决.

崩溃发生在函数strlen中,该函数从系统函数XSetCommand调用.添加我自己的简单实现允许我看到strlen收到一个损坏的指针,见下文.

#include <QApplication>
#include <QMessageBox>

void func(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());
    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) () 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&,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文档和互联网中找到提示 – 没有运气.
谢谢

解决方法

QApplication对argc和argv有一个特殊的(和IMHO可疑的)要求.见 documentation:

Warning: The data referred to by argc and argv must stay valid for the entire lifetime of the QApplication object. In addition,argc must be greater than zero and argv must contain at least one valid character string.

如果argc和argv在运行时被销毁,则会发生未定义的行为.它可能在某些平台上运行,并且会在其他平台上崩溃.相应地更改您的代码并检查它是否修复了您的问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读