Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: Program works while debugging with debug or release mode, but an executable alone not

  1. #1
    Junior Member Newbie
    Join Date
    Feb 2016
    Posts
    24

    Program works while debugging with debug or release mode, but an executable alone not

    Hello folks,

    I have really weird dilemma: I have Win32 CAD program, whose OpenGL related DLL library is compiled by a Visual Studio 2010 and other parts of program are compiled dy Embarcadero XE8. The whole system works fine on three separate workstations when debugging it with Visual Studio 2010, but if I try to run the executable alone, some test files (not every file) doesn't show lightning, dark world or at least distorted static shadows shows up instead.

    So, with debugger everything is working perfectly, but executable alone only part of the test files works as expected. And more confusion, if I first open a perfectly working file and then a file which doesn't show lightning, then both files are working perfectly or at least lights are on but shadows may be off. However, this misbehaviour is deterministic: it does always the same fails and same order even on different machines. Nvidia or AMD don't make a difference with regard to their behaviour or misbehaviour. GeForce GT 525M, AMD Radeon R6 and GeForce GTX 860M show equal behaviour.

    What could be wrong?

    1: I think this could be some out-of-memory problem. The program doesn't check available memory on board and it doesn't count the memory needed to load some file, but after loading more OpenGL stuff it checks GL_OUT_OF_MEMORY by glGetError(). But, because I get the lightning working by loading a file after another, this doesn't seem a memory problem (the first file is still loaded, so there is more OpenGL stuff on board). Anyway, opengl driver memory management is tricky -actually I dont know, I only guess- so if the driver feels it doesn't have enough memory or time, is it possible that driver just silently refuses to allocate space or transfer data and keep working like everything was okay?

    2: On the other way, it is possible that CUDA or OpenCL could indirectly cause a lightning problem, but I don't delieve it because the behaviour is identical between a CUDA machine and an OpenCL machine. If the problem would be there, their behaviour would differ. Moreover, the case where lights are on but shadows are absent or distorted, is definitely not a CUDA or OpenCL case. But if you think I should double check or triple check CUDA/OpenCL, I'm glad if you tell it to me.

    3: The third sympton would be threads: I use boost::thread and boost::asio libraries to handle four threads, and OpenGL rendering context is connected to two of them, in different times I hope. This is the thing I suspect at most. But, if this is the reason of misbehaviour, shouldn't it prevent rendering completely? All rendering is happening in a same thread, which calls a single render function that draws everything. Moreover, the program works either with OpenGL 4.0 or OpenGL 1.5, and they both use the same threading skeme. OpenGL 1.5 works perfectly with all files, so this is an indication that threads work correctly.

    4: Some other reason you name it

    Please help, any suggestions are welcome...

  2. #2
    Junior Member Newbie
    Join Date
    Feb 2016
    Posts
    24
    There were bugs here and there, but one thing I want to point out: If you are using boost threads and OpenGL, make sure that OpenGL thread is always bound the thread which "talks" with OpenGL. If there are several threads talking to OpenGL, you need to change context between threads by wglMakeCurrent:

    Code :
    wglMakeCurrent(NULL, NULL);  //leaving thread
     
    wglMakeCurrent(Window_Handle/HDC, Rendering_Handle/HGLRC);  //new thread

    Context changing is an expensive operation as well as to create and destroy threads. Therefore I'm using boost::asio library which keeps your threads alive, so a single thread invocation and destruction happens during the lifetime of a program. There is one caveat about boost::asio and OpenGL: DON'T USE A THREADPOOL!! If you do that, you're forced to call wglMakeCurrent every time you use your threads. Instead use fixed threads and call wglMakeCurrent only once. Below is an example class how to do that:

    Code :
    #ifndef __saie_H
    #define __saie_H
     
    class Saie : public boost::asio::io_service::service {
     
      private:
    	boost::asio::io_service ioPalvelu;
    	boost::shared_ptr<boost::asio::io_service::work> tyo;
    	boost::shared_ptr<boost::thread> saie;
    	volatile bool sammutus;
     
    	Saie(const Saie& saie);
    	Saie & operator=(const Saie& saie);
     
      public:
    	Saie(boost::asio::io_service& io);
    	virtual ~Saie();
     
    //we need to define an abstract method
    	void shutdown_service() {}
     
    //returns a reference to this service
    	boost::asio::io_service& annaPalvelu();
     
    //test whether the service is ready
    	bool onkoPysaytetty();
     
    //run a thread
    	void saieRun(void (*funktio)());
     
    //stop service
    	void saieStop();
     
    //restart service
    	void saieReset();
    };
     
    #endif
     
     
     
     
    #include "stdafx.h"
     
    #include "saie.h"
     
    Saie::Saie(boost::asio::io_service& io) : boost::asio::io_service::service(io), 
    	                                      ioPalvelu(),
    	                                      tyo(new boost::asio::io_service::work(ioPalvelu)), 
                                              saie(new boost::thread(boost::bind(&boost::asio::io_service::run, &ioPalvelu))) {
     
      sammutus=false;
    }
     
    Saie::~Saie() {
      saieStop();
    }
     
     
    boost::asio::io_service& Saie::annaPalvelu() {
      return ioPalvelu;
    }
     
    bool Saie::onkoPysaytetty() {
      return sammutus;
    }
     
    void Saie::saieRun(void (*funktio)()) {
      ioPalvelu.post(funktio);
    }
     
    void Saie::saieStop() {
      if (sammutus==false) {
        ioPalvelu.stop();
        if (saie) {
    		saie->join();
    	}
    	sammutus=true;
      }
    }
     
    void Saie::saieReset() {
      if (sammutus==true) {
    	ioPalvelu.reset();
    	tyo.reset(new boost::asio::io_service::work(ioPalvelu));
    	saie.reset(new boost::thread(boost::bind(&boost::asio::io_service::run, &ioPalvelu)));
    	sammutus=false;
      }
    }

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •