Segmentation fault with GtkGlExtmm



Hello everybody out there!

	As it is the first time I am posting here, let me introduce myself.

	My name is Yoann Le Bars, and I am French, so please do forgive me for
the improper English. I am a C++ developer since something like 15
years. My main field of development is numerical modelling. I also
develop pre- and post-processing tools to deal with data used in the
models. I am also teaching C++ in engineer courses.

	So one can tell I am experimented in programming. But I usually make
command line programs and some visualisation with OpenGL. So far, I have
never developed graphical user interface. Recently, I decided to self
train into this kind of programming, which can be quite handy. After
comparing Qt and Gtkmm and a long debate with myself, I have chosen to
use Gtkmm. Important criterion for me are portability, independence to
the working platform, and compliance with standards.

	I have used official Gtkmm tutorial
(<http://developer.gnome.org/gtkmm-tutorial/3.4/>), which is well done.
Now, I try and make some OpenGL rendering with GtkGlExtmm. I am adapting
Nehe tutorials (<http://nehe.gamedev.net/>) into GtkGlExtmm. As
GtkGlExtmm is not yet available in Gtkmm 3, I have switched to Gtkmm 2.
I can wait, I understand transition from a major version to another take
some time.

	But still, I have some trouble when trying and create an OpenGL capable
widget. At the end of this message (for sake of lisibility), I give a
complete minimal example which leads to a segmentation fault when trying
and start an OpenGL rendering (line
“glWindow->gl_begin(get_gl_context());”). I also give you Valgring
output. I use CMake for the building process (“CMakeLists.txt” file also
given) and every source files are in a sub-directory call “src/.”

	I guess I have done some stupid mistake, but I cannot find it. So, if
anyone can give me some help, this would be nice.

	Regards.

							Yoann


CMakeLists.txt:

cmake_minimum_required(VERSION 2.6)

project(Tutoriel1 CXX)
set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})
set(EXECUTABLE_NAME tutoriel1)

find_package(
	Boost
	1.31.1
)

find_package(PkgConfig)

pkg_check_modules(Glibmm glibmm-2.4>=2.4.0)
pkg_check_modules(GTKmm gtkmm-2.4>=2.4.0)
pkg_check_modules(GLExtmm gtkglextmm-1.2>=1.2.0)
link_directories(
        ${Boost_LIBRARY_DIRS}
        ${Glibmm_LIBRARY_DIRS}
        ${GTKmm_LIBRARY_DIRS}
        ${GLExtmm_LIBRARY_DIRS}
)
include_directories(
        ${Boost_INCLUDE_DIRS}
        ${Glibmm_INCLUDE_DIRS}
        ${GTKmm_INCLUDE_DIRS}
        ${GLExtmm_INCLUDE_DIRS}
)

file(
	GLOB_RECURSE
	source_files
	src/*
)

add_executable(
	${EXECUTABLE_NAME}
	${source_files}
)

target_link_libraries(
	${EXECUTABLE_NAME}
	${Boost_LIBRARIES}
	${Glibmm_LIBRARIES}
	${GTKmm_LIBRARIES}
	${GLExtmm_LIBRARIES}
)


src/window.hpp:

#ifndef WINDOW_HPP
#define WINDOW_HPP

#include <gtkmm/window.h>
#include <gtkmm/drawingarea.h>
#include <gtkglmm.h>

namespace Interface {
  /* OpenGL widget. */
  class GlDrawingArea: public Gtk::DrawingArea,
                       public Gtk::GL::Widget<GlDrawingArea> {
    public:
      GlDrawingArea ();
      virtual ~GlDrawingArea ();

    protected:
      /* -- Handlers: */

      /* When exposing the widget. */
      virtual bool on_expose_event (GdkEventExpose* event);
  };

/* -------------------------------------------------------------- */

  /* Class for main window. */
  class Window: public Gtk::Window {
    public:
      Window ();
      virtual ~Window();

    private:
      /* -- Child widgets: */

      /* OpenGL widget. */
      GlDrawingArea glArea;
  };
}

#endif  // #ifndef WINDOW_HPP


src/window.cpp:

#include <glibmm/error.h>
#include <cstdlib>

#include "window.hpp"

/* -- GlDrawingArea default constructor. --------------------------- */
Interface::GlDrawingArea::GlDrawingArea (): Gtk::DrawingArea () {
  /* OpenGL configuration. */
  Glib::RefPtr<Gdk::GL::Config> configuration;

  /* Trying to create a double buffered rendering. */
  configuration = Gdk::GL::Config::create(Gdk::GL::MODE_RGB    |
                                          Gdk::GL::MODE_DEPTH  |
                                          Gdk::GL::MODE_DOUBLE);
  if (!configuration) {
    g_warning("Double buffering not possible,trying single buffering.\n");
    /* Trying to create single buffered rendering. */
    configuration = Gdk::GL::Config::create(Gdk::GL::MODE_RGB   |
                                            Gdk::GL::MODE_DEPTH);
    if (!configuration) {
      g_critical("Impossible to create OpenGL context.\n");
      std::exit(-2);
    }

    /* Give OpenGL capability to the widget. */
    set_gl_capability(configuration);
  }
}

/* -- GlDrawingArea destructor. --------------------------------------- */
Interface::GlDrawingArea::~GlDrawingArea () {
}

/* -- When GlDrawingArea is exposed. ------------------------- */
bool Interface::GlDrawingArea::on_expose_event (GdkEventExpose* event) {
  /* OpenGL window. */
  Glib::RefPtr<Gdk::GL::Window> glWindow = get_gl_window();

  glWindow->gl_begin(get_gl_context());
  glClear(GL_COLOR_BUFFER_BIT);

  /* Main OpenGL rendering. */

  glWindow->gl_end();
  glWindow->swap_buffers ();

  return true;
}

/* -- Window default constructor. ------------------------------ */
Interface::Window::Window (): Gtk::Window () {
  set_name("Tutorial 1");
  set_border_width(2);

  add(glArea);

  show_all_children();
}

/* -- Windows destructor. ------------------------------------------ */

Interface::Window::~Window () {
}


src/main.cpp:

/*
 * First tutorial: creating a window with an OpenGL area.
 */

#include <iostream>
#include <boost/test/included/prg_exec_monitor.hpp>
#include <gtkmm/main.h>
#include <gtkglmm.h>
#include <sstream>

#include "window.hpp"

/*
 * Program main function.
 * Inputs:
 *   argc  Number of arguments.
 *   argv  Values of arguments.
 * Return:
 *   0 if everything went well.
 *   -1 in case of a GLib error.
 */
int cpp_main (int argc, char** argv) {
  try {
    /* Program kit. */
    const Gtk::Main kit(argc, argv);
    Gtk::GL::init(argc, argv);

    /* Main window */
    Interface::Window window;

    kit.run(window);

    return 0;
  }
  catch(const Glib::Error& ex) {
    /* Message d’erreur. */
    std::ostringstream message;
    message << "GLib error: " <<  ex.what() << '\n';
    g_warning(message.str().c_str());
    return -1;
  }
}


Valgrind result:

$ valgrind ./build/bin/Debug/tutoriel1 --leak-check=full --track-origins=yes
==7850== Memcheck, a memory error detector
==7850== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==7850== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==7850== Command: ./build/bin/Debug/tutoriel1 --leak-check=full
--track-origins=yes
==7850==
==7850== Syscall param ioctl(generic) points to uninitialised byte(s)
==7850==    at 0xB0E4AC7: ioctl (syscall-template.S:82)
==7850==    by 0x4060B44: ukiCreateContext (in
/usr/lib/x86_64-linux-gnu/libatiuki.so.1.0)
==7850==    by 0x127957D5: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==    by 0x131FAD5F: ???
==7850==    by 0x131F9E17: ???
==7850==    by 0x131F9F1F: ???
==7850==    by 0x127CE17F: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==  Address 0x7feff5598 is on thread 1's stack
==7850==
==7850== Conditional jump or move depends on uninitialised value(s)
==7850==    at 0x127DC0F4: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==    by 0x127DB853: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==    by 0x127DBACC: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==    by 0x127CC967: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==
==7850== Invalid write of size 8
==7850==    at 0x4C2A7ED: memcpy (mc_replace_strmem.c:838)
==7850==    by 0x11E5CB62: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==  Address 0x7fd84bf27ff8 is not stack'd, malloc'd or (recently)
free'd
==7850==
==7850== Invalid write of size 8
==7850==    at 0x4C2A7ED: memcpy (mc_replace_strmem.c:838)
==7850==    by 0x11E5CB77: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==  Address 0x7fd84bf27ff8 is not stack'd, malloc'd or (recently)
free'd
==7850==
==7850== Conditional jump or move depends on uninitialised value(s)
==7850==    at 0x127D121F: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==    by 0x6804130000000F: ???
==7850==    by 0x2DEACFFFF: ???
==7850==    by 0x3A0000000F: ???
==7850==    by 0xCF: ???
==7850==    by 0x1101: ???
==7850==    by 0x3802167F: ??? (mc_malloc_wrappers.c:364)
==7850==    by 0x131FC7CF: ???
==7850==
==7850== Conditional jump or move depends on uninitialised value(s)
==7850==    at 0x127D1224: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==    by 0x6804130000000F: ???
==7850==    by 0x2DEACFFFF: ???
==7850==    by 0x3A0000000F: ???
==7850==    by 0xCF: ???
==7850==    by 0x1101: ???
==7850==    by 0x3802167F: ??? (mc_malloc_wrappers.c:364)
==7850==    by 0x131FC7CF: ???
==7850==
==7850== Conditional jump or move depends on uninitialised value(s)
==7850==    at 0x127D1228: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==    by 0x6804130000000F: ???
==7850==    by 0x2DEACFFFF: ???
==7850==    by 0x3A0000000F: ???
==7850==    by 0xCF: ???
==7850==    by 0x1101: ???
==7850==    by 0x3802167F: ??? (mc_malloc_wrappers.c:364)
==7850==    by 0x131FC7CF: ???
==7850==
==7850== Invalid write of size 1
==7850==    at 0x4C2A7C8: memcpy (mc_replace_strmem.c:838)
==7850==    by 0x127D23F5: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==  Address 0x7fd84ba68583 is not stack'd, malloc'd or (recently)
free'd
==7850==
==7850== Invalid write of size 8
==7850==    at 0x4C2A7ED: memcpy (mc_replace_strmem.c:838)
==7850==    by 0x127D23F5: ??? (in
/usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
==7850==  Address 0x7fd84ba68578 is not stack'd, malloc'd or (recently)
free'd
==7850==
==7850== Invalid read of size 8
==7850==    at 0x8B973BA:
Gdk::GL::Drawable::gl_begin(Glib::RefPtr<Gdk::GL::Context> const&) (in
/usr/lib/libgdkglextmm-x11-1.2.so.0.0.0)
==7850==    by 0x41B97F:
Interface::GlDrawingArea::on_expose_event(_GdkEventExpose*) (fenetre.cpp:53)
==7850==    by 0x5B37BB2:
Gtk::Widget_Class::expose_event_callback(_GtkWidget*, _GdkEventExpose*)
(in /usr/lib/libgtkmm-2.4.so.1.1.0)
==7850==    by 0x69BF098: ??? (in
/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.10)
==7850==    by 0x50AF6DF: g_closure_invoke (in
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3200.4)
==7850==    by 0x50C04CF: ??? (in
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3200.4)
==7850==    by 0x50C82DA: g_signal_emit_valist (in
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3200.4)
==7850==    by 0x50C8851: g_signal_emit (in
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3200.4)
==7850==    by 0x6AD693D: ??? (in
/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.10)
==7850==    by 0x69BDA7F: gtk_main_do_event (in
/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.10)


[Several empty lines]


==7850==    by 0x712A46B: ??? (in
/usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0.2400.10)
==7850==    by 0x712A412: ??? (in
/usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0.2400.10)
==7850==  Address 0x8 is not stack'd, malloc'd or (recently) free'd
==7850==
==7850== Warning: client switching stacks?  SP change: 0xead7860 -->
0x7fefff4d0
==7850==          to suppress, use: --max-stackframe=34096708720 or greater

**** exception(225): memory access violation at address: 0x00000008: no
mapping at fault address
******** errors detected; see standard output for details ********
==7850==
==7850== HEAP SUMMARY:
==7850==     in use at exit: 4,593,599 bytes in 7,270 blocks
==7850==   total heap usage: 42,126 allocs, 34,856 frees, 8,619,425
bytes allocated
==7850==
==7850== LEAK SUMMARY:
==7850==    definitely lost: 17,507 bytes in 14 blocks
==7850==    indirectly lost: 3,792,311 bytes in 615 blocks
==7850==      possibly lost: 137,180 bytes in 771 blocks
==7850==    still reachable: 646,601 bytes in 5,870 blocks
==7850==         suppressed: 0 bytes in 0 blocks
==7850== Rerun with --leak-check=full to see details of leaked memory
==7850==
==7850== For counts of detected and suppressed errors, rerun with: -v
==7850== Use --track-origins=yes to see where uninitialised values come from
==7850== ERROR SUMMARY: 2621629 errors from 10 contexts (suppressed: 8
from 8)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]