Horde3D

Next-Generation Graphics Engine
It is currently 27.11.2024, 14:02

All times are UTC + 1 hour




Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: 04.07.2009, 04:16 
Offline

Joined: 04.07.2009, 03:52
Posts: 8
Hello all,

I'm having a problem where Horde3D causes a segfault in Horde3D::init() in Ubuntu Jaunty. Tracing it in GDB is a bit mysterious, as GDB reports that the segfault occurs in 'Horde3DEngine/egMain.cpp:87', which is the fairly innocuous line:

Code:
if( !Modules::renderer().init() ) return false;


This segfault occurs in my code in linux, but not in the demo programs, which compile and run just fine. Also, my code is cross platform, and works perfectly fine in Windows when compiled in VS2008.

Horde3D::init() is almost the first thing called in the program, just after the code to create an OpenGL window. I played around with modifying the Horde3D code to try to get it working, and found that removing the 'virtual' keywords from the RendererBase::init() function in 'Horde3DEngine/egRendererBase.h' fixed the original segfault, but led to another in 'Horde3DEngine/egRendererBase.cpp:72'.

With basic functions segfaulting, I'm thinking it might be a bad compiler setting or something, but I'm not using any strange settings in my compilation. Any ideas?

The relevant sections of code are below. H3d::init() is the first thing called in the main program, right after a H3d object is created (nothing in the constructor).

Code:
void H3d::init(int w, int h)
{
   _cpath = "/home/******/Desktop/k3engine/build/";

   // initialize sdl
   k3SDL::init();
   resetVideoMode(w, h, false);

       // Initialize engine
   if( !Horde3D::init() ) // <--- This is exactly where it fails
   {   
      LOG(logERROR) << "Horde3D init error";
   }
   ...
   // Other stuff, but it's already crashed by here
}

void k3SDL::init()
{
   if(_initted)
      return;

   // SDL Initialization
   int error;
   error = SDL_Init(SDL_INIT_EVERYTHING);
   _initted = true;
}

int H3d::resetVideoMode(int screenWidth, int screenHeight, bool fullscreen)
{
   // SDL/OpenGL initialization (doublebuffered, depthbuffered, 32 bit color)
   SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
   SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
   SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
   SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
   SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
   SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);

   SDL_Surface* drawContext;
   Uint32 flags;

   if(fullscreen)
      flags = SDL_OPENGL | SDL_HWSURFACE | SDL_FULLSCREEN;
   else
      flags = SDL_OPENGL | SDL_HWSURFACE;

   drawContext = SDL_SetVideoMode(screenWidth, screenHeight, 0, flags);

   _screenW = screenWidth;
   _screenH = screenHeight;
   return 1;
}


Top
 Profile  
Reply with quote  
PostPosted: 04.07.2009, 13:49 
Offline

Joined: 21.12.2008, 23:46
Posts: 23
Try to call your resetVideoMode()-function(i.e. initializing SDL) before initializing Horde.


Top
 Profile  
Reply with quote  
PostPosted: 04.07.2009, 16:30 
Offline

Joined: 22.11.2007, 17:05
Posts: 707
Location: Boston, MA
wakko wrote:
Try to call your resetVideoMode()-function(i.e. initializing SDL) before initializing Horde.
Ja, you absolutely have to have a valid OpenGL context before calling Horde.init.

_________________
Tristam MacDonald - [swiftcoding]


Top
 Profile  
Reply with quote  
PostPosted: 04.07.2009, 17:14 
Offline

Joined: 04.07.2009, 03:52
Posts: 8
Right, I'm pretty sure that I'm doing that. H3d::init() is my function (yes, yes, confusing name), and the first thing it does is initialize an SDL window with GL, and the second thing is calling Horde3D::init(). In fact, when using GDB, at the time the segfault occurs, SDL has already opened a perfectly good 800x600 GL window. It's just sitting on the desktop while I stack trace Horde3D::init().

Code:
...
// initialize sdl
k3SDL::init();
resetVideoMode(w, h, false); // <---SDL GL window is opened by here

// Initialize engine
if( !Horde3D::init() ) // <--- This is exactly where it fails
{   
   LOG(logERROR) << "Horde3D init error";
}
...


Top
 Profile  
Reply with quote  
PostPosted: 04.07.2009, 17:46 
Offline

Joined: 06.06.2009, 23:13
Posts: 7
Could you attach a minimal self-contained example which crashes (with a Makefile), so we could try it?
(You are using 1.0.0-beta3, right?)


Top
 Profile  
Reply with quote  
PostPosted: 05.07.2009, 07:43 
Offline

Joined: 04.07.2009, 03:52
Posts: 8
Ok, I solved the problem. I have several rendering modules (2D, 3D, etc) that I can select between depending on the type of game I am making. It turns out that Horde3D and one of the other modules both use a few generic classnames, e.g. Renderer, and neither package was using namespaces. Even though I was only using Horde3D, both were being compiled into libraries, and then during runtime linking, Horde3D somehow linked to the opposite Renderer class without any errors (it wasn't checked because the function calls were virtual :roll:) and promptly killed itself.

I added a namespace to the other module to fix the problem, but it would probably be helpful to use namespaces in Horde3D to avoid this problem in general.


Top
 Profile  
Reply with quote  
PostPosted: 05.07.2009, 14:36 
Offline

Joined: 22.11.2007, 17:05
Posts: 707
Location: Boston, MA
wakka wrote:
I added a namespace to the other module to fix the problem, but it would probably be helpful to use namespaces in Horde3D to avoid this problem in general.
Horde's public API doesn't expose any classes, for the same reason that it doesn't use a namespace - it is a C API. It sounds like you are including internal headers by mistake.

_________________
Tristam MacDonald - [swiftcoding]


Top
 Profile  
Reply with quote  
PostPosted: 06.07.2009, 01:28 
Offline

Joined: 08.11.2006, 03:10
Posts: 384
Location: Australia
I'm not sure (as I'm a windows man), but doesn't GCC export all symbols in a library, not just the "public" C API? If so, this could mean that internal class names in the Horde library could cause linking conflicts with other libraries...


Top
 Profile  
Reply with quote  
PostPosted: 06.07.2009, 01:39 
Offline

Joined: 22.11.2007, 17:05
Posts: 707
Location: Boston, MA
DarkAngel wrote:
I'm not sure (as I'm a windows man), but doesn't GCC export all symbols in a library, not just the "public" C API?
It doesn't have to - may do by default if you have an old version of GCC.

_________________
Tristam MacDonald - [swiftcoding]


Top
 Profile  
Reply with quote  
PostPosted: 07.07.2009, 18:38 
Offline

Joined: 04.07.2009, 03:52
Posts: 8
swiftcoder wrote:
Horde's public API doesn't expose any classes, for the same reason that it doesn't use a namespace - it is a C API. It sounds like you are including internal headers by mistake.

No, just using the two exported ones and dynamically linking to the library. C'mon now, give me some credit.
swiftcoder wrote:
It doesn't have to - may do by default if you have an old version of GCC.

I'm using the latest GCC in the Jaunty repositories (4.3.3). But I found another case of this happening. Apparently under certain conditions, normally internal symbols are left accessible in compiled libraries and can collide. I was compiling with "-g", so maybe that was doing it.

Anyway, I can understand wanting to keep the API in C. At this point I'm not sure there's anything to do about this issue other than acknowledge that it can happen. Or rename all the internal functions with crazy prefixes.


Top
 Profile  
Reply with quote  
PostPosted: 07.07.2009, 19:45 
Offline

Joined: 22.11.2007, 17:05
Posts: 707
Location: Boston, MA
wakka wrote:
Apparently under certain conditions, normally internal symbols are left accessible in compiled libraries and can collide. I was compiling with "-g", so maybe that was doing it.

At this point I'm not sure there's anything to do about this issue other than acknowledge that it can happen. Or rename all the internal functions with crazy prefixes.
I have applied a patch to the community SVN which adds support for symbol visibility under GCC. Under normal conditions, it wont make any difference, but if you feed the '-fvisibility=hidden' option to GCC, all internal symbols will be kept private.

I haven't figured out how to make CMake automatically feed that option to GCC yet.

_________________
Tristam MacDonald - [swiftcoding]


Top
 Profile  
Reply with quote  
PostPosted: 07.07.2009, 19:57 
Offline

Joined: 04.07.2009, 03:52
Posts: 8
swiftcoder wrote:
I have applied a patch to the community SVN which adds support for symbol visibility under GCC. Under normal conditions, it wont make any difference, but if you feed the '-fvisibility=hidden' option to GCC, all internal symbols will be kept private.

This sounds like the right solution, thanks!


Top
 Profile  
Reply with quote  
PostPosted: 07.07.2009, 21:16 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
swiftcoder wrote:
wakka wrote:
I have applied a patch to the community SVN which adds support for symbol visibility under GCC. Under normal conditions, it wont make any difference, but if you feed the '-fvisibility=hidden' option to GCC, all internal symbols will be kept private.

I haven't figured out how to make CMake automatically feed that option to GCC yet.

Great swiftcoder, thanks for that! We could put all the internal classes in a namespace as well but I think it is cleaner to have control over what is exported. If someone has a way to add the visibility flag to CMake please let us know.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 14 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group