Subject: Getting Mozilla to run under NetBSD
To: None <port-i386@netbsd.org>
From: Tom Ivar Helbekkmo <tih@nhh.no>
List: port-i386
Date: 12/07/1998 07:54:37
I keep trying to get Mozilla (-current) to work on NetBSD/i386 1.3.2.
Unfortunately, it looks like my lack of C++ knowledge is stopping me
right now.  Mozilla configures and compiles just great, but crashes
immediately upon startup, when it tries to dereference a null
pointer.  In gfx/src/nsImageManager.cpp, we find this:

// The singleton image manager
static ImageManagerImpl*   gImageManager;

// Class to manage construction and destruction of the singleton
// image manager
struct ImageManagerInit {
  ImageManagerInit() {
    gImageManager = new ImageManagerImpl();
    NS_ADDREF(gImageManager);
  }

  ~ImageManagerInit() {
    NS_RELEASE(gImageManager);
  }
};

static ImageManagerInit imageManagerInit;

extern "C" NS_GFX_(nsresult)
NS_NewImageManager(nsIImageManager **aInstancePtrResult)
{
  NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
  if (nsnull == aInstancePtrResult) {
    return NS_ERROR_NULL_POINTER;
  }

  NS_ASSERTION(nsnull != gImageManager, "no image manager");
  return gImageManager->QueryInterface(kIImageManagerIID, (void **)aInstancePtrResult);
}

Now, NS_NewImageManager gets called from main(), without anything
having been done to initialize any of this, and it crashes when it
tries to dereference gImageManager in the return statement above.
Adding a statement

	ImageManagerInit.imageManagerInit();

in the middle of NS_NewImageManager() gets me past this point, but I
then get similar crashes elsewhere -- which leads me to believe that
it's supposed to work the way it is.

Little things I've picked up here and there lead me to believe that
certain initializations are supposed to take place automatically with
C++, and so I'm wondering whether the statement

	static ImageManagerInit imageManagerInit;

should actually cause the constructor (that's what they're called,
right?) inside the given struct definition for ImageManagerInit to be
called before main() even runs.  If my shaky understanding of things
is right, /usr/lib/c++rt0.o has something to do with this, and is
supposed to be included in the shared library that the above code
resides in, in order for this to happen.  This isn't done during the
build of Mozilla.

However, if I try to add c++rt0.o to the set of object files supplied
to ld for the building of the shared library in question, I end up
with another error situation:  Mozilla then doesn't even try to start,
but fails very quickly with the error message:

	failed to initialize shared libraries [Service unavailable]

However, I see from the system library Makefiles that c++rt0.o is,
indeed included in e.g. libstdc++.so.0.1, so it can't be all wrong to
do it.  What am I missing here?  Some magic required during the
building of the actual executable?  Or am I on the wrong track
altogether?  Any hints much appreciated!

-tih
-- 
Popularity is the hallmark of mediocrity.  --Niles Crane, "Frasier"