Often the first time you create an XPCOM component, it may fail to register correctly.
There are several common reasons that registration can fail:
- A component that is a binary (shared library) fails to load
- A JavaScript component has parsing errors
- The shared library loaded correctly, but registration was not successful
Did Registration Succeed?
It is important to not misdiagnose the problem. You can be certain that a component has failed to register by going to the Error Console and evaluating Components.classes["contract-id"].name
where contract-id is your contract ID. If the response is your contract ID instead of an error, the component was successfully registered and this is the wrong page.
Load Failure of Binary Components
On the Mozilla trunk (Firefox 3, XULRunner 1.9), components that fail to load will print an error to the Error Console. Chrome errors must be enabled. If the error appears, you can use NSPR logging to see additional information about the failure by running Firefox from a command prompt:
rem Close all Firefox windows!
set NSPR_LOG_MODULES=nsNativeModuleLoader:5
set NSPR_LOG_FILE=C:\Path\to\logfile
"C:\Program Files\Mozilla Firefox\firefox.exe"
Examining this log for warning and errors may provide valuable clues why the component failed to load.
If using Firefox 4 / XULRunner 2.0, make sure that your extension is unpacked and you declared the binary component in your chrome.manifest
. See XPCOM changes in Gecko 2.0
Parsing Errors in JavaScript Components
The most common reason for components written in JavaScript to fail is that there are parsing errors. These parsing errors should show up in the Error Console if chrome errors are enabled. To learn more about enabling chrome errors, see "How can I see errors in my code" in the Extension FAQs.
Registration Failure
If the module is loading correctly but doesn't register its components, try adding calls to Components.utils.reportError("Debug me!");
in NSGetModule()
and other functions to try and find any errors.
General hints
- You may need to delete compreg.dat in your profile folder to force re-registration. This should not occur if you uninstalled/installed your extension via the Extension Manager.
- When adding a component to a XULRunner application, change the BuildID in application.ini.
- If your component requires any external libraries, you may need to read Using Dependent Libraries In Extension Components
- Make sure you are compiling against the right version.
- If you are testing with a release from mozilla.org, use the Gecko SDK (and not your own compile of trunk Firefox, etc.).
- If you are compiling your own Firefox (or XULRunner, etc.), use the artifacts from that compilation to build your component.
- If you are testing a build from your Linux distribution (or other vendor-supplied build), look for -dev packages from them.
- Remember to check that the directory the component is in is named correctly i.e.
$profile/extensions/$plugindirectory/components
!
- Double check your GUIDs in your install.rdf with your sourcecode, and then check them again.
Windows-specific hints
- Use Dependency Walker to check that your dependent libraries are loaded correctly.
- In Dependency Walker, open the Options menu and select Configure Module Search Order....
- In the bottom right corner of the new dialog, click Browse... and select the directory firefox.exe (or equivalent) is in.
- In the bottom left corner, click Add Directory.
- Do not add any other directories; in particular, do not add your extension's (or XULRunner application's) components directory.
- After clicking OK in the top right, check for any missing dependencies using File -> Open -> firefox.exe (or equivalent).
- Also check that the function
NSGetModule
is exported.
- You can also use the Profiling feature of Dependency Walker to view failed module loads while running your application. Open the Profile menu and select Start Profiling.... In the dialog that appears, you can provide command line parameters and click OK to start the application. You will see any modules that failed to load in the module list.
Note: You should delete compreg.dat
from your profile before doing this.
- Note that even your version of MSVC may matter; your test machine may not have the C runtime libraries (msvcr70.dll / msvcp70.dll for MSVC 7.0, and similarly named files for 7.1 and 8.0) available.
- This even means that if you are using a component stub, the stub needs to be compiled using a version which the machine does support; most likely this means MSVC 6.0. It may then be necessary for the stub to locate the newer runtime libraries for the other files it loads.
- If you compiled the component with MSVC 8.0 (2005) and are attempting to use it on a Windows XP machine or later, it will need a manifest embedded to find the runtime. Please refer to MSDN for details.
- If you have the option, you can manually copy these dependencies to firefox.exe's directory, to Windows\system32, or to any directory is the system's PATH.
- A Google Groups thread on the matter is located here.
- The dllmain code that MSVC 8 (and probably earlier versions too) generates for you doesn't need to be there, you can remove it.
- You may be able build your component using USE_STATIC_LIBS=1 in order to remove C runtime library dependencies.
Linux-specific hints
- Check if you have missing dependent libraries:
- From your Firefox (/XULRunner) install directory, run "
./run-mozilla.sh `which ldd` -r path/to/your/component.so
". There should be no "not found" entries and no undefined symbols. (The -r
switch from GNU ldd lists function relocations; adjust as suitable for your version)
- Trace shared library loading by setting the environment variable
LD_DEBUG=all
while launching Firefox (see `man ld.so` for details).
- Use strace to see if Firefox is trying to load your components.
- Pass the
-Wl,-z,defs
flag to gcc when linking your component. This will ensure that undefined symbols show an error at link time instead of failing at run time.
Mac-specific hints
- Use ktrace to see if Firefox is trying to load your components.
- Use dyld environment variables to trace binary component loading: DYLD_PRINT_APIS=1 DYLD_PRINT_LIBRARIES=1 (see `man dyld` for details).
Further help
If the component still does not load, you may wish to ask for help. The extension-related places are often useful; please refer to the Community section on the Extensions page.