linux - विभाजन की गलती जब Qt QApplication को नए के साथ बनाया गया था



segmentation-fault new-operator (1)

QApplication में argc और argv लिए एक विशेष (और argc संदिग्ध) आवश्यकता है दस्तावेज़ीकरण देखें:

चेतावनी: argc और argv द्वारा निर्दिष्ट डेटा QApplication ऑब्जेक्ट के पूरे जीवनकाल के लिए मान्य रहना चाहिए। इसके अलावा, argc शून्य से बड़ा होना चाहिए और argv में कम से कम एक वैध वर्ण स्ट्रिंग होना चाहिए।

यदि argc और argv रनटाइम के दौरान नष्ट हो जाते हैं, तो अनिर्धारित व्यवहार होता है। यह कुछ प्लेटफार्मों पर काम कर सकता है और यह दूसरों पर क्रैश हो जाएगा अपने कोड को तदनुसार बदलें और जांच लें कि क्या यह आपकी समस्या को ठीक करता है

मेरे पास एक प्रोग्राम है जहां QApplication नए ऑपरेटर के साथ बनाया गया है। यह अज्ञात कारणों के लिए दुर्घटनाग्रस्त है। मैं रेडहाट लिनक्स, जी ++ 4.8.2, क्यूटी 4.7.2 का उपयोग करता हूं जो कि एक ही कंपाइलर के साथ बनाया गया था।

इस स्रोत में कई बेकार हैं, लेकिन हानिरहित टुकड़े हैं, जैसे चार अप्रयुक्त तर्कों के साथ 'फ़ंक्शन' फ़ंक्शन। अगर मैं उन्हें हटाने की कोशिश करता हूं और कार्यक्रम को थोड़ी सी आसान कर देता हूं तो दुर्घटना अब और नहीं हो सकती है, बेशक इसका मतलब यह नहीं है कि समस्या का हल हो गया है।

दुर्घटना फ़ंक्शन strlen में होती है, जिसे सिस्टम फ़ंक्शन XSetCommand से कहा जाता है। अपना अपना सरल क्रियान्वयन जोड़ने से मुझे यह देखने की अनुमति मिली कि उस स्ट्रेल को एक भ्रष्ट सूचक मिला है, नीचे देखें।

#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 में होता है और इसी कारण मैंने इसके लिए अपना खुद का कार्यान्वयन भी शामिल किया। इसका तर्क पी अंक कहीं नहीं है। मैंने इसे क्यूटी के डिबग बिल्ड के साथ पुन: उत्पन्न करने की कोशिश की - कोई भाग्य नहीं। यह सब मुझे लगता है कि यहां एक गंदा स्मृति भ्रष्टाचार है। लेकिन यह कहां हो सकता है? मैं यहाँ केवल निर्दोष बातें करता हूं।

मैं इसे बनाने के लिए सीमके का उपयोग करता हूं:

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})

मैंने क्यूटी प्रलेखन और इंटरनेट में संकेत खोजने की कोशिश की - कोई भाग्य नहीं। धन्यवाद





qapplication