linux qt segmentation-fault new-operator qapplication

linux - Falla de segmentación cuando Qt QApplication creado con nuevo



segmentation-fault new-operator (1)

Tengo un programa donde QApplication se crea con el nuevo operador. Se bloquea por un motivo desconocido. Uso RedHat Linux, G ++ 4.8.2, Qt 4.7.2 que fue construido con el mismo compilador.

Esta fuente contiene muchas piezas inútiles pero inofensivas, por ejemplo, la función ''func'' con cuatro argumentos no utilizados. Si trato de eliminarlos y simplificar un poco más el programa, ya no se puede reproducir el bloqueo, lo que, por supuesto, no significa que el problema haya sido resuelto.

El bloqueo ocurre en la función strlen, que se llama desde la función del sistema XSetCommand. Agregar mi propia implementación simple me permitió ver que strlen recibe un puntero corrupto, ver debajo.

#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(); }

Crash backtrace:

#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

Como ves, sucede en strlen. Y es por eso que incluí mi propia implementación para eso. Su argumento p apunta a ninguna parte. Traté de reproducirlo con la versión de depuración de Qt, sin suerte. Todo esto me hace pensar que hay una corrupción de memoria desagradable aquí. Pero, ¿dónde podría pasar? Aquí solo hago cosas inocentes.

Yo uso CMake para construirlo:

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

Traté de encontrar pistas en la documentación de Qt e Internet, sin suerte. Gracias


QApplication tiene un requisito especial (e IMHO cuestionable) para argc y argv . Ver la documentación :

Advertencia: los datos referidos por argc y argv deben permanecer válidos durante toda la vigencia del objeto QApplication. Además, argc debe ser mayor que cero y argv debe contener al menos una cadena de caracteres válida.

Si argc y argv se destruyen durante el tiempo de ejecución, se produce un comportamiento indefinido. Puede funcionar en algunas plataformas y se bloqueará en otras. Cambie su código en consecuencia y verifique si soluciona su problema.