Bug 325229 part 1 - standalone glue registers exit routine which is called after module unload; also fixes bug 317481 - C API for nsTraceRefcnt; also fixes bug 318622 - Make nsTraceRefcntImpl::SetActivityIsLegal work properly and turn it on; design review by dbaron, r=darin
git-svn-id: svn://10.0.0.236/trunk@189558 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
ca08a4fcea
commit
70d82c362b
@ -5728,18 +5728,6 @@ else
|
||||
AC_DEFINE(MOZ_LOGGING)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl Crash on assert
|
||||
dnl ========================================================
|
||||
MOZ_ARG_ENABLE_BOOL(crash-on-assert,
|
||||
[ --enable-crash-on-assert
|
||||
Make NS_ASSERTION crash on Unix],
|
||||
_CRASH_ON_ASSERT=1,
|
||||
_CRASH_ON_ASSERT= )
|
||||
if test "$_CRASH_ON_ASSERT"; then
|
||||
AC_DEFINE(UNIX_CRASH_ON_ASSERT)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable function reordering. Off by default
|
||||
dnl ========================================================
|
||||
|
||||
@ -181,7 +181,7 @@ private:
|
||||
#define NS_BOX_ASSERTION(box,expr,str) \
|
||||
if (!(expr)) { \
|
||||
box->DumpBox(stdout); \
|
||||
NSGlue_Assertion(str, #expr, __FILE__, __LINE__); \
|
||||
NS_DebugBreak(NSDebugAssertion, str, #expr, __FILE__, __LINE__); \
|
||||
}
|
||||
#else
|
||||
#define NS_BOX_ASSERTION(box,expr,str) {}
|
||||
|
||||
@ -746,22 +746,28 @@ static void DumpArbitraryHelp()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsXREDirProvider dirProvider;
|
||||
dirProvider.Initialize(nsnull);
|
||||
NS_LogInit();
|
||||
|
||||
ScopedXPCOMStartup xpcom;
|
||||
xpcom.Initialize();
|
||||
xpcom.DoAutoreg();
|
||||
{
|
||||
nsXREDirProvider dirProvider;
|
||||
dirProvider.Initialize(nsnull);
|
||||
|
||||
nsCOMPtr<nsICommandLineRunner> cmdline
|
||||
(do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
|
||||
if (!cmdline)
|
||||
return;
|
||||
ScopedXPCOMStartup xpcom;
|
||||
xpcom.Initialize();
|
||||
xpcom.DoAutoreg();
|
||||
|
||||
nsCString text;
|
||||
rv = cmdline->GetHelpText(text);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
printf("%s", text.get());
|
||||
nsCOMPtr<nsICommandLineRunner> cmdline
|
||||
(do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
|
||||
if (!cmdline)
|
||||
return;
|
||||
|
||||
nsCString text;
|
||||
rv = cmdline->GetHelpText(text);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
printf("%s", text.get());
|
||||
}
|
||||
|
||||
NS_LogTerm();
|
||||
}
|
||||
|
||||
// English text needs to go into a dtd file.
|
||||
@ -1950,443 +1956,449 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
||||
gArgc = argc = NS_TraceMallocStartupArgs(argc, argv);
|
||||
#endif
|
||||
|
||||
nsXREDirProvider dirProvider;
|
||||
NS_LogInit();
|
||||
|
||||
{
|
||||
nsXREDirProvider dirProvider;
|
||||
rv = dirProvider.Initialize(gAppData->directory);
|
||||
if (NS_FAILED(rv))
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check for -register, which registers chrome and then exits immediately.
|
||||
if (CheckArg("register")) {
|
||||
ScopedXPCOMStartup xpcom;
|
||||
rv = xpcom.Initialize();
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
// Check for -register, which registers chrome and then exits immediately.
|
||||
if (CheckArg("register")) {
|
||||
ScopedXPCOMStartup xpcom;
|
||||
rv = xpcom.Initialize();
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIChromeRegistry> chromeReg
|
||||
(do_GetService("@mozilla.org/chrome/chrome-registry;1"));
|
||||
NS_ENSURE_TRUE(chromeReg, 1);
|
||||
{
|
||||
nsCOMPtr<nsIChromeRegistry> chromeReg
|
||||
(do_GetService("@mozilla.org/chrome/chrome-registry;1"));
|
||||
NS_ENSURE_TRUE(chromeReg, 1);
|
||||
|
||||
chromeReg->CheckForNewChrome();
|
||||
chromeReg->CheckForNewChrome();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_GTK2)
|
||||
// setup for private colormap. Ideally we'd like to do this
|
||||
// in nsAppShell::Create, but we need to get in before gtk
|
||||
// has been initialized to make sure everything is running
|
||||
// consistently.
|
||||
if (CheckArg("install"))
|
||||
gdk_rgb_set_install(TRUE);
|
||||
// setup for private colormap. Ideally we'd like to do this
|
||||
// in nsAppShell::Create, but we need to get in before gtk
|
||||
// has been initialized to make sure everything is running
|
||||
// consistently.
|
||||
if (CheckArg("install"))
|
||||
gdk_rgb_set_install(TRUE);
|
||||
|
||||
// Initialize GTK+1/2 here for splash
|
||||
// Initialize GTK+1/2 here for splash
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
gtk_set_locale();
|
||||
gtk_set_locale();
|
||||
#endif
|
||||
gtk_init(&gArgc, &gArgv);
|
||||
gtk_init(&gArgc, &gArgv);
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK2)
|
||||
// g_set_application_name () is only defined in glib2.2 and higher.
|
||||
PRLibrary *glib2 = nsnull;
|
||||
_g_set_application_name_fn _g_set_application_name =
|
||||
// g_set_application_name () is only defined in glib2.2 and higher.
|
||||
PRLibrary *glib2 = nsnull;
|
||||
_g_set_application_name_fn _g_set_application_name =
|
||||
(_g_set_application_name_fn)PR_FindFunctionSymbolAndLibrary("g_set_application_name", &glib2);
|
||||
if (_g_set_application_name) {
|
||||
_g_set_application_name(gAppData->name);
|
||||
}
|
||||
if (glib2) {
|
||||
PR_UnloadLibrary(glib2);
|
||||
}
|
||||
if (_g_set_application_name) {
|
||||
_g_set_application_name(gAppData->name);
|
||||
}
|
||||
if (glib2) {
|
||||
PR_UnloadLibrary(glib2);
|
||||
}
|
||||
#endif
|
||||
|
||||
gtk_widget_set_default_visual(gdk_rgb_get_visual());
|
||||
gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
|
||||
gtk_widget_set_default_visual(gdk_rgb_get_visual());
|
||||
gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
|
||||
#endif /* MOZ_WIDGET_GTK || MOZ_WIDGET_GTK2 */
|
||||
|
||||
#if defined(MOZ_WIDGET_QT)
|
||||
QApplication qapp(argc, argv);
|
||||
QApplication qapp(argc, argv);
|
||||
#endif
|
||||
|
||||
// #if defined(MOZ_WIDGET_XLIB)
|
||||
// XXXtimeless fix me! How do we get a Display from here to nsAppShell.cpp ?
|
||||
// #endif
|
||||
// #if defined(MOZ_WIDGET_XLIB)
|
||||
// XXXtimeless fix me! How do we get a Display from here to nsAppShell.cpp ?
|
||||
// #endif
|
||||
|
||||
// Call the code to install our handler
|
||||
// Call the code to install our handler
|
||||
#ifdef MOZ_JPROF
|
||||
setupProfilingStuff();
|
||||
setupProfilingStuff();
|
||||
#endif
|
||||
|
||||
// Try to allocate "native app support."
|
||||
nsCOMPtr<nsINativeAppSupport> nativeApp;
|
||||
rv = NS_CreateNativeAppSupport(getter_AddRefs(nativeApp));
|
||||
if (NS_FAILED(rv))
|
||||
return 1;
|
||||
// Try to allocate "native app support."
|
||||
nsCOMPtr<nsINativeAppSupport> nativeApp;
|
||||
rv = NS_CreateNativeAppSupport(getter_AddRefs(nativeApp));
|
||||
if (NS_FAILED(rv))
|
||||
return 1;
|
||||
|
||||
PRBool canRun = PR_FALSE;
|
||||
rv = nativeApp->Start(&canRun);
|
||||
if (NS_FAILED(rv) || !canRun) {
|
||||
return 1;
|
||||
}
|
||||
PRBool canRun = PR_FALSE;
|
||||
rv = nativeApp->Start(&canRun);
|
||||
if (NS_FAILED(rv) || !canRun) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef MOZ_XPINSTALL
|
||||
//----------------------------------------------------------------
|
||||
// We need to check if a previous installation occured and
|
||||
// if so, make sure it finished and cleaned up correctly.
|
||||
//
|
||||
// If there is an xpicleanup.dat file left around, that means the
|
||||
// previous installation did not finish correctly. We must cleanup
|
||||
// before a valid mozilla can run.
|
||||
//
|
||||
// Show the user a platform-specific Alert message, then spawn the
|
||||
// xpicleanup utility, then exit.
|
||||
//----------------------------------------------------------------
|
||||
nsCOMPtr<nsIFile> registryFile;
|
||||
rv = dirProvider.GetAppDir()->Clone(getter_AddRefs(registryFile));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
registryFile->AppendNative(CLEANUP_REGISTRY);
|
||||
//----------------------------------------------------------------
|
||||
// We need to check if a previous installation occured and
|
||||
// if so, make sure it finished and cleaned up correctly.
|
||||
//
|
||||
// If there is an xpicleanup.dat file left around, that means the
|
||||
// previous installation did not finish correctly. We must cleanup
|
||||
// before a valid mozilla can run.
|
||||
//
|
||||
// Show the user a platform-specific Alert message, then spawn the
|
||||
// xpicleanup utility, then exit.
|
||||
//----------------------------------------------------------------
|
||||
{
|
||||
nsCOMPtr<nsIFile> registryFile;
|
||||
rv = dirProvider.GetAppDir()->Clone(getter_AddRefs(registryFile));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
registryFile->AppendNative(CLEANUP_REGISTRY);
|
||||
|
||||
PRBool exists;
|
||||
rv = registryFile->Exists(&exists);
|
||||
if (NS_SUCCEEDED(rv) && exists) {
|
||||
return VerifyInstallation(dirProvider.GetAppDir());
|
||||
PRBool exists;
|
||||
rv = registryFile->Exists(&exists);
|
||||
if (NS_SUCCEEDED(rv) && exists) {
|
||||
return VerifyInstallation(dirProvider.GetAppDir());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_ENABLE_XREMOTE
|
||||
// handle -remote now that xpcom is fired up
|
||||
// handle -remote now that xpcom is fired up
|
||||
|
||||
const char* xremotearg;
|
||||
ArgResult ar = CheckArg("remote", &xremotearg);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR, "Error: -remote requires an argument\n");
|
||||
return 1;
|
||||
}
|
||||
if (ar) {
|
||||
return HandleRemoteArgument(xremotearg);
|
||||
}
|
||||
const char* xremotearg;
|
||||
ArgResult ar = CheckArg("remote", &xremotearg);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR, "Error: -remote requires an argument\n");
|
||||
return 1;
|
||||
}
|
||||
if (ar) {
|
||||
return HandleRemoteArgument(xremotearg);
|
||||
}
|
||||
|
||||
if (!PR_GetEnv("MOZ_NO_REMOTE")) {
|
||||
// Try to remote the entire command line. If this fails, start up normally.
|
||||
if (RemoteCommandLine())
|
||||
return 0;
|
||||
}
|
||||
if (!PR_GetEnv("MOZ_NO_REMOTE")) {
|
||||
// Try to remote the entire command line. If this fails, start up normally.
|
||||
if (RemoteCommandLine())
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_UPDATER)
|
||||
// Check for and process any available updates
|
||||
ProcessUpdates(dirProvider.GetAppDir(), gRestartArgc, gRestartArgv);
|
||||
// Check for and process any available updates
|
||||
ProcessUpdates(dirProvider.GetAppDir(), gRestartArgc, gRestartArgv);
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIProfileLock> profileLock;
|
||||
PRBool startOffline = PR_FALSE;
|
||||
nsCOMPtr<nsIProfileLock> profileLock;
|
||||
PRBool startOffline = PR_FALSE;
|
||||
|
||||
rv = SelectProfile(getter_AddRefs(profileLock), nativeApp, &startOffline);
|
||||
if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS ||
|
||||
rv == NS_ERROR_ABORT) return 0;
|
||||
if (NS_FAILED(rv)) return 1;
|
||||
rv = SelectProfile(getter_AddRefs(profileLock), nativeApp, &startOffline);
|
||||
if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS ||
|
||||
rv == NS_ERROR_ABORT) return 0;
|
||||
if (NS_FAILED(rv)) return 1;
|
||||
|
||||
nsCOMPtr<nsILocalFile> profD;
|
||||
rv = profileLock->GetDirectory(getter_AddRefs(profD));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
nsCOMPtr<nsILocalFile> profLD;
|
||||
rv = profileLock->GetLocalDirectory(getter_AddRefs(profLD));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
rv = dirProvider.SetProfile(profD, profLD);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
//////////////////////// NOW WE HAVE A PROFILE ////////////////////////
|
||||
|
||||
PRBool upgraded = PR_FALSE;
|
||||
|
||||
nsCAutoString version;
|
||||
BuildVersion(version);
|
||||
|
||||
// Check for version compatibility with the last version of the app this
|
||||
// profile was started with. The format of the version stamp is defined
|
||||
// by the BuildVersion function.
|
||||
PRBool versionOK = CheckCompatibility(profD, version,
|
||||
dirProvider.GetGREDir(),
|
||||
gAppData->directory);
|
||||
|
||||
// Every time a profile is loaded by a build with a different version,
|
||||
// it updates the compatibility.ini file saying what version last wrote
|
||||
// the compreg.dat. On subsequent launches if the version matches,
|
||||
// there is no need for re-registration. If the user loads the same
|
||||
// profile in different builds the component registry must be
|
||||
// re-generated to prevent mysterious component loading failures.
|
||||
//
|
||||
if (gSafeMode) {
|
||||
RemoveComponentRegistries(profD, profLD, PR_FALSE);
|
||||
WriteVersion(profD, NS_LITERAL_CSTRING("Safe Mode"),
|
||||
dirProvider.GetGREDir(), gAppData->directory);
|
||||
}
|
||||
else if (versionOK) {
|
||||
if (ComponentsListChanged(profD)) {
|
||||
// Remove compreg.dat and xpti.dat, forcing component re-registration.
|
||||
// The new list of additional components directories is derived from
|
||||
// information in "extensions.ini".
|
||||
RemoveComponentRegistries(profD, profLD, PR_FALSE);
|
||||
}
|
||||
// Nothing need be done for the normal startup case.
|
||||
}
|
||||
else {
|
||||
// Remove compreg.dat and xpti.dat, forcing component re-registration
|
||||
// with the default set of components (this disables any potentially
|
||||
// troublesome incompatible XPCOM components).
|
||||
RemoveComponentRegistries(profD, profLD, PR_TRUE);
|
||||
|
||||
// Tell the Extension Manager it should check for incompatible
|
||||
// Extensions and re-write the "extensions.ini" file with a list of
|
||||
// directories for compatible extensions
|
||||
upgraded = PR_TRUE;
|
||||
|
||||
// Write out version
|
||||
WriteVersion(profD, version,
|
||||
dirProvider.GetGREDir(), gAppData->directory);
|
||||
}
|
||||
|
||||
PRBool needsRestart = PR_FALSE;
|
||||
PRBool appInitiatedRestart = PR_FALSE;
|
||||
|
||||
// Allows the user to forcefully bypass the restart process at their
|
||||
// own risk. Useful for debugging or for tinderboxes where child
|
||||
// processes can be problematic.
|
||||
{
|
||||
// Start the real application
|
||||
ScopedXPCOMStartup xpcom;
|
||||
rv = xpcom.Initialize();
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
rv = xpcom.DoAutoreg();
|
||||
rv |= xpcom.InitEventQueue();
|
||||
rv |= xpcom.SetWindowCreator(nativeApp);
|
||||
nsCOMPtr<nsILocalFile> profD;
|
||||
rv = profileLock->GetDirectory(getter_AddRefs(profD));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
{
|
||||
if (startOffline) {
|
||||
nsCOMPtr<nsIIOService> io (do_GetService("@mozilla.org/network/io-service;1"));
|
||||
NS_ENSURE_TRUE(io, 1);
|
||||
io->SetOffline(PR_TRUE);
|
||||
nsCOMPtr<nsILocalFile> profLD;
|
||||
rv = profileLock->GetLocalDirectory(getter_AddRefs(profLD));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
rv = dirProvider.SetProfile(profD, profLD);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
//////////////////////// NOW WE HAVE A PROFILE ////////////////////////
|
||||
|
||||
PRBool upgraded = PR_FALSE;
|
||||
|
||||
nsCAutoString version;
|
||||
BuildVersion(version);
|
||||
|
||||
// Check for version compatibility with the last version of the app this
|
||||
// profile was started with. The format of the version stamp is defined
|
||||
// by the BuildVersion function.
|
||||
PRBool versionOK = CheckCompatibility(profD, version,
|
||||
dirProvider.GetGREDir(),
|
||||
gAppData->directory);
|
||||
|
||||
// Every time a profile is loaded by a build with a different version,
|
||||
// it updates the compatibility.ini file saying what version last wrote
|
||||
// the compreg.dat. On subsequent launches if the version matches,
|
||||
// there is no need for re-registration. If the user loads the same
|
||||
// profile in different builds the component registry must be
|
||||
// re-generated to prevent mysterious component loading failures.
|
||||
//
|
||||
if (gSafeMode) {
|
||||
RemoveComponentRegistries(profD, profLD, PR_FALSE);
|
||||
WriteVersion(profD, NS_LITERAL_CSTRING("Safe Mode"),
|
||||
dirProvider.GetGREDir(), gAppData->directory);
|
||||
}
|
||||
else if (versionOK) {
|
||||
if (ComponentsListChanged(profD)) {
|
||||
// Remove compreg.dat and xpti.dat, forcing component re-registration.
|
||||
// The new list of additional components directories is derived from
|
||||
// information in "extensions.ini".
|
||||
RemoveComponentRegistries(profD, profLD, PR_FALSE);
|
||||
}
|
||||
// Nothing need be done for the normal startup case.
|
||||
}
|
||||
else {
|
||||
// Remove compreg.dat and xpti.dat, forcing component re-registration
|
||||
// with the default set of components (this disables any potentially
|
||||
// troublesome incompatible XPCOM components).
|
||||
RemoveComponentRegistries(profD, profLD, PR_TRUE);
|
||||
|
||||
// Tell the Extension Manager it should check for incompatible
|
||||
// Extensions and re-write the "extensions.ini" file with a list of
|
||||
// directories for compatible extensions
|
||||
upgraded = PR_TRUE;
|
||||
|
||||
// Write out version
|
||||
WriteVersion(profD, version,
|
||||
dirProvider.GetGREDir(), gAppData->directory);
|
||||
}
|
||||
|
||||
PRBool needsRestart = PR_FALSE;
|
||||
PRBool appInitiatedRestart = PR_FALSE;
|
||||
|
||||
// Allows the user to forcefully bypass the restart process at their
|
||||
// own risk. Useful for debugging or for tinderboxes where child
|
||||
// processes can be problematic.
|
||||
{
|
||||
// Start the real application
|
||||
ScopedXPCOMStartup xpcom;
|
||||
rv = xpcom.Initialize();
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
rv = xpcom.DoAutoreg();
|
||||
rv |= xpcom.InitEventQueue();
|
||||
rv |= xpcom.SetWindowCreator(nativeApp);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
{
|
||||
NS_TIMELINE_ENTER("startupNotifier");
|
||||
nsCOMPtr<nsIObserver> startupNotifier
|
||||
(do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
if (startOffline) {
|
||||
nsCOMPtr<nsIIOService> io (do_GetService("@mozilla.org/network/io-service;1"));
|
||||
NS_ENSURE_TRUE(io, 1);
|
||||
io->SetOffline(PR_TRUE);
|
||||
}
|
||||
|
||||
startupNotifier->Observe(nsnull, APPSTARTUP_TOPIC, nsnull);
|
||||
NS_TIMELINE_LEAVE("startupNotifier");
|
||||
}
|
||||
{
|
||||
NS_TIMELINE_ENTER("startupNotifier");
|
||||
nsCOMPtr<nsIObserver> startupNotifier
|
||||
(do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
nsCOMPtr<nsIAppStartup> appStartup
|
||||
(do_GetService(NS_APPSTARTUP_CONTRACTID));
|
||||
NS_ENSURE_TRUE(appStartup, 1);
|
||||
startupNotifier->Observe(nsnull, APPSTARTUP_TOPIC, nsnull);
|
||||
NS_TIMELINE_LEAVE("startupNotifier");
|
||||
}
|
||||
|
||||
if (gDoMigration) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
profD->Clone(getter_AddRefs(file));
|
||||
file->AppendNative(NS_LITERAL_CSTRING("override.ini"));
|
||||
nsINIParser parser;
|
||||
nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(file));
|
||||
nsresult rv = parser.Init(localFile);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString buf;
|
||||
rv = parser.GetString("XRE", "EnableProfileMigrator", buf);
|
||||
nsCOMPtr<nsIAppStartup> appStartup
|
||||
(do_GetService(NS_APPSTARTUP_CONTRACTID));
|
||||
NS_ENSURE_TRUE(appStartup, 1);
|
||||
|
||||
if (gDoMigration) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
profD->Clone(getter_AddRefs(file));
|
||||
file->AppendNative(NS_LITERAL_CSTRING("override.ini"));
|
||||
nsINIParser parser;
|
||||
nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(file));
|
||||
nsresult rv = parser.Init(localFile);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (buf[0] == '0' || buf[0] == 'f' || buf[0] == 'F') {
|
||||
gDoMigration = PR_FALSE;
|
||||
nsCAutoString buf;
|
||||
rv = parser.GetString("XRE", "EnableProfileMigrator", buf);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (buf[0] == '0' || buf[0] == 'f' || buf[0] == 'F') {
|
||||
gDoMigration = PR_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Profile Migration
|
||||
if (gAppData->flags & NS_XRE_ENABLE_PROFILE_MIGRATOR && gDoMigration) {
|
||||
gDoMigration = PR_FALSE;
|
||||
nsCOMPtr<nsIProfileMigrator> pm
|
||||
(do_CreateInstance(NS_PROFILEMIGRATOR_CONTRACTID));
|
||||
if (pm)
|
||||
pm->Migrate(&dirProvider);
|
||||
}
|
||||
dirProvider.DoStartup();
|
||||
|
||||
nsCOMPtr<nsICommandLineRunner> cmdLine
|
||||
(do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
|
||||
NS_ENSURE_TRUE(cmdLine, 1);
|
||||
|
||||
nsCOMPtr<nsIFile> workingDir;
|
||||
rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(workingDir));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
rv = cmdLine->Init(gArgc, gArgv,
|
||||
workingDir, nsICommandLine::STATE_INITIAL_LAUNCH);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
/* Special-case services that need early access to the command
|
||||
line. */
|
||||
nsCOMPtr<nsIObserver> chromeObserver
|
||||
(do_GetService("@mozilla.org/chrome/chrome-registry;1"));
|
||||
if (chromeObserver) {
|
||||
chromeObserver->Observe(cmdLine, "command-line-startup", nsnull);
|
||||
}
|
||||
|
||||
NS_TIMELINE_ENTER("appStartup->CreateHiddenWindow");
|
||||
rv = appStartup->CreateHiddenWindow();
|
||||
NS_TIMELINE_LEAVE("appStartup->CreateHiddenWindow");
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
// Extension Compatibility Checking and Startup
|
||||
if (gAppData->flags & NS_XRE_ENABLE_EXTENSION_MANAGER) {
|
||||
nsCOMPtr<nsIExtensionManager> em(do_GetService("@mozilla.org/extensions/manager;1"));
|
||||
NS_ENSURE_TRUE(em, 1);
|
||||
|
||||
if (CheckArg("install-global-extension") || CheckArg("install-global-theme")) {
|
||||
// Do the required processing and then shut down.
|
||||
em->HandleCommandLineArgs(cmdLine);
|
||||
return 0;
|
||||
// Profile Migration
|
||||
if (gAppData->flags & NS_XRE_ENABLE_PROFILE_MIGRATOR && gDoMigration) {
|
||||
gDoMigration = PR_FALSE;
|
||||
nsCOMPtr<nsIProfileMigrator> pm
|
||||
(do_CreateInstance(NS_PROFILEMIGRATOR_CONTRACTID));
|
||||
if (pm)
|
||||
pm->Migrate(&dirProvider);
|
||||
}
|
||||
dirProvider.DoStartup();
|
||||
|
||||
if (upgraded) {
|
||||
rv = em->CheckForMismatches(&needsRestart);
|
||||
if (NS_FAILED(rv)) {
|
||||
needsRestart = PR_FALSE;
|
||||
upgraded = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!upgraded || !needsRestart)
|
||||
em->Start(cmdLine, &needsRestart);
|
||||
}
|
||||
|
||||
// We want to restart no more than 2 times. The first restart,
|
||||
// NO_EM_RESTART == "0" , and the second time, "1".
|
||||
char* noEMRestart = PR_GetEnv("NO_EM_RESTART");
|
||||
if (noEMRestart && *noEMRestart && *noEMRestart == '1') {
|
||||
if (upgraded || needsRestart) {
|
||||
NS_WARNING("EM tried to force us to restart twice! Forcefully preventing that.");
|
||||
}
|
||||
needsRestart = upgraded = PR_FALSE;
|
||||
}
|
||||
|
||||
if (!upgraded && !needsRestart) {
|
||||
SaveStateForAppInitiatedRestart();
|
||||
|
||||
// clear out any environment variables which may have been set
|
||||
// during the relaunch process now that we know we won't be relaunching.
|
||||
PR_SetEnv("XRE_PROFILE_PATH=");
|
||||
PR_SetEnv("XRE_PROFILE_LOCAL_PATH=");
|
||||
PR_SetEnv("XRE_START_OFFLINE=");
|
||||
PR_SetEnv("XRE_IMPORT_PROFILES=");
|
||||
PR_SetEnv("NO_EM_RESTART=");
|
||||
PR_SetEnv("XUL_APP_FILE=");
|
||||
PR_SetEnv("XRE_BINARY_PATH=");
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// we re-initialize the command-line service and do appleevents munging
|
||||
// after we are sure that we're not restarting
|
||||
cmdLine = do_CreateInstance("@mozilla.org/toolkit/command-line;1");
|
||||
nsCOMPtr<nsICommandLineRunner> cmdLine
|
||||
(do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
|
||||
NS_ENSURE_TRUE(cmdLine, 1);
|
||||
|
||||
rv = InitializeMacCommandLine(gArgc, gArgv);
|
||||
nsCOMPtr<nsIFile> workingDir;
|
||||
rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(workingDir));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
rv = cmdLine->Init(gArgc, gArgv,
|
||||
workingDir, nsICommandLine::STATE_INITIAL_LAUNCH);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
#endif
|
||||
nsCOMPtr<nsIObserverService> obsService
|
||||
(do_GetService("@mozilla.org/observer-service;1"));
|
||||
if (obsService)
|
||||
obsService->NotifyObservers(nsnull, "final-ui-startup", nsnull);
|
||||
|
||||
rv = cmdLine->Run();
|
||||
NS_ENSURE_SUCCESS_LOG(rv, 1);
|
||||
/* Special-case services that need early access to the command
|
||||
line. */
|
||||
nsCOMPtr<nsIObserver> chromeObserver
|
||||
(do_GetService("@mozilla.org/chrome/chrome-registry;1"));
|
||||
if (chromeObserver) {
|
||||
chromeObserver->Observe(cmdLine, "command-line-startup", nsnull);
|
||||
}
|
||||
|
||||
NS_TIMELINE_ENTER("appStartup->CreateHiddenWindow");
|
||||
rv = appStartup->CreateHiddenWindow();
|
||||
NS_TIMELINE_LEAVE("appStartup->CreateHiddenWindow");
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
// Extension Compatibility Checking and Startup
|
||||
if (gAppData->flags & NS_XRE_ENABLE_EXTENSION_MANAGER) {
|
||||
nsCOMPtr<nsIExtensionManager> em(do_GetService("@mozilla.org/extensions/manager;1"));
|
||||
NS_ENSURE_TRUE(em, 1);
|
||||
|
||||
if (CheckArg("install-global-extension") || CheckArg("install-global-theme")) {
|
||||
// Do the required processing and then shut down.
|
||||
em->HandleCommandLineArgs(cmdLine);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (upgraded) {
|
||||
rv = em->CheckForMismatches(&needsRestart);
|
||||
if (NS_FAILED(rv)) {
|
||||
needsRestart = PR_FALSE;
|
||||
upgraded = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!upgraded || !needsRestart)
|
||||
em->Start(cmdLine, &needsRestart);
|
||||
}
|
||||
|
||||
// We want to restart no more than 2 times. The first restart,
|
||||
// NO_EM_RESTART == "0" , and the second time, "1".
|
||||
char* noEMRestart = PR_GetEnv("NO_EM_RESTART");
|
||||
if (noEMRestart && *noEMRestart && *noEMRestart == '1') {
|
||||
if (upgraded || needsRestart) {
|
||||
NS_WARNING("EM tried to force us to restart twice! Forcefully preventing that.");
|
||||
}
|
||||
needsRestart = upgraded = PR_FALSE;
|
||||
}
|
||||
|
||||
if (!upgraded && !needsRestart) {
|
||||
SaveStateForAppInitiatedRestart();
|
||||
|
||||
// clear out any environment variables which may have been set
|
||||
// during the relaunch process now that we know we won't be relaunching.
|
||||
PR_SetEnv("XRE_PROFILE_PATH=");
|
||||
PR_SetEnv("XRE_PROFILE_LOCAL_PATH=");
|
||||
PR_SetEnv("XRE_START_OFFLINE=");
|
||||
PR_SetEnv("XRE_IMPORT_PROFILES=");
|
||||
PR_SetEnv("NO_EM_RESTART=");
|
||||
PR_SetEnv("XUL_APP_FILE=");
|
||||
PR_SetEnv("XRE_BINARY_PATH=");
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// we re-initialize the command-line service and do appleevents munging
|
||||
// after we are sure that we're not restarting
|
||||
cmdLine = do_CreateInstance("@mozilla.org/toolkit/command-line;1");
|
||||
NS_ENSURE_TRUE(cmdLine, 1);
|
||||
|
||||
rv = InitializeMacCommandLine(gArgc, gArgv);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
rv = cmdLine->Init(gArgc, gArgv,
|
||||
workingDir, nsICommandLine::STATE_INITIAL_LAUNCH);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
#endif
|
||||
nsCOMPtr<nsIObserverService> obsService
|
||||
(do_GetService("@mozilla.org/observer-service;1"));
|
||||
if (obsService)
|
||||
obsService->NotifyObservers(nsnull, "final-ui-startup", nsnull);
|
||||
|
||||
rv = cmdLine->Run();
|
||||
NS_ENSURE_SUCCESS_LOG(rv, 1);
|
||||
|
||||
#ifdef MOZ_ENABLE_XREMOTE
|
||||
// if we have X remote support, start listening for requests on the
|
||||
// proxy window.
|
||||
nsCOMPtr<nsIRemoteService> remoteService;
|
||||
remoteService = do_GetService("@mozilla.org/toolkit/remote-service;1");
|
||||
if (remoteService)
|
||||
remoteService->Startup(gAppData->name, nsnull);
|
||||
// if we have X remote support, start listening for requests on the
|
||||
// proxy window.
|
||||
nsCOMPtr<nsIRemoteService> remoteService;
|
||||
remoteService = do_GetService("@mozilla.org/toolkit/remote-service;1");
|
||||
if (remoteService)
|
||||
remoteService->Startup(gAppData->name, nsnull);
|
||||
#endif /* MOZ_ENABLE_XREMOTE */
|
||||
|
||||
// enable win32 DDE responses and Mac appleevents responses
|
||||
nativeApp->Enable();
|
||||
// enable win32 DDE responses and Mac appleevents responses
|
||||
nativeApp->Enable();
|
||||
|
||||
NS_TIMELINE_ENTER("appStartup->Run");
|
||||
rv = appStartup->Run();
|
||||
NS_TIMELINE_LEAVE("appStartup->Run");
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("failed to run appstartup");
|
||||
gLogConsoleErrors = PR_TRUE;
|
||||
}
|
||||
NS_TIMELINE_ENTER("appStartup->Run");
|
||||
rv = appStartup->Run();
|
||||
NS_TIMELINE_LEAVE("appStartup->Run");
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("failed to run appstartup");
|
||||
gLogConsoleErrors = PR_TRUE;
|
||||
}
|
||||
|
||||
// Check for an application initiated restart. This is one that
|
||||
// corresponds to nsIAppStartup.quit(eRestart)
|
||||
if (rv == NS_SUCCESS_RESTART_APP) {
|
||||
needsRestart = PR_TRUE;
|
||||
appInitiatedRestart = PR_TRUE;
|
||||
}
|
||||
// Check for an application initiated restart. This is one that
|
||||
// corresponds to nsIAppStartup.quit(eRestart)
|
||||
if (rv == NS_SUCCESS_RESTART_APP) {
|
||||
needsRestart = PR_TRUE;
|
||||
appInitiatedRestart = PR_TRUE;
|
||||
}
|
||||
|
||||
#ifdef MOZ_ENABLE_XREMOTE
|
||||
// shut down the x remote proxy window
|
||||
if (remoteService)
|
||||
remoteService->Shutdown();
|
||||
// shut down the x remote proxy window
|
||||
if (remoteService)
|
||||
remoteService->Shutdown();
|
||||
#endif /* MOZ_ENABLE_XREMOTE */
|
||||
|
||||
#ifdef MOZ_TIMELINE
|
||||
// Make sure we print this out even if timeline is runtime disabled
|
||||
if (NS_FAILED(NS_TIMELINE_LEAVE("main1")))
|
||||
NS_TimelineForceMark("...main1");
|
||||
// Make sure we print this out even if timeline is runtime disabled
|
||||
if (NS_FAILED(NS_TIMELINE_LEAVE("main1")))
|
||||
NS_TimelineForceMark("...main1");
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
// Upgrade condition (build id changes), but the restart hint was
|
||||
// not set by the Extension Manager. This is because the compatibility
|
||||
// resolution for Extensions is different than for the component
|
||||
// registry - major milestone vs. build id.
|
||||
needsRestart = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
profileLock->Unlock();
|
||||
}
|
||||
|
||||
// Restart the app after XPCOM has been shut down cleanly.
|
||||
if (needsRestart) {
|
||||
if (appInitiatedRestart) {
|
||||
RestoreStateForAppInitiatedRestart();
|
||||
}
|
||||
else {
|
||||
// Upgrade condition (build id changes), but the restart hint was
|
||||
// not set by the Extension Manager. This is because the compatibility
|
||||
// resolution for Extensions is different than for the component
|
||||
// registry - major milestone vs. build id.
|
||||
needsRestart = PR_TRUE;
|
||||
char* noEMRestart = PR_GetEnv("NO_EM_RESTART");
|
||||
if (noEMRestart && *noEMRestart) {
|
||||
PR_SetEnv("NO_EM_RESTART=1");
|
||||
}
|
||||
else {
|
||||
PR_SetEnv("NO_EM_RESTART=0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
profileLock->Unlock();
|
||||
}
|
||||
|
||||
// Restart the app after XPCOM has been shut down cleanly.
|
||||
if (needsRestart) {
|
||||
if (appInitiatedRestart) {
|
||||
RestoreStateForAppInitiatedRestart();
|
||||
}
|
||||
else {
|
||||
char* noEMRestart = PR_GetEnv("NO_EM_RESTART");
|
||||
if (noEMRestart && *noEMRestart) {
|
||||
PR_SetEnv("NO_EM_RESTART=1");
|
||||
}
|
||||
else {
|
||||
PR_SetEnv("NO_EM_RESTART=0");
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that these environment variables are set:
|
||||
SaveFileToEnvIfUnset("XRE_PROFILE_PATH", profD);
|
||||
SaveFileToEnvIfUnset("XRE_PROFILE_LOCAL_PATH", profLD);
|
||||
// Ensure that these environment variables are set:
|
||||
SaveFileToEnvIfUnset("XRE_PROFILE_PATH", profD);
|
||||
SaveFileToEnvIfUnset("XRE_PROFILE_LOCAL_PATH", profLD);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (gBinaryPath) {
|
||||
static char kEnvVar[MAXPATHLEN];
|
||||
sprintf(kEnvVar, "XRE_BINARY_PATH=%s", gBinaryPath);
|
||||
PR_SetEnv(kEnvVar);
|
||||
}
|
||||
if (gBinaryPath) {
|
||||
static char kEnvVar[MAXPATHLEN];
|
||||
sprintf(kEnvVar, "XRE_BINARY_PATH=%s", gBinaryPath);
|
||||
PR_SetEnv(kEnvVar);
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = LaunchChild(nativeApp, appInitiatedRestart);
|
||||
return rv == NS_ERROR_LAUNCHED_CHILD_PROCESS ? 0 : 1;
|
||||
rv = LaunchChild(nativeApp, appInitiatedRestart);
|
||||
return rv == NS_ERROR_LAUNCHED_CHILD_PROCESS ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
NS_LogTerm();
|
||||
|
||||
return NS_FAILED(rv) ? 1 : 0;
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
* Contributor(s):
|
||||
* IBM Corp.
|
||||
* Henry Sobotka
|
||||
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -46,6 +47,7 @@
|
||||
#include "nsError.h"
|
||||
#include "prerror.h"
|
||||
#include "prerr.h"
|
||||
#include "prenv.h"
|
||||
|
||||
#if defined(XP_BEOS)
|
||||
/* For DEBUGGER macros */
|
||||
@ -57,42 +59,33 @@
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX) && !defined(UNIX_CRASH_ON_ASSERT)
|
||||
#include <signal.h>
|
||||
/* for nsTraceRefcnt::WalkTheStack() */
|
||||
#include "nsISupportsUtils.h"
|
||||
#include "nsTraceRefcntImpl.h"
|
||||
#include "nsISupportsUtils.h"
|
||||
|
||||
#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64__))
|
||||
# define DebugBreak() { asm("int $3"); }
|
||||
#elif defined(__APPLE__) && defined(TARGET_CARBON)
|
||||
# include "MacTypes.h"
|
||||
# define DebugBreak() { Debugger(); }
|
||||
#else
|
||||
# define DebugBreak()
|
||||
#if defined(XP_UNIX)
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
static void
|
||||
Abort(const char *aMsg);
|
||||
|
||||
static void
|
||||
Break(const char *aMsg);
|
||||
|
||||
#if defined(__APPLE__) && defined(TARGET_CARBON)
|
||||
# include "MacTypes.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_OS2)
|
||||
/* Added definitions for DebugBreak() for 2 different OS/2 compilers. Doing
|
||||
* the int3 on purpose so that a developer can step over the
|
||||
* instruction if so desired. Not always possible if trapping due to exception
|
||||
* handling IBM-AKR
|
||||
*/
|
||||
#define INCL_WINDIALOGS // need for WinMessageBox
|
||||
#include <os2.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define DebugBreak() { asm("int $3"); }
|
||||
#else
|
||||
#define DebugBreak()
|
||||
#endif /* DEBUG */
|
||||
# define INCL_WINDIALOGS // need for WinMessageBox
|
||||
# include <os2.h>
|
||||
# include <string.h>
|
||||
#endif /* XP_OS2 */
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <signal.h>
|
||||
#include <malloc.h> // for _alloca
|
||||
#elif defined(XP_UNIX)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
@ -129,10 +122,47 @@ PRBool InDebugger()
|
||||
|
||||
#endif /* WIN32*/
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsDebugImpl, nsIDebug)
|
||||
NS_IMPL_QUERY_INTERFACE1(nsDebugImpl, nsIDebug)
|
||||
|
||||
nsDebugImpl::nsDebugImpl()
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsDebugImpl::AddRef()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsDebugImpl::Release()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDebugImpl::Assertion(const char *aStr, const char *aExpr,
|
||||
const char *aFile, PRInt32 aLine)
|
||||
{
|
||||
NS_DebugBreak(NS_DEBUG_ASSERTION, aStr, aExpr, aFile, aLine);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDebugImpl::Warning(const char *aStr, const char *aFile, PRInt32 aLine)
|
||||
{
|
||||
NS_DebugBreak(NS_DEBUG_WARNING, aStr, nsnull, aFile, aLine);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDebugImpl::Break(const char *aFile, PRInt32 aLine)
|
||||
{
|
||||
NS_DebugBreak(NS_DEBUG_BREAK, nsnull, nsnull, aFile, aLine);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDebugImpl::Abort(const char *aFile, PRInt32 aLine)
|
||||
{
|
||||
NS_DebugBreak(NS_DEBUG_ABORT, nsnull, nsnull, aFile, aLine);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,275 +180,296 @@ static void InitLog(void)
|
||||
}
|
||||
}
|
||||
|
||||
enum nsAssertBehavior {
|
||||
NS_ASSERT_UNINITIALIZED,
|
||||
NS_ASSSERT_WARN,
|
||||
NS_ASSSERT_SUSPEND,
|
||||
NS_ASSSERT_STACK,
|
||||
NS_ASSSERT_TRAP,
|
||||
NS_ASSSERT_ABORT
|
||||
};
|
||||
|
||||
static nsAssertBehavior GetAssertBehavior()
|
||||
{
|
||||
static nsAssertBehavior gAssertBehavior = NS_ASSERT_UNINITIALIZED;
|
||||
if (gAssertBehavior != NS_ASSERT_UNINITIALIZED)
|
||||
return gAssertBehavior;
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDebugImpl::Assertion(const char *aStr, const char *aExpr, const char *aFile, PRInt32 aLine)
|
||||
#if defined(XP_WIN) || defined(XP_OS2)
|
||||
gAssertBehavior = NS_ASSSERT_TRAP;
|
||||
#else
|
||||
gAssertBehavior = NS_ASSSERT_WARN;
|
||||
#endif
|
||||
|
||||
const char *assertString = PR_GetEnv("XPCOM_DEBUG_BREAK");
|
||||
if (!assertString || !*assertString)
|
||||
return gAssertBehavior;
|
||||
|
||||
if (!strcmp(assertString, "warn"))
|
||||
return gAssertBehavior = NS_ASSSERT_WARN;
|
||||
|
||||
if (!strcmp(assertString, "suspend"))
|
||||
return gAssertBehavior = NS_ASSSERT_SUSPEND;
|
||||
|
||||
if (!strcmp(assertString, "stack"))
|
||||
return gAssertBehavior = NS_ASSSERT_STACK;
|
||||
|
||||
if (!strcmp(assertString, "abort"))
|
||||
return gAssertBehavior = NS_ASSSERT_ABORT;
|
||||
|
||||
if (!strcmp(assertString, "trap") || !strcmp(assertString, "break"))
|
||||
return gAssertBehavior = NS_ASSSERT_TRAP;
|
||||
|
||||
fprintf(stderr, "Unrecognized value of XPCOM_DEBUG_BREAK\n");
|
||||
return gAssertBehavior;
|
||||
}
|
||||
|
||||
struct FixedBuffer
|
||||
{
|
||||
FixedBuffer() : curlen(0) { buffer[0] = '\0'; }
|
||||
|
||||
char buffer[1000];
|
||||
PRUint32 curlen;
|
||||
};
|
||||
|
||||
static PRIntn
|
||||
StuffFixedBuffer(void *closure, const char *buf, PRUint32 len)
|
||||
{
|
||||
FixedBuffer *fb = (FixedBuffer*) closure;
|
||||
|
||||
// strip the trailing null, we add it again later
|
||||
if (buf[len - 1] == '\0')
|
||||
--len;
|
||||
|
||||
if (fb->curlen + len >= sizeof(fb->buffer))
|
||||
len = sizeof(fb->buffer) - fb->curlen - 1;
|
||||
|
||||
if (len) {
|
||||
memcpy(fb->buffer + fb->curlen, buf, len);
|
||||
fb->curlen += len;
|
||||
fb->buffer[fb->curlen] = '\0';
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_DebugBreak(PRUint32 aSeverity, const char *aStr, const char *aExpr,
|
||||
const char *aFile, PRInt32 aLine)
|
||||
{
|
||||
InitLog();
|
||||
|
||||
char buf[1000];
|
||||
PR_snprintf(buf, sizeof(buf),
|
||||
"###!!! ASSERTION: %s: '%s', file %s, line %d",
|
||||
aStr, aExpr, aFile, aLine);
|
||||
FixedBuffer buf;
|
||||
PRLogModuleLevel ll = PR_LOG_WARNING;
|
||||
const char *sevString = "WARNING";
|
||||
|
||||
switch (aSeverity) {
|
||||
case NS_DEBUG_ASSERTION:
|
||||
sevString = "\07###!!! ASSERTION";
|
||||
ll = PR_LOG_ERROR;
|
||||
break;
|
||||
|
||||
case NS_DEBUG_BREAK:
|
||||
sevString = "\07###!!! BREAK";
|
||||
ll = PR_LOG_ALWAYS;
|
||||
break;
|
||||
|
||||
case NS_DEBUG_ABORT:
|
||||
sevString = "\07###!!! ABORT";
|
||||
ll = PR_LOG_ALWAYS;
|
||||
break;
|
||||
|
||||
default:
|
||||
aSeverity = NS_DEBUG_WARNING;
|
||||
};
|
||||
|
||||
PR_sxprintf(StuffFixedBuffer, &buf, "%s: ", sevString);
|
||||
|
||||
if (aStr)
|
||||
PR_sxprintf(StuffFixedBuffer, &buf, "%s: ", aStr);
|
||||
|
||||
if (aExpr)
|
||||
PR_sxprintf(StuffFixedBuffer, &buf, "'%s', ", aExpr);
|
||||
|
||||
if (aFile)
|
||||
PR_sxprintf(StuffFixedBuffer, &buf, "file %s, ", aFile);
|
||||
|
||||
if (aLine != -1)
|
||||
PR_sxprintf(StuffFixedBuffer, &buf, "line %d", aLine);
|
||||
|
||||
// Write out the assertion message to the debug log
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR, ("%s", buf));
|
||||
PR_LOG(gDebugLog, ll, ("%s", buf.buffer));
|
||||
PR_LogFlush();
|
||||
|
||||
// And write it out to the stderr
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
fprintf(stderr, "%s\n", buf.buffer);
|
||||
fflush(stderr);
|
||||
|
||||
#if defined(_WIN32)
|
||||
char* assertBehavior = getenv("XPCOM_DEBUG_BREAK");
|
||||
if (assertBehavior && strcmp(assertBehavior, "warn") == 0)
|
||||
return NS_OK;
|
||||
switch (aSeverity) {
|
||||
case NS_DEBUG_WARNING:
|
||||
return;
|
||||
|
||||
#ifndef WINCE // we really just want to crash for now
|
||||
static int ignoreDebugger;
|
||||
if (!ignoreDebugger) {
|
||||
const char *shouldIgnoreDebugger = getenv("XPCOM_DEBUG_DLG");
|
||||
ignoreDebugger = 1 + (shouldIgnoreDebugger && !strcmp(shouldIgnoreDebugger, "1"));
|
||||
case NS_DEBUG_BREAK:
|
||||
Break(buf.buffer);
|
||||
return;
|
||||
|
||||
case NS_DEBUG_ABORT:
|
||||
Abort(buf.buffer);
|
||||
return;
|
||||
}
|
||||
if((ignoreDebugger == 2) || !InDebugger())
|
||||
{
|
||||
DWORD code = IDRETRY;
|
||||
|
||||
/* Create the debug dialog out of process to avoid the crashes caused by
|
||||
* Windows events leaking into our event loop from an in process dialog.
|
||||
* We do this by launching windbgdlg.exe (built in xpcom/windbgdlg).
|
||||
* See http://bugzilla.mozilla.org/show_bug.cgi?id=54792
|
||||
*/
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFO si;
|
||||
char executable[MAX_PATH];
|
||||
char* pName;
|
||||
// Now we deal with assertions
|
||||
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
switch (GetAssertBehavior()) {
|
||||
case NS_ASSSERT_WARN:
|
||||
return;
|
||||
|
||||
memset(&si, 0, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
si.wShowWindow = SW_SHOW;
|
||||
|
||||
if(GetModuleFileName(GetModuleHandle("xpcom.dll"), executable, MAX_PATH) &&
|
||||
NULL != (pName = strrchr(executable, '\\')) &&
|
||||
NULL != strcpy(pName+1, "windbgdlg.exe") &&
|
||||
#ifdef DEBUG_jband
|
||||
(printf("Launching %s\n", executable), PR_TRUE) &&
|
||||
#endif
|
||||
CreateProcess(executable, buf, NULL, NULL, PR_FALSE,
|
||||
DETACHED_PROCESS | NORMAL_PRIORITY_CLASS,
|
||||
NULL, NULL, &si, &pi) &&
|
||||
WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, INFINITE) &&
|
||||
GetExitCodeProcess(pi.hProcess, &code))
|
||||
{
|
||||
CloseHandle(pi.hProcess);
|
||||
}
|
||||
|
||||
switch(code)
|
||||
{
|
||||
case IDABORT:
|
||||
//This should exit us
|
||||
raise(SIGABRT);
|
||||
//If we are ignored exit this way..
|
||||
_exit(3);
|
||||
break;
|
||||
|
||||
case IDIGNORE:
|
||||
return NS_OK;
|
||||
// Fall Through
|
||||
}
|
||||
}
|
||||
#endif // WINCE
|
||||
#endif
|
||||
|
||||
#if defined(XP_OS2)
|
||||
char* assertBehavior = getenv("XPCOM_DEBUG_BREAK");
|
||||
if (assertBehavior && strcmp(assertBehavior, "warn") == 0)
|
||||
return NS_OK;
|
||||
|
||||
char msg[1200];
|
||||
PR_snprintf(msg, sizeof(msg),
|
||||
"%s\n\nClick Cancel to Debug Application.\n"
|
||||
"Click Enter to continue running the Application.", buf);
|
||||
ULONG code = MBID_ERROR;
|
||||
code = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg,
|
||||
"NSGlue_Assertion", 0,
|
||||
MB_ERROR | MB_ENTERCANCEL);
|
||||
|
||||
/* It is possible that we are executing on a thread that doesn't have a
|
||||
* message queue. In that case, the message won't appear, and code will
|
||||
* be 0xFFFF. We'll give the user a chance to debug it by calling
|
||||
* Break()
|
||||
* Actually, that's a really bad idea since this happens a lot with threadsafe
|
||||
* assertions and since it means that you can't actually run the debug build
|
||||
* outside a debugger without it crashing constantly.
|
||||
*/
|
||||
if(( code == MBID_ENTER ) || (code == MBID_ERROR))
|
||||
{
|
||||
return NS_OK;
|
||||
// If Retry, Fall Through
|
||||
}
|
||||
#endif
|
||||
|
||||
Break(aFile, aLine);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDebugImpl::Break(const char *aFile, PRInt32 aLine)
|
||||
{
|
||||
#ifndef TEMP_MAC_HACK
|
||||
// Write out the assertion message to the debug log
|
||||
InitLog();
|
||||
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR,
|
||||
("###!!! Break: at file %s, line %d", aFile, aLine));
|
||||
PR_LogFlush();
|
||||
|
||||
fprintf(stderr, "Break: at file %s, line %d\n",aFile, aLine); fflush(stderr);
|
||||
fflush(stderr);
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifdef _M_IX86
|
||||
::DebugBreak();
|
||||
#endif
|
||||
#elif defined(XP_UNIX) && !defined(UNIX_CRASH_ON_ASSERT)
|
||||
fprintf(stderr, "\07");
|
||||
|
||||
char *assertBehavior = getenv("XPCOM_DEBUG_BREAK");
|
||||
|
||||
if (!assertBehavior) {
|
||||
|
||||
// the default; nothing else to do
|
||||
;
|
||||
|
||||
} else if ( strcmp(assertBehavior, "suspend")== 0 ) {
|
||||
|
||||
// the suspend case is first because we wanna send the signal before
|
||||
// other threads have had a chance to get too far from the state that
|
||||
// caused this assertion (in case they happen to have been involved).
|
||||
//
|
||||
case NS_ASSSERT_SUSPEND:
|
||||
#ifdef XP_UNIX
|
||||
fprintf(stderr, "Suspending process; attach with the debugger.\n");
|
||||
kill(0, SIGSTOP);
|
||||
|
||||
} else if ( strcmp(assertBehavior, "warn")==0 ) {
|
||||
|
||||
// same as default; nothing else to do (see "suspend" case comment for
|
||||
// why this compare isn't done as part of the default case)
|
||||
//
|
||||
;
|
||||
|
||||
}
|
||||
else if ( strcmp(assertBehavior,"stack")==0 ) {
|
||||
|
||||
// walk the stack
|
||||
//
|
||||
nsTraceRefcntImpl::WalkTheStack(stderr);
|
||||
}
|
||||
else if ( strcmp(assertBehavior,"abort")==0 ) {
|
||||
|
||||
// same as UNIX_CRASH_ON_ASSERT
|
||||
//
|
||||
Abort(aFile, aLine);
|
||||
|
||||
} else if ( strcmp(assertBehavior,"trap")==0 ) {
|
||||
|
||||
DebugBreak();
|
||||
|
||||
} else {
|
||||
|
||||
fprintf(stderr, "unrecognized value of XPCOM_DEBUG_BREAK env var!\n");
|
||||
|
||||
}
|
||||
fflush(stderr); // this shouldn't really be necessary, i don't think,
|
||||
// but maybe there's some lame stdio that buffers stderr
|
||||
|
||||
#elif defined(XP_BEOS)
|
||||
{
|
||||
#ifdef UNIX_CRASH_ON_ASSERT
|
||||
char buf[2000];
|
||||
sprintf(buf, "Break: at file %s, line %d", aFile, aLine);
|
||||
DEBUGGER(buf);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
Abort(aFile, aLine);
|
||||
Break(buf.buffer);
|
||||
#endif
|
||||
#endif // TEMP_MAC_HACK
|
||||
return NS_OK;
|
||||
return;
|
||||
|
||||
case NS_ASSSERT_STACK:
|
||||
nsTraceRefcntImpl::WalkTheStack(stderr);
|
||||
return;
|
||||
|
||||
case NS_ASSSERT_ABORT:
|
||||
Abort(buf.buffer);
|
||||
return;
|
||||
|
||||
case NS_ASSSERT_TRAP:
|
||||
Break(buf.buffer);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDebugImpl::Abort(const char *aFile, PRInt32 aLine)
|
||||
static void
|
||||
Abort(const char *aMsg)
|
||||
{
|
||||
InitLog();
|
||||
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR,
|
||||
("###!!! Abort: at file %s, line %d", aFile, aLine));
|
||||
PR_LogFlush();
|
||||
fprintf(stderr, "\07 Abort\n"); fflush(stderr);
|
||||
fflush(stderr);
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifdef _M_IX86
|
||||
long* __p = (long*) 0x7;
|
||||
*__p = 0x7;
|
||||
#else /* _M_ALPHA */
|
||||
PR_Abort();
|
||||
#endif
|
||||
//This should exit us
|
||||
raise(SIGABRT);
|
||||
//If we are ignored exit this way..
|
||||
_exit(3);
|
||||
#elif defined(XP_UNIX)
|
||||
PR_Abort();
|
||||
#elif defined(XP_OS2)
|
||||
DebugBreak();
|
||||
return NS_OK;
|
||||
#elif defined(XP_BEOS)
|
||||
{
|
||||
#ifndef DEBUG_cls
|
||||
char buf[2000];
|
||||
sprintf(buf, "Abort: at file %s, line %d", aFile, aLine);
|
||||
DEBUGGER(buf);
|
||||
DEBUGGER(aMsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Don't know how to abort on this platform! call Break() instead
|
||||
Break(aMsg);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDebugImpl::Warning(const char* aMessage,
|
||||
const char* aFile, PRIntn aLine)
|
||||
// Abort() calls this function, don't call it!
|
||||
static void
|
||||
Break(const char *aMsg)
|
||||
{
|
||||
InitLog();
|
||||
#if defined(_WIN32)
|
||||
#ifndef WINCE // we really just want to crash for now
|
||||
static int ignoreDebugger;
|
||||
if (!ignoreDebugger) {
|
||||
const char *shouldIgnoreDebugger = getenv("XPCOM_DEBUG_DLG");
|
||||
ignoreDebugger = 1 + (shouldIgnoreDebugger && !strcmp(shouldIgnoreDebugger, "1"));
|
||||
}
|
||||
if((ignoreDebugger == 2) || !InDebugger()) {
|
||||
DWORD code = IDRETRY;
|
||||
|
||||
char buf[1000];
|
||||
PR_snprintf(buf, sizeof(buf),
|
||||
"WARNING: %s, file %s, line %d",
|
||||
aMessage, aFile, aLine);
|
||||
/* Create the debug dialog out of process to avoid the crashes caused by
|
||||
* Windows events leaking into our event loop from an in process dialog.
|
||||
* We do this by launching windbgdlg.exe (built in xpcom/windbgdlg).
|
||||
* See http://bugzilla.mozilla.org/show_bug.cgi?id=54792
|
||||
*/
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFO si;
|
||||
char executable[MAX_PATH];
|
||||
char* pName;
|
||||
|
||||
// Write out the warning message to the debug log
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR, ("%s", buf));
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
|
||||
// And write it out to the stdout
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
fflush(stderr);
|
||||
return NS_OK;
|
||||
memset(&si, 0, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
si.wShowWindow = SW_SHOW;
|
||||
|
||||
// 2nd arg of CreateProcess is in/out
|
||||
char *msgCopy = (char*) _alloca(strlen(aMsg) + 1);
|
||||
strcpy(msgCopy, aMsg);
|
||||
|
||||
if(GetModuleFileName(GetModuleHandle("xpcom.dll"), executable, MAX_PATH) &&
|
||||
NULL != (pName = strrchr(executable, '\\')) &&
|
||||
NULL != strcpy(pName+1, "windbgdlg.exe") &&
|
||||
CreateProcess(executable, msgCopy, NULL, NULL, PR_FALSE,
|
||||
DETACHED_PROCESS | NORMAL_PRIORITY_CLASS,
|
||||
NULL, NULL, &si, &pi) &&
|
||||
WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, INFINITE) &&
|
||||
GetExitCodeProcess(pi.hProcess, &code)) {
|
||||
CloseHandle(pi.hProcess);
|
||||
}
|
||||
|
||||
switch(code) {
|
||||
case IDABORT:
|
||||
//This should exit us
|
||||
raise(SIGABRT);
|
||||
//If we are ignored exit this way..
|
||||
_exit(3);
|
||||
|
||||
case IDIGNORE:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
::DebugBreak();
|
||||
|
||||
#endif // WINCE
|
||||
#elif defined(XP_OS2)
|
||||
char msg[1200];
|
||||
PR_snprintf(msg, sizeof(msg),
|
||||
"%s\n\nClick Cancel to Debug Application.\n"
|
||||
"Click Enter to continue running the Application.", aMsg);
|
||||
ULONG code = MBID_ERROR;
|
||||
code = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg,
|
||||
"NSGlue_Assertion", 0,
|
||||
MB_ERROR | MB_ENTERCANCEL);
|
||||
|
||||
/* It is possible that we are executing on a thread that doesn't have a
|
||||
* message queue. In that case, the message won't appear, and code will
|
||||
* be 0xFFFF. We'll give the user a chance to debug it by calling
|
||||
* Break()
|
||||
* Actually, that's a really bad idea since this happens a lot with threadsafe
|
||||
* assertions and since it means that you can't actually run the debug build
|
||||
* outside a debugger without it crashing constantly.
|
||||
*/
|
||||
if (( code == MBID_ENTER ) || (code == MBID_ERROR))
|
||||
return;
|
||||
|
||||
asm("int $3");
|
||||
#elif defined(XP_BEOS)
|
||||
DEBUGGER(aMgr);
|
||||
#elif defined(__GNUC__) && (defined(__i386) || defined(__x86_64__))
|
||||
asm("int $3");
|
||||
#elif defined(__APPLE__) && defined(TARGET_CARBON)
|
||||
Debugger();
|
||||
#else
|
||||
// don't know how to break on this platform
|
||||
#endif
|
||||
}
|
||||
|
||||
static const nsDebugImpl kImpl;
|
||||
|
||||
NS_METHOD
|
||||
nsDebugImpl::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
|
||||
{
|
||||
*aInstancePtr = nsnull;
|
||||
nsIDebug* debug = new nsDebugImpl();
|
||||
if (!debug)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = debug->QueryInterface(aIID, aInstancePtr);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete debug;
|
||||
}
|
||||
|
||||
return rv;
|
||||
NS_ENSURE_NO_AGGREGATION(outer);
|
||||
|
||||
return NS_CONST_CAST(nsDebugImpl*, &kImpl)->
|
||||
QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -42,11 +42,7 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDEBUG
|
||||
|
||||
nsDebugImpl();
|
||||
static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
|
||||
private:
|
||||
~nsDebugImpl() {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -38,12 +38,8 @@
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* nsIDebug is an interface between XPCOM Glue and XPCOM. Users should access
|
||||
* the nsIDebug interface through the static class nsDebug.
|
||||
* @see nsDebug.h
|
||||
*
|
||||
* @status UNDER_REVIEW
|
||||
*
|
||||
* @status DEPRECATED Replaced by the NS_DebugBreak function.
|
||||
* @status FROZEN
|
||||
*/
|
||||
|
||||
[scriptable, uuid(3bf0c3d7-3bd9-4cf2-a971-33572c503e1e)]
|
||||
|
||||
@ -57,20 +57,6 @@
|
||||
{ 0x00000000, 0x0000, 0x0000, \
|
||||
{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }
|
||||
|
||||
/**
|
||||
* Reference count values
|
||||
*
|
||||
* This is the return type for AddRef() and Release() in nsISupports.
|
||||
* IUnknown of COM returns an unsigned long from equivalent functions.
|
||||
* The following ifdef exists to maintain binary compatibility with
|
||||
* IUnknown.
|
||||
*/
|
||||
#if defined(XP_WIN) && PR_BYTES_PER_LONG == 4
|
||||
typedef unsigned long nsrefcnt;
|
||||
#else
|
||||
typedef PRUint32 nsrefcnt;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Basic component object model interface. Objects which implement
|
||||
* this interface support runtime interface discovery (QueryInterface)
|
||||
|
||||
@ -38,11 +38,10 @@
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* nsITraceRefcnt is an interface between XPCOM Glue and XPCOM. Users should
|
||||
* access the nsITraceRefcnt interface through the static class nsTraceRefcnt.
|
||||
* @see nsTraceRefcnt.h
|
||||
*
|
||||
* @status UNDER_REVIEW
|
||||
* nsITraceRefcnt is an interface between XPCOM Glue and XPCOM.
|
||||
*
|
||||
* @status DEPRECATED Replaced by the NS_Log* functions.
|
||||
* @status FROZEN
|
||||
*/
|
||||
|
||||
[uuid(273dc92f-0fe6-4545-96a9-21be77828039)]
|
||||
|
||||
@ -469,10 +469,10 @@ DumpStackToFile(FILE* aStream)
|
||||
walkerThread = ::CreateThread( NULL, 0, DumpStackToFileThread, (LPVOID) &data, 0, NULL ) ;
|
||||
if (walkerThread) {
|
||||
walkerReturn = ::WaitForSingleObject(walkerThread, 2000); // no timeout is never a good idea
|
||||
CloseHandle(myThread) ;
|
||||
if (walkerReturn != WAIT_OBJECT_0) {
|
||||
PrintError("ThreadWait", aStream);
|
||||
}
|
||||
CloseHandle(myThread);
|
||||
}
|
||||
else {
|
||||
PrintError("ThreadCreate", aStream);
|
||||
|
||||
@ -79,11 +79,13 @@ NS_MeanAndStdDev(double n, double sumOfValues, double sumOfSquaredValues,
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NS_IMPL_REFCNT_LOGGING
|
||||
|
||||
#ifdef WINCE
|
||||
#undef NS_BUILD_REFCNT_LOGGING
|
||||
#undef NS_IMPL_REFCNT_LOGGING
|
||||
#endif
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
#include "plhash.h"
|
||||
#include "prmem.h"
|
||||
|
||||
@ -107,13 +109,22 @@ static PRBool gLogLeaksOnly;
|
||||
static void (*leakyLogAddRef)(void* p, int oldrc, int newrc);
|
||||
static void (*leakyLogRelease)(void* p, int oldrc, int newrc);
|
||||
|
||||
static PRBool gInitialized = PR_FALSE;
|
||||
#define BAD_TLS_INDEX ((PRUintn) -1)
|
||||
|
||||
// if gActivityTLS == BAD_TLS_INDEX, then we're
|
||||
// unitialized... otherwise this points to a NSPR TLS thread index
|
||||
// indicating whether addref activity is legal. If the PTR_TO_INT32 is 0 then
|
||||
// activity is ok, otherwise not!
|
||||
static PRUintn gActivityTLS = BAD_TLS_INDEX;
|
||||
|
||||
static PRBool gInitialized;
|
||||
static nsrefcnt gInitCount;
|
||||
|
||||
static FILE *gBloatLog = nsnull;
|
||||
static FILE *gRefcntsLog = nsnull;
|
||||
static FILE *gAllocLog = nsnull;
|
||||
static FILE *gLeakyLog = nsnull;
|
||||
static FILE *gCOMPtrLog = nsnull;
|
||||
static PRBool gActivityIsLegal = PR_FALSE;
|
||||
|
||||
struct serialNumberRecord {
|
||||
PRInt32 serialNumber;
|
||||
@ -132,15 +143,11 @@ struct nsTraceRefcntStats {
|
||||
double mObjsOutstandingSquared;
|
||||
};
|
||||
|
||||
#ifdef DEBUG_dbaron_off
|
||||
// I hope to turn this on for everybody once we hit it a little less.
|
||||
#define ASSERT_ACTIVITY_IS_LEGAL \
|
||||
NS_WARN_IF_FALSE(gActivityIsLegal, \
|
||||
"XPCOM objects created/destroyed from static ctor/dtor")
|
||||
#else
|
||||
#define ASSERT_ACTIVITY_IS_LEGAL
|
||||
#endif
|
||||
|
||||
#define ASSERT_ACTIVITY_IS_LEGAL \
|
||||
NS_WARN_IF_FALSE(gActivityTLS != BAD_TLS_INDEX && \
|
||||
NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0, \
|
||||
"XPCOM objects created/destroyed from static ctor/dtor");
|
||||
|
||||
// These functions are copied from nsprpub/lib/ds/plhash.c, with changes
|
||||
// to the functions not called Default* to free the serialNumberRecord or
|
||||
@ -445,13 +452,13 @@ static PRIntn PR_CALLBACK DumpSerialNumbers(PLHashEntry* aHashEntry, PRIntn aInd
|
||||
}
|
||||
|
||||
|
||||
#endif /* NS_BUILD_REFCNT_LOGGING */
|
||||
#endif /* NS_IMPL_REFCNT_LOGGING */
|
||||
|
||||
NS_COM nsresult
|
||||
nsTraceRefcntImpl::DumpStatistics(StatisticsType type, FILE* out)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
if (gBloatLog == nsnull || gBloatView == nsnull) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -527,7 +534,7 @@ done:
|
||||
NS_COM void
|
||||
nsTraceRefcntImpl::ResetStatistics()
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
LOCK_TRACELOG();
|
||||
if (gBloatView) {
|
||||
PL_HashTableDestroy(gBloatView);
|
||||
@ -537,7 +544,7 @@ nsTraceRefcntImpl::ResetStatistics()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
static PRBool LogThisType(const char* aTypeName)
|
||||
{
|
||||
void* he = PL_HashTableLookup(gTypesToLog, aTypeName);
|
||||
@ -873,7 +880,7 @@ NS_COM void
|
||||
nsTraceRefcntImpl::LoadLibrarySymbols(const char* aLibraryName,
|
||||
void* aLibrayHandle)
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
#if defined(_WIN32) && defined(_M_IX86) /* Win32 x86 only */
|
||||
if (!gInitialized)
|
||||
InitTraceLog();
|
||||
@ -928,44 +935,37 @@ nsTraceRefcntImpl::LoadLibrarySymbols(const char* aLibraryName,
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// don't use the logging ones. :-)
|
||||
NS_IMETHODIMP_(nsrefcnt) nsTraceRefcntImpl::AddRef(void)
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogInit()
|
||||
{
|
||||
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
|
||||
++mRefCnt;
|
||||
return mRefCnt;
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
if (++gInitCount)
|
||||
nsTraceRefcntImpl::SetActivityIsLegal(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt) nsTraceRefcntImpl::Release(void)
|
||||
{
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||
--mRefCnt;
|
||||
if (mRefCnt == 0) {
|
||||
mRefCnt = 1; /* stabilize */
|
||||
delete this;
|
||||
return 0;
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogTerm()
|
||||
{
|
||||
NS_ASSERTION(gInitCount > 0,
|
||||
"NS_LogTerm without matching NS_LogInit");
|
||||
|
||||
if (--gInitCount == 0) {
|
||||
nsTraceRefcntImpl::DumpStatistics();
|
||||
nsTraceRefcntImpl::ResetStatistics();
|
||||
nsTraceRefcntImpl::Shutdown();
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
nsTraceRefcntImpl::SetActivityIsLegal(PR_FALSE);
|
||||
gActivityTLS = BAD_TLS_INDEX;
|
||||
#endif
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE1(nsTraceRefcntImpl, nsITraceRefcnt)
|
||||
|
||||
nsTraceRefcntImpl::nsTraceRefcntImpl()
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogAddRef(void* aPtr, nsrefcnt aRefcnt,
|
||||
const char* aClazz, PRUint32 classSize)
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogAddRef(void* aPtr,
|
||||
nsrefcnt aRefcnt,
|
||||
const char* aClazz,
|
||||
PRUint32 classSize)
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
ASSERT_ACTIVITY_IS_LEGAL;
|
||||
if (!gInitialized)
|
||||
InitTraceLog();
|
||||
@ -996,7 +996,7 @@ nsTraceRefcntImpl::LogAddRef(void* aPtr,
|
||||
if (aRefcnt == 1 && gAllocLog && loggingThisType && loggingThisObject) {
|
||||
fprintf(gAllocLog, "\n<%s> 0x%08X %d Create\n",
|
||||
aClazz, NS_PTR_TO_INT32(aPtr), serialno);
|
||||
WalkTheStack(gAllocLog);
|
||||
nsTraceRefcntImpl::WalkTheStack(gAllocLog);
|
||||
}
|
||||
|
||||
if (gRefcntsLog && loggingThisType && loggingThisObject) {
|
||||
@ -1007,22 +1007,19 @@ nsTraceRefcntImpl::LogAddRef(void* aPtr,
|
||||
// Can't use PR_LOG(), b/c it truncates the line
|
||||
fprintf(gRefcntsLog,
|
||||
"\n<%s> 0x%08X %d AddRef %d\n", aClazz, NS_PTR_TO_INT32(aPtr), serialno, aRefcnt);
|
||||
WalkTheStack(gRefcntsLog);
|
||||
nsTraceRefcntImpl::WalkTheStack(gRefcntsLog);
|
||||
fflush(gRefcntsLog);
|
||||
}
|
||||
}
|
||||
UNLOCK_TRACELOG();
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogRelease(void* aPtr,
|
||||
nsrefcnt aRefcnt,
|
||||
const char* aClazz)
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogRelease(void* aPtr, nsrefcnt aRefcnt, const char* aClazz)
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
ASSERT_ACTIVITY_IS_LEGAL;
|
||||
if (!gInitialized)
|
||||
InitTraceLog();
|
||||
@ -1055,7 +1052,7 @@ nsTraceRefcntImpl::LogRelease(void* aPtr,
|
||||
// Can't use PR_LOG(), b/c it truncates the line
|
||||
fprintf(gRefcntsLog,
|
||||
"\n<%s> 0x%08X %d Release %d\n", aClazz, NS_PTR_TO_INT32(aPtr), serialno, aRefcnt);
|
||||
WalkTheStack(gRefcntsLog);
|
||||
nsTraceRefcntImpl::WalkTheStack(gRefcntsLog);
|
||||
fflush(gRefcntsLog);
|
||||
}
|
||||
}
|
||||
@ -1067,7 +1064,7 @@ nsTraceRefcntImpl::LogRelease(void* aPtr,
|
||||
fprintf(gAllocLog,
|
||||
"\n<%s> 0x%08X %d Destroy\n",
|
||||
aClazz, NS_PTR_TO_INT32(aPtr), serialno);
|
||||
WalkTheStack(gAllocLog);
|
||||
nsTraceRefcntImpl::WalkTheStack(gAllocLog);
|
||||
}
|
||||
|
||||
if (aRefcnt == 0 && gSerialNumbers && loggingThisType) {
|
||||
@ -1077,15 +1074,12 @@ nsTraceRefcntImpl::LogRelease(void* aPtr,
|
||||
UNLOCK_TRACELOG();
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogCtor(void* aPtr,
|
||||
const char* aType,
|
||||
PRUint32 aInstanceSize)
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogCtor(void* aPtr, const char* aType, PRUint32 aInstanceSize)
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
ASSERT_ACTIVITY_IS_LEGAL;
|
||||
if (!gInitialized)
|
||||
InitTraceLog();
|
||||
@ -1110,22 +1104,19 @@ nsTraceRefcntImpl::LogCtor(void* aPtr,
|
||||
if (gAllocLog && loggingThisType && loggingThisObject) {
|
||||
fprintf(gAllocLog, "\n<%s> 0x%08X %d Ctor (%d)\n",
|
||||
aType, NS_PTR_TO_INT32(aPtr), serialno, aInstanceSize);
|
||||
WalkTheStack(gAllocLog);
|
||||
nsTraceRefcntImpl::WalkTheStack(gAllocLog);
|
||||
}
|
||||
|
||||
UNLOCK_TRACELOG();
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogDtor(void* aPtr,
|
||||
const char* aType,
|
||||
PRUint32 aInstanceSize)
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogDtor(void* aPtr, const char* aType, PRUint32 aInstanceSize)
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
ASSERT_ACTIVITY_IS_LEGAL;
|
||||
if (!gInitialized)
|
||||
InitTraceLog();
|
||||
@ -1154,21 +1145,19 @@ nsTraceRefcntImpl::LogDtor(void* aPtr,
|
||||
if (gAllocLog && loggingThisType && loggingThisObject) {
|
||||
fprintf(gAllocLog, "\n<%s> 0x%08X %d Dtor (%d)\n",
|
||||
aType, NS_PTR_TO_INT32(aPtr), serialno, aInstanceSize);
|
||||
WalkTheStack(gAllocLog);
|
||||
nsTraceRefcntImpl::WalkTheStack(gAllocLog);
|
||||
}
|
||||
|
||||
UNLOCK_TRACELOG();
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogAddCOMPtr(void* aCOMPtr,
|
||||
nsISupports* aObject)
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogCOMPtrAddRef(void* aCOMPtr, nsISupports* aObject)
|
||||
{
|
||||
#if defined(NS_BUILD_REFCNT_LOGGING) && defined(HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR)
|
||||
#if defined(NS_IMPL_REFCNT_LOGGING) && defined(HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR)
|
||||
// Get the most-derived object.
|
||||
void *object = dynamic_cast<void *>(aObject);
|
||||
|
||||
@ -1176,11 +1165,11 @@ nsTraceRefcntImpl::LogAddCOMPtr(void* aCOMPtr,
|
||||
// of the object being logged. If we're logging a specific type,
|
||||
// then
|
||||
if (!gTypesToLog || !gSerialNumbers) {
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
PRInt32 serialno = GetSerialNumber(object, PR_FALSE);
|
||||
if (serialno == 0) {
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gInitialized)
|
||||
@ -1197,21 +1186,19 @@ nsTraceRefcntImpl::LogAddCOMPtr(void* aCOMPtr,
|
||||
if (gCOMPtrLog && loggingThisObject) {
|
||||
fprintf(gCOMPtrLog, "\n<?> 0x%08X %d nsCOMPtrAddRef %d 0x%08X\n",
|
||||
NS_PTR_TO_INT32(object), serialno, count?(*count):-1, NS_PTR_TO_INT32(aCOMPtr));
|
||||
WalkTheStack(gCOMPtrLog);
|
||||
nsTraceRefcntImpl::WalkTheStack(gCOMPtrLog);
|
||||
}
|
||||
|
||||
UNLOCK_TRACELOG();
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogReleaseCOMPtr(void* aCOMPtr,
|
||||
nsISupports* aObject)
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogCOMPtrRelease(void* aCOMPtr, nsISupports* aObject)
|
||||
{
|
||||
#if defined(NS_BUILD_REFCNT_LOGGING) && defined(HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR)
|
||||
#if defined(NS_IMPL_REFCNT_LOGGING) && defined(HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR)
|
||||
// Get the most-derived object.
|
||||
void *object = dynamic_cast<void *>(aObject);
|
||||
|
||||
@ -1219,11 +1206,11 @@ nsTraceRefcntImpl::LogReleaseCOMPtr(void* aCOMPtr,
|
||||
// of the object being logged. If we're logging a specific type,
|
||||
// then
|
||||
if (!gTypesToLog || !gSerialNumbers) {
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
PRInt32 serialno = GetSerialNumber(object, PR_FALSE);
|
||||
if (serialno == 0) {
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gInitialized)
|
||||
@ -1240,27 +1227,23 @@ nsTraceRefcntImpl::LogReleaseCOMPtr(void* aCOMPtr,
|
||||
if (gCOMPtrLog && loggingThisObject) {
|
||||
fprintf(gCOMPtrLog, "\n<?> 0x%08X %d nsCOMPtrRelease %d 0x%08X\n",
|
||||
NS_PTR_TO_INT32(object), serialno, count?(*count):-1, NS_PTR_TO_INT32(aCOMPtr));
|
||||
WalkTheStack(gCOMPtrLog);
|
||||
nsTraceRefcntImpl::WalkTheStack(gCOMPtrLog);
|
||||
}
|
||||
|
||||
UNLOCK_TRACELOG();
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcntImpl::Startup()
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
SetActivityIsLegal(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcntImpl::Shutdown()
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
|
||||
if (gBloatView) {
|
||||
PL_HashTableDestroy(gBloatView);
|
||||
@ -1278,33 +1261,81 @@ nsTraceRefcntImpl::Shutdown()
|
||||
PL_HashTableDestroy(gSerialNumbers);
|
||||
gSerialNumbers = nsnull;
|
||||
}
|
||||
|
||||
SetActivityIsLegal(PR_FALSE);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcntImpl::SetActivityIsLegal(PRBool aLegal)
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
gActivityIsLegal = aLegal;
|
||||
#ifdef NS_IMPL_REFCNT_LOGGING
|
||||
if (gActivityTLS == BAD_TLS_INDEX)
|
||||
PR_NewThreadPrivateIndex(&gActivityTLS, nsnull);
|
||||
|
||||
PR_SetThreadPrivate(gActivityTLS, NS_INT32_TO_PTR(!aLegal));
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE1(nsTraceRefcntImpl, nsITraceRefcnt)
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt) nsTraceRefcntImpl::AddRef(void)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt) nsTraceRefcntImpl::Release(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogAddRef(void *aPtr, nsrefcnt aNewRefcnt,
|
||||
const char *aTypeName, PRUint32 aSize)
|
||||
{
|
||||
NS_LogAddRef(aPtr, aNewRefcnt, aTypeName, aSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogRelease(void *aPtr, nsrefcnt aNewRefcnt,
|
||||
const char *aTypeName)
|
||||
{
|
||||
NS_LogRelease(aPtr, aNewRefcnt, aTypeName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogCtor(void *aPtr, const char *aTypeName, PRUint32 aSize)
|
||||
{
|
||||
NS_LogCtor(aPtr, aTypeName, aSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogDtor(void *aPtr, const char *aTypeName, PRUint32 aSize)
|
||||
{
|
||||
NS_LogDtor(aPtr, aTypeName, aSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogAddCOMPtr(void *aCOMPtr, nsISupports* aObject)
|
||||
{
|
||||
NS_LogCOMPtrAddRef(aCOMPtr, aObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTraceRefcntImpl::LogReleaseCOMPtr(void *aCOMPtr, nsISupports* aObject)
|
||||
{
|
||||
NS_LogCOMPtrRelease(aCOMPtr, aObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static const nsTraceRefcntImpl kTraceRefcntImpl;
|
||||
|
||||
NS_METHOD
|
||||
nsTraceRefcntImpl::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
|
||||
{
|
||||
*aInstancePtr = nsnull;
|
||||
nsITraceRefcnt* tracer = new nsTraceRefcntImpl();
|
||||
if (!tracer)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = tracer->QueryInterface(aIID, aInstancePtr);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete tracer;
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_CONST_CAST(nsTraceRefcntImpl*, &kTraceRefcntImpl)->
|
||||
QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
@ -47,8 +47,6 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITRACEREFCNT
|
||||
|
||||
nsTraceRefcntImpl();
|
||||
|
||||
static NS_COM void Startup();
|
||||
static NS_COM void Shutdown();
|
||||
|
||||
@ -79,9 +77,6 @@ public:
|
||||
static NS_COM void SetActivityIsLegal(PRBool aLegal);
|
||||
|
||||
static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
|
||||
private:
|
||||
~nsTraceRefcntImpl() {}
|
||||
};
|
||||
|
||||
#define NS_TRACE_REFCNT_CONTRACTID "@mozilla.org/xpcom/trace-refcnt;1"
|
||||
|
||||
@ -241,9 +241,15 @@
|
||||
* Import/Export macros for XPCOM APIs
|
||||
*/
|
||||
|
||||
#define EXPORT_XPCOM_API(type) extern "C" NS_EXPORT type NS_FROZENCALL
|
||||
#define IMPORT_XPCOM_API(type) extern "C" NS_IMPORT type NS_FROZENCALL
|
||||
#define GLUE_XPCOM_API(type) NS_HIDDEN_(type) NS_FROZENCALL
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C extern "C"
|
||||
#else
|
||||
#define EXTERN_C
|
||||
#endif
|
||||
|
||||
#define EXPORT_XPCOM_API(type) EXTERN_C NS_EXPORT type NS_FROZENCALL
|
||||
#define IMPORT_XPCOM_API(type) EXTERN_C NS_IMPORT type NS_FROZENCALL
|
||||
#define GLUE_XPCOM_API(type) EXTERN_C NS_HIDDEN_(type) NS_FROZENCALL
|
||||
|
||||
#ifdef _IMPL_NS_COM
|
||||
#define XPCOM_API(type) EXPORT_XPCOM_API(type)
|
||||
@ -303,6 +309,20 @@
|
||||
*/
|
||||
typedef PRUint32 nsresult;
|
||||
|
||||
/**
|
||||
* Reference count values
|
||||
*
|
||||
* This is the return type for AddRef() and Release() in nsISupports.
|
||||
* IUnknown of COM returns an unsigned long from equivalent functions.
|
||||
* The following ifdef exists to maintain binary compatibility with
|
||||
* IUnknown.
|
||||
*/
|
||||
#if defined(XP_WIN) && PR_BYTES_PER_LONG == 4
|
||||
typedef unsigned long nsrefcnt;
|
||||
#else
|
||||
typedef PRUint32 nsrefcnt;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The preferred symbol for null.
|
||||
*/
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
#ifndef nsXPCOM_h__
|
||||
#define nsXPCOM_h__
|
||||
|
||||
// Map frozen functions to private symbol names if not using strict API.
|
||||
/* Map frozen functions to private symbol names if not using strict API. */
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
# define NS_InitXPCOM2 NS_InitXPCOM2_P
|
||||
# define NS_InitXPCOM3 NS_InitXPCOM3_P
|
||||
@ -55,24 +55,40 @@
|
||||
# define NS_Alloc NS_Alloc_P
|
||||
# define NS_Realloc NS_Realloc_P
|
||||
# define NS_Free NS_Free_P
|
||||
# define NS_DebugBreak NS_DebugBreak_P
|
||||
# define NS_LogInit NS_LogInit_P
|
||||
# define NS_LogTerm NS_LogTerm_P
|
||||
# define NS_LogAddRef NS_LogAddRef_P
|
||||
# define NS_LogRelease NS_LogRelease_P
|
||||
# define NS_LogCtor NS_LogCtor_P
|
||||
# define NS_LogDtor NS_LogDtor_P
|
||||
# define NS_LogCOMPtrAddRef NS_LogCOMPtrAddRef_P
|
||||
# define NS_LogCOMPtrRelease NS_LogCOMPtrRelease_P
|
||||
#endif
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
|
||||
class nsAString;
|
||||
class nsACString;
|
||||
#ifdef __cplusplus
|
||||
#define DECL_CLASS(c) class c
|
||||
#else
|
||||
#define DECL_CLASS(c) typedef struct c c
|
||||
#endif
|
||||
|
||||
class nsIModule;
|
||||
class nsIComponentManager;
|
||||
class nsIComponentRegistrar;
|
||||
class nsIServiceManager;
|
||||
class nsIFile;
|
||||
class nsILocalFile;
|
||||
class nsIDirectoryServiceProvider;
|
||||
class nsIMemory;
|
||||
class nsIDebug;
|
||||
class nsITraceRefcnt;
|
||||
DECL_CLASS(nsAString);
|
||||
DECL_CLASS(nsACString);
|
||||
|
||||
DECL_CLASS(nsISupports);
|
||||
DECL_CLASS(nsIModule);
|
||||
DECL_CLASS(nsIComponentManager);
|
||||
DECL_CLASS(nsIComponentRegistrar);
|
||||
DECL_CLASS(nsIServiceManager);
|
||||
DECL_CLASS(nsIFile);
|
||||
DECL_CLASS(nsILocalFile);
|
||||
DECL_CLASS(nsIDirectoryServiceProvider);
|
||||
DECL_CLASS(nsIMemory);
|
||||
DECL_CLASS(nsIDebug);
|
||||
DECL_CLASS(nsITraceRefcnt);
|
||||
|
||||
/**
|
||||
* Every XPCOM component implements this function signature, which is the
|
||||
@ -130,10 +146,10 @@ NS_InitXPCOM2(nsIServiceManager* *result,
|
||||
*
|
||||
* @status FROZEN
|
||||
*/
|
||||
struct nsStaticModuleInfo {
|
||||
typedef struct nsStaticModuleInfo {
|
||||
const char *name;
|
||||
nsGetModuleProc getModule;
|
||||
};
|
||||
} nsStaticModuleInfo;
|
||||
|
||||
/**
|
||||
* Initialises XPCOM with static components. You must call one of the
|
||||
@ -274,6 +290,8 @@ NS_GetMemoryManager(nsIMemory* *result);
|
||||
* other error codes indicate a failure.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
XPCOM_API(nsresult)
|
||||
NS_NewLocalFile(const nsAString &path,
|
||||
PRBool followLinks,
|
||||
@ -284,6 +302,8 @@ NS_NewNativeLocalFile(const nsACString &path,
|
||||
PRBool followLinks,
|
||||
nsILocalFile* *result);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Allocates a block of memory of a particular size. If the memory cannot
|
||||
* be allocated (because of an out-of-memory condition), null is returned.
|
||||
@ -331,6 +351,107 @@ NS_Realloc(void* ptr, PRSize size);
|
||||
XPCOM_API(void)
|
||||
NS_Free(void* ptr);
|
||||
|
||||
/**
|
||||
* Support for warnings, assertions, and debugging breaks.
|
||||
*/
|
||||
|
||||
enum {
|
||||
NS_DEBUG_WARNING = 0,
|
||||
NS_DEBUG_ASSERTION = 1,
|
||||
NS_DEBUG_BREAK = 2,
|
||||
NS_DEBUG_ABORT = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* Print a runtime assertion. This function is available in both debug and
|
||||
* release builds.
|
||||
*
|
||||
* @note Based on the value of aSeverity and the XPCOM_DEBUG_BREAK
|
||||
* environment variable, this function may cause the application to
|
||||
* print the warning, print a stacktrace, break into a debugger, or abort
|
||||
* immediately.
|
||||
*
|
||||
* @param aSeverity A NS_DEBUG_* value
|
||||
* @param aStr A readable error message (ASCII, may be null)
|
||||
* @param aExpr The expression evaluated (may be null)
|
||||
* @param aFile The source file containing the assertion (may be null)
|
||||
* @param aLine The source file line number (-1 indicates no line number)
|
||||
*/
|
||||
XPCOM_API(void)
|
||||
NS_DebugBreak(PRUint32 aSeverity,
|
||||
const char *aStr, const char *aExpr,
|
||||
const char *aFile, PRInt32 aLine);
|
||||
|
||||
/**
|
||||
* Perform a stack-walk to a debugging log under various
|
||||
* circumstances. Used to aid debugging of leaked object graphs.
|
||||
*
|
||||
* The NS_Log* functions are available in both debug and release
|
||||
* builds of XPCOM, but the output will be useless unless binary
|
||||
* debugging symbols for all modules in the stacktrace are available.
|
||||
*/
|
||||
|
||||
/**
|
||||
* By default, refcount logging is enabled at NS_InitXPCOM and
|
||||
* refcount statistics are printed at NS_ShutdownXPCOM. NS_LogInit and
|
||||
* NS_LogTerm allow applications to enable logging earlier and delay
|
||||
* printing of logging statistics. They should always be used as a
|
||||
* matched pair.
|
||||
*/
|
||||
XPCOM_API(void)
|
||||
NS_LogInit();
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogTerm();
|
||||
|
||||
/**
|
||||
* Log construction and destruction of objects. Processing tools can use the
|
||||
* stacktraces printed by these functions to identify objects that are being
|
||||
* leaked.
|
||||
*
|
||||
* @param aPtr A pointer to the concrete object.
|
||||
* @param aTypeName The class name of the type
|
||||
* @param aInstanceSize The size of the type
|
||||
*/
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogCtor(void *aPtr, const char *aTypeName, PRUint32 aInstanceSize);
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogDtor(void *aPtr, const char *aTypeName, PRUint32 aInstanceSize);
|
||||
|
||||
/**
|
||||
* Log a stacktrace when an XPCOM object's refcount is incremented or
|
||||
* decremented. Processing tools can use the stacktraces printed by these
|
||||
* functions to identify objects that were leaked due to XPCOM references.
|
||||
*
|
||||
* @param aPtr A pointer to the concrete object
|
||||
* @param aNewRefCnt The new reference count.
|
||||
* @param aTypeName The class name of the type
|
||||
* @param aInstanceSize The size of the type
|
||||
*/
|
||||
XPCOM_API(void)
|
||||
NS_LogAddRef(void *aPtr, nsrefcnt aNewRefCnt,
|
||||
const char *aTypeName, PRUint32 aInstanceSize);
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogRelease(void *aPtr, nsrefcnt aNewRefCnt, const char *aTypeName);
|
||||
|
||||
/**
|
||||
* Log reference counting performed by COMPtrs. Processing tools can
|
||||
* use the stacktraces printed by these functions to simplify reports
|
||||
* about leaked objects generated from the data printed by
|
||||
* NS_LogAddRef/NS_LogRelease.
|
||||
*
|
||||
* @param aCOMPtr the address of the COMPtr holding a strong reference
|
||||
* @param aObject the object being referenced by the COMPtr
|
||||
*/
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogCOMPtrAddRef(void *aCOMPtr, nsISupports *aObject);
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogCOMPtrRelease(void *aCOMPtr, nsISupports *aObject);
|
||||
|
||||
/**
|
||||
* Categories (in the category manager service) used by XPCOM:
|
||||
|
||||
@ -136,6 +136,16 @@ typedef void* (* AllocFunc)(PRSize size);
|
||||
typedef void* (* ReallocFunc)(void* ptr, PRSize size);
|
||||
typedef void (* FreeFunc)(void* ptr);
|
||||
|
||||
typedef void (* DebugBreakFunc)(PRUint32 aSeverity,
|
||||
const char *aStr, const char *aExpr,
|
||||
const char *aFile, PRInt32 aLine);
|
||||
|
||||
typedef void (* xpcomVoidFunc)();
|
||||
typedef void (* LogAddRefFunc)(void*, nsrefcnt, const char*, PRUint32);
|
||||
typedef void (* LogReleaseFunc)(void*, nsrefcnt, const char*);
|
||||
typedef void (* LogCtorFunc)(void*, const char*, PRUint32);
|
||||
typedef void (* LogCOMPtrFunc)(void*, nsISupports*);
|
||||
|
||||
// PRIVATE
|
||||
typedef nsresult (* RegisterXPCOMExitRoutineFunc)(XPCOMExitRoutine exitRoutine, PRUint32 priority);
|
||||
typedef nsresult (* UnregisterXPCOMExitRoutineFunc)(XPCOMExitRoutine exitRoutine);
|
||||
@ -187,6 +197,18 @@ typedef struct XPCOMFunctions{
|
||||
StringGetMutableDataFunc stringGetMutableData;
|
||||
CStringGetMutableDataFunc cstringGetMutableData;
|
||||
Init3Func init3;
|
||||
|
||||
// Added for Mozilla 1.9
|
||||
DebugBreakFunc debugBreakFunc;
|
||||
xpcomVoidFunc logInitFunc;
|
||||
xpcomVoidFunc logTermFunc;
|
||||
LogAddRefFunc logAddRefFunc;
|
||||
LogReleaseFunc logReleaseFunc;
|
||||
LogCtorFunc logCtorFunc;
|
||||
LogCtorFunc logDtorFunc;
|
||||
LogCOMPtrFunc logCOMPtrAddRefFunc;
|
||||
LogCOMPtrFunc logCOMPtrReleaseFunc;
|
||||
|
||||
} XPCOMFunctions;
|
||||
|
||||
typedef nsresult (PR_CALLBACK *GetFrozenFunctionsFunc)(XPCOMFunctions *entryPoints, const char* libraryPath);
|
||||
|
||||
@ -421,38 +421,17 @@ static nsIDebug* gDebug = nsnull;
|
||||
EXPORT_XPCOM_API(nsresult)
|
||||
NS_GetDebug(nsIDebug** result)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!gDebug)
|
||||
{
|
||||
rv = nsDebugImpl::Create(nsnull,
|
||||
NS_GET_IID(nsIDebug),
|
||||
(void**)&gDebug);
|
||||
}
|
||||
NS_IF_ADDREF(*result = gDebug);
|
||||
return rv;
|
||||
return nsDebugImpl::Create(nsnull,
|
||||
NS_GET_IID(nsIDebug),
|
||||
(void**) result);
|
||||
}
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
// gTraceRefcnt will be freed during shutdown.
|
||||
static nsITraceRefcnt* gTraceRefcnt = nsnull;
|
||||
#endif
|
||||
|
||||
EXPORT_XPCOM_API(nsresult)
|
||||
NS_GetTraceRefcnt(nsITraceRefcnt** result)
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
nsresult rv = NS_OK;
|
||||
if (!gTraceRefcnt)
|
||||
{
|
||||
rv = nsTraceRefcntImpl::Create(nsnull,
|
||||
NS_GET_IID(nsITraceRefcnt),
|
||||
(void**)&gTraceRefcnt);
|
||||
}
|
||||
NS_IF_ADDREF(*result = gTraceRefcnt);
|
||||
return rv;
|
||||
#else
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
#endif
|
||||
return nsTraceRefcntImpl::Create(nsnull,
|
||||
NS_GET_IID(nsITraceRefcnt),
|
||||
(void**) result);
|
||||
}
|
||||
|
||||
EXPORT_XPCOM_API(nsresult)
|
||||
@ -489,9 +468,7 @@ NS_InitXPCOM3(nsIServiceManager* *result,
|
||||
// We are not shutting down
|
||||
gXPCOMShuttingDown = PR_FALSE;
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
nsTraceRefcntImpl::Startup();
|
||||
#endif
|
||||
NS_LogInit();
|
||||
|
||||
// Establish the main thread here.
|
||||
rv = nsIThread::SetMainThread();
|
||||
@ -868,11 +845,7 @@ NS_ShutdownXPCOM(nsIServiceManager* servMgr)
|
||||
|
||||
NS_IF_RELEASE(gDebug);
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
nsTraceRefcntImpl::DumpStatistics();
|
||||
nsTraceRefcntImpl::ResetStatistics();
|
||||
nsTraceRefcntImpl::Shutdown();
|
||||
#endif
|
||||
NS_LogTerm();
|
||||
|
||||
#ifdef GC_LEAK_DETECTOR
|
||||
// Shutdown the Leak detector.
|
||||
|
||||
@ -1,111 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is XPCOM
|
||||
*
|
||||
* The Initial Developer of the Original Code is Doug Turner <dougt@meer.net>
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsXPCOMPrivate.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsDebugImpl.h"
|
||||
|
||||
static nsIDebug* gDebugObject = nsnull;
|
||||
|
||||
static NS_METHOD FreeDebugObject(void)
|
||||
{
|
||||
NS_IF_RELEASE(gDebugObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define ENSURE_DEBUGOBJECT \
|
||||
(gDebugObject ? PR_TRUE : (PRBool)(SetupDebugObject() != nsnull))
|
||||
|
||||
static nsIDebug* SetupDebugObject()
|
||||
{
|
||||
NS_GetDebug(&gDebugObject);
|
||||
if (gDebugObject)
|
||||
NS_RegisterXPCOMExitRoutine(FreeDebugObject, 0);
|
||||
return gDebugObject;
|
||||
}
|
||||
|
||||
#ifdef XPCOM_GLUE
|
||||
nsresult GlueStartupDebug()
|
||||
{
|
||||
NS_GetDebug(&gDebugObject);
|
||||
if (!gDebugObject)
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void GlueShutdownDebug()
|
||||
{
|
||||
NS_IF_RELEASE(gDebugObject);
|
||||
}
|
||||
#endif
|
||||
|
||||
void NS_FASTCALL
|
||||
NSGlue_Abort(const char* aFile, PRIntn aLine)
|
||||
{
|
||||
if (!ENSURE_DEBUGOBJECT)
|
||||
return;
|
||||
|
||||
gDebugObject->Abort(aFile, aLine);
|
||||
}
|
||||
|
||||
void NS_FASTCALL
|
||||
NSGlue_Break(const char* aFile, PRIntn aLine)
|
||||
{
|
||||
if (!ENSURE_DEBUGOBJECT)
|
||||
return;
|
||||
|
||||
gDebugObject->Break(aFile, aLine);
|
||||
}
|
||||
|
||||
void NS_FASTCALL
|
||||
NSGlue_Warning(const char* aStr, const char* aFile, PRIntn aLine)
|
||||
{
|
||||
if (!ENSURE_DEBUGOBJECT)
|
||||
return;
|
||||
gDebugObject->Warning(aStr, aFile, aLine);
|
||||
}
|
||||
|
||||
void NS_FASTCALL
|
||||
NSGlue_Assertion(const char* aStr, const char* aExpr,
|
||||
const char* aFile, PRIntn aLine)
|
||||
{
|
||||
if (!ENSURE_DEBUGOBJECT)
|
||||
return;
|
||||
gDebugObject->Assertion(aStr, aExpr, aFile, aLine);
|
||||
}
|
||||
@ -46,45 +46,12 @@
|
||||
#include "nsError.h"
|
||||
#endif
|
||||
|
||||
#include "nsXPCOM.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define NS_DEBUG
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Namespace for debugging methods. Note that your code must use the
|
||||
* macros defined later in this file so that the debug code can be
|
||||
* conditionally compiled out.
|
||||
*/
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* Log a warning message to the debug log.
|
||||
*/
|
||||
NS_COM_GLUE void NS_FASTCALL
|
||||
NSGlue_Warning(const char *aMessage, const char *aFile, PRIntn aLine);
|
||||
|
||||
/**
|
||||
* Abort the executing program. This works on all architectures.
|
||||
*/
|
||||
NS_COM_GLUE void NS_FASTCALL
|
||||
NSGlue_Abort(const char *aFile, PRIntn aLine);
|
||||
|
||||
/**
|
||||
* Break the executing program into the debugger.
|
||||
*/
|
||||
NS_COM_GLUE void NS_FASTCALL
|
||||
NSGlue_Break(const char* aFile, PRIntn aLine);
|
||||
|
||||
/**
|
||||
* Log an assertion message to the debug log
|
||||
*/
|
||||
NS_COM_GLUE void NS_FASTCALL
|
||||
NSGlue_Assertion(const char* aStr, const char* aExpr,
|
||||
const char* aFile, PRIntn aLine);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/**
|
||||
@ -106,7 +73,7 @@ PR_END_EXTERN_C
|
||||
#define NS_ABORT_IF_FALSE(_expr, _msg) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (!(_expr)) { \
|
||||
NSGlue_Assertion(_msg, #_expr, __FILE__, __LINE__); \
|
||||
NS_DebugBreak(NS_DEBUG_ASSERTION, _msg, #_expr, __FILE__, __LINE__); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
@ -121,7 +88,7 @@ PR_END_EXTERN_C
|
||||
#define NS_WARN_IF_FALSE(_expr,_msg) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (!(_expr)) { \
|
||||
NSGlue_Assertion(_msg, #_expr, __FILE__, __LINE__); \
|
||||
NS_DebugBreak(NS_DEBUG_ASSERTION, _msg, #_expr, __FILE__, __LINE__); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
@ -132,7 +99,7 @@ PR_END_EXTERN_C
|
||||
#define NS_PRECONDITION(expr, str) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (!(expr)) { \
|
||||
NSGlue_Assertion(str, #expr, __FILE__, __LINE__); \
|
||||
NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
@ -143,7 +110,7 @@ PR_END_EXTERN_C
|
||||
#define NS_ASSERTION(expr, str) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (!(expr)) { \
|
||||
NSGlue_Assertion(str, #expr, __FILE__, __LINE__); \
|
||||
NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
@ -154,7 +121,7 @@ PR_END_EXTERN_C
|
||||
#define NS_POSTCONDITION(expr, str) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (!(expr)) { \
|
||||
NSGlue_Assertion(str, #expr, __FILE__, __LINE__); \
|
||||
NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
@ -163,38 +130,38 @@ PR_END_EXTERN_C
|
||||
* an attempt was made to execute some unimplemented functionality.
|
||||
*/
|
||||
#define NS_NOTYETIMPLEMENTED(str) \
|
||||
NSGlue_Assertion(str, "NotYetImplemented", __FILE__, __LINE__)
|
||||
NS_DebugBreak(NS_DEBUG_ASSERTION, str, "NotYetImplemented", __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* This macros triggers a program failure if executed. It indicates that
|
||||
* an attempt was made to execute some unimplemented functionality.
|
||||
*/
|
||||
#define NS_NOTREACHED(str) \
|
||||
NSGlue_Assertion(str, "Not Reached", __FILE__, __LINE__)
|
||||
NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Not Reached", __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Log an error message.
|
||||
*/
|
||||
#define NS_ERROR(str) \
|
||||
NSGlue_Assertion(str, "Error", __FILE__, __LINE__)
|
||||
NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Error", __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Log a warning message.
|
||||
*/
|
||||
#define NS_WARNING(str) \
|
||||
NSGlue_Warning(str, __FILE__, __LINE__)
|
||||
NS_DebugBreak(NS_DEBUG_WARNING, str, nsnull, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Trigger an abort
|
||||
*/
|
||||
#define NS_ABORT() \
|
||||
NSGlue_Abort(__FILE__, __LINE__)
|
||||
NS_DebugBreak(NS_DEBUG_ABORT, nsnull, nsnull, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Cause a break
|
||||
*/
|
||||
#define NS_BREAK() \
|
||||
NSGlue_Break(__FILE__, __LINE__)
|
||||
NS_DebugBreak(NS_DEBUG_BREAK, nsnull, nsnull, __FILE__, __LINE__)
|
||||
|
||||
#else /* NS_DEBUG */
|
||||
|
||||
|
||||
@ -1,125 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is XPCOM
|
||||
*
|
||||
* The Initial Developer of the Original Code is Doug Turner <dougt@meer.net>
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsXPCOMPrivate.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "nsTraceRefcntImpl.h"
|
||||
|
||||
static nsITraceRefcnt* gTraceRefcntObject = nsnull;
|
||||
|
||||
static NS_METHOD FreeTraceRefcntObject(void)
|
||||
{
|
||||
NS_IF_RELEASE(gTraceRefcntObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define ENSURE_TRACEOBJECT \
|
||||
(gTraceRefcntObject || SetupTraceRefcntObject() != nsnull)
|
||||
|
||||
static nsITraceRefcnt* SetupTraceRefcntObject()
|
||||
{
|
||||
NS_GetTraceRefcnt(&gTraceRefcntObject);
|
||||
if (gTraceRefcntObject)
|
||||
NS_RegisterXPCOMExitRoutine(FreeTraceRefcntObject, 0);
|
||||
return gTraceRefcntObject;
|
||||
}
|
||||
|
||||
#ifdef XPCOM_GLUE
|
||||
nsresult GlueStartupTraceRefcnt()
|
||||
{
|
||||
NS_GetTraceRefcnt(&gTraceRefcntObject);
|
||||
if (!gTraceRefcntObject)
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void GlueShutdownTraceRefcnt()
|
||||
{
|
||||
NS_IF_RELEASE(gTraceRefcntObject);
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_COM_GLUE void
|
||||
nsTraceRefcnt::LogAddRef(void * aPtr, nsrefcnt aNewRefcnt, const char *aTypeName, PRUint32 aInstanceSize)
|
||||
{
|
||||
if (!ENSURE_TRACEOBJECT)
|
||||
return;
|
||||
gTraceRefcntObject->LogAddRef(aPtr, aNewRefcnt, aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
NS_COM_GLUE void
|
||||
nsTraceRefcnt::LogRelease(void * aPtr, nsrefcnt aNewRefcnt, const char *aTypeName)
|
||||
{
|
||||
if (!ENSURE_TRACEOBJECT)
|
||||
return;
|
||||
gTraceRefcntObject->LogRelease(aPtr, aNewRefcnt, aTypeName);
|
||||
}
|
||||
|
||||
NS_COM_GLUE void
|
||||
nsTraceRefcnt::LogCtor(void * aPtr, const char *aTypeName, PRUint32 aInstanceSize)
|
||||
{
|
||||
if (!ENSURE_TRACEOBJECT)
|
||||
return;
|
||||
gTraceRefcntObject->LogCtor(aPtr, aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
NS_COM_GLUE void
|
||||
nsTraceRefcnt::LogDtor(void * aPtr, const char *aTypeName, PRUint32 aInstanceSize)
|
||||
{
|
||||
if (!ENSURE_TRACEOBJECT)
|
||||
return;
|
||||
gTraceRefcntObject->LogDtor(aPtr, aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
NS_COM_GLUE void
|
||||
nsTraceRefcnt::LogAddCOMPtr(void * aPtr, nsISupports *aObject)
|
||||
{
|
||||
if (!ENSURE_TRACEOBJECT)
|
||||
return;
|
||||
gTraceRefcntObject->LogAddCOMPtr(aPtr, aObject);
|
||||
}
|
||||
|
||||
NS_COM_GLUE void
|
||||
nsTraceRefcnt::LogReleaseCOMPtr(void * aPtr, nsISupports *aObject)
|
||||
{
|
||||
if (!ENSURE_TRACEOBJECT)
|
||||
return;
|
||||
gTraceRefcntObject->LogReleaseCOMPtr(aPtr, aObject);
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
#ifndef nsTraceRefcnt_h___
|
||||
#define nsTraceRefcnt_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsXPCOM.h"
|
||||
|
||||
class nsISupports;
|
||||
|
||||
@ -61,38 +61,33 @@ class nsISupports;
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
|
||||
#define NS_LOG_ADDREF(_p, _rc, _type, _size) \
|
||||
nsTraceRefcnt::LogAddRef((_p), (_rc), (_type), (PRUint32) (_size))
|
||||
NS_LogAddRef((_p), (_rc), (_type), (PRUint32) (_size))
|
||||
|
||||
#define NS_LOG_RELEASE(_p, _rc, _type) \
|
||||
nsTraceRefcnt::LogRelease((_p), (_rc), (_type))
|
||||
NS_LogRelease((_p), (_rc), (_type))
|
||||
|
||||
#define MOZ_DECL_CTOR_COUNTER(_type)
|
||||
|
||||
#define MOZ_COUNT_CTOR(_type) \
|
||||
PR_BEGIN_MACRO \
|
||||
nsTraceRefcnt::LogCtor((void*)this, #_type, sizeof(*this)); \
|
||||
NS_LogCtor((void*)this, #_type, sizeof(*this)); \
|
||||
PR_END_MACRO
|
||||
|
||||
#define MOZ_COUNT_DTOR(_type) \
|
||||
PR_BEGIN_MACRO \
|
||||
nsTraceRefcnt::LogDtor((void*)this, #_type, sizeof(*this)); \
|
||||
NS_LogDtor((void*)this, #_type, sizeof(*this)); \
|
||||
PR_END_MACRO
|
||||
|
||||
#ifdef HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR // from autoconf (XXX needs to be
|
||||
// set for non-autoconf platforms)
|
||||
|
||||
// nsCOMPtr.h allows these macros to be defined by clients
|
||||
// These logging functions require dynamic_cast<void *>, so we don't
|
||||
// define these macros if we don't have dynamic_cast.
|
||||
#define NSCAP_LOG_ASSIGNMENT(_c, _p) \
|
||||
if (_p) \
|
||||
nsTraceRefcnt::LogAddCOMPtr((_c),NS_STATIC_CAST(nsISupports*,_p))
|
||||
NS_LogCOMPtrAddRef((_c),NS_STATIC_CAST(nsISupports*,_p))
|
||||
|
||||
#define NSCAP_LOG_RELEASE(_c, _p) \
|
||||
if (_p) \
|
||||
nsTraceRefcnt::LogReleaseCOMPtr((_c), NS_STATIC_CAST(nsISupports*,_p))
|
||||
|
||||
#endif /* HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR */
|
||||
NS_LogCOMPtrRelease((_c), NS_STATIC_CAST(nsISupports*,_p))
|
||||
|
||||
#else /* !NS_BUILD_REFCNT_LOGGING */
|
||||
|
||||
@ -104,32 +99,35 @@ PR_END_MACRO
|
||||
|
||||
#endif /* NS_BUILD_REFCNT_LOGGING */
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Note: The implementations for these methods are no-ops in a build
|
||||
* where NS_BUILD_REFCNT_LOGGING is disabled.
|
||||
*/
|
||||
class nsTraceRefcnt {
|
||||
public:
|
||||
static NS_COM_GLUE void LogAddRef(void* aPtr,
|
||||
nsrefcnt aNewRefCnt,
|
||||
const char* aTypeName,
|
||||
PRUint32 aInstanceSize);
|
||||
inline static void LogAddRef(void* aPtr, nsrefcnt aNewRefCnt,
|
||||
const char* aTypeName, PRUint32 aInstanceSize) {
|
||||
NS_LogAddRef(aPtr, aNewRefCnt, aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
static NS_COM_GLUE void LogRelease(void* aPtr,
|
||||
nsrefcnt aNewRefCnt,
|
||||
const char* aTypeName);
|
||||
inline static void LogRelease(void* aPtr, nsrefcnt aNewRefCnt,
|
||||
const char* aTypeName) {
|
||||
NS_LogRelease(aPtr, aNewRefCnt, aTypeName);
|
||||
}
|
||||
|
||||
static NS_COM_GLUE void LogCtor(void* aPtr, const char* aTypeName,
|
||||
PRUint32 aInstanceSize);
|
||||
inline static void LogCtor(void* aPtr, const char* aTypeName,
|
||||
PRUint32 aInstanceSize) {
|
||||
NS_LogCtor(aPtr, aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
static NS_COM_GLUE void LogDtor(void* aPtr, const char* aTypeName,
|
||||
PRUint32 aInstanceSize);
|
||||
inline static void LogDtor(void* aPtr, const char* aTypeName,
|
||||
PRUint32 aInstanceSize) {
|
||||
NS_LogDtor(aPtr, aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
static NS_COM_GLUE void LogAddCOMPtr(void *aCOMPtr, nsISupports *aObject);
|
||||
|
||||
static NS_COM_GLUE void LogReleaseCOMPtr(void *aCOMPtr, nsISupports *aObject);
|
||||
inline static void LogAddCOMPtr(void *aCOMPtr, nsISupports *aObject) {
|
||||
NS_LogCOMPtrAddRef(aCOMPtr, aObject);
|
||||
}
|
||||
|
||||
inline static void LogReleaseCOMPtr(void *aCOMPtr, nsISupports *aObject) {
|
||||
NS_LogCOMPtrRelease(aCOMPtr, aObject);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* nsTraceRefcnt_h___ */
|
||||
|
||||
@ -45,12 +45,10 @@ XPCOM_GLUE_SRC_LCPPSRCS = \
|
||||
nsCOMArray.cpp \
|
||||
nsCRTGlue.cpp \
|
||||
nsComponentManagerUtils.cpp \
|
||||
nsDebug.cpp \
|
||||
nsID.cpp \
|
||||
nsIInterfaceRequestorUtils.cpp \
|
||||
nsINIParser.cpp \
|
||||
nsMemory.cpp \
|
||||
nsTraceRefcnt.cpp \
|
||||
nsWeakReference.cpp \
|
||||
nsGREGlue.cpp \
|
||||
nsVersionComparator.cpp \
|
||||
|
||||
@ -55,10 +55,6 @@
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
// functions provided by nsDebug.cpp
|
||||
nsresult GlueStartupDebug();
|
||||
void GlueShutdownDebug();
|
||||
|
||||
static XPCOMFunctions xpcomFunctions;
|
||||
|
||||
extern "C"
|
||||
@ -83,13 +79,6 @@ nsresult XPCOMGlueStartup(const char* xpcomFile)
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = GlueStartupDebug();
|
||||
if (NS_FAILED(rv)) {
|
||||
memset(&xpcomFunctions, 0, sizeof(xpcomFunctions));
|
||||
XPCOMGlueUnload();
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -132,8 +121,6 @@ XPCOMGlueLoadDependentLibs(const char *xpcomDir, DependentLibsCallback cb)
|
||||
extern "C"
|
||||
nsresult XPCOMGlueShutdown()
|
||||
{
|
||||
GlueShutdownDebug();
|
||||
|
||||
XPCOMGlueUnload();
|
||||
|
||||
memset(&xpcomFunctions, 0, sizeof(xpcomFunctions));
|
||||
@ -452,6 +439,73 @@ NS_Free(void* ptr)
|
||||
xpcomFunctions.freeFunc(ptr);
|
||||
}
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_DebugBreak(PRUint32 aSeverity, const char *aStr, const char *aExpr,
|
||||
const char *aFile, PRInt32 aLine)
|
||||
{
|
||||
if (xpcomFunctions.debugBreakFunc)
|
||||
xpcomFunctions.debugBreakFunc(aSeverity, aStr, aExpr, aFile, aLine);
|
||||
}
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogInit()
|
||||
{
|
||||
if (xpcomFunctions.logInitFunc)
|
||||
xpcomFunctions.logInitFunc();
|
||||
}
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogTerm()
|
||||
{
|
||||
if (xpcomFunctions.logTermFunc)
|
||||
xpcomFunctions.logTermFunc();
|
||||
}
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogAddRef(void *aPtr, nsrefcnt aNewRefCnt,
|
||||
const char *aTypeName, PRUint32 aInstanceSize)
|
||||
{
|
||||
if (xpcomFunctions.logAddRefFunc)
|
||||
xpcomFunctions.logAddRefFunc(aPtr, aNewRefCnt,
|
||||
aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogRelease(void *aPtr, nsrefcnt aNewRefCnt, const char *aTypeName)
|
||||
{
|
||||
if (xpcomFunctions.logReleaseFunc)
|
||||
xpcomFunctions.logReleaseFunc(aPtr, aNewRefCnt, aTypeName);
|
||||
}
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogCtor(void *aPtr, const char *aTypeName, PRUint32 aInstanceSize)
|
||||
{
|
||||
if (xpcomFunctions.logCtorFunc)
|
||||
xpcomFunctions.logCtorFunc(aPtr, aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogDtor(void *aPtr, const char *aTypeName, PRUint32 aInstanceSize)
|
||||
{
|
||||
if (xpcomFunctions.logDtorFunc)
|
||||
xpcomFunctions.logDtorFunc(aPtr, aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogCOMPtrAddRef(void *aCOMPtr, nsISupports *aObject)
|
||||
{
|
||||
if (xpcomFunctions.logCOMPtrAddRefFunc)
|
||||
xpcomFunctions.logCOMPtrAddRefFunc(aCOMPtr, aObject);
|
||||
}
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_LogCOMPtrRelease(void *aCOMPtr, nsISupports *aObject)
|
||||
{
|
||||
if (xpcomFunctions.logCOMPtrReleaseFunc)
|
||||
xpcomFunctions.logCOMPtrReleaseFunc(aCOMPtr, aObject);
|
||||
}
|
||||
|
||||
|
||||
// Default GRE startup/shutdown code
|
||||
|
||||
extern "C"
|
||||
|
||||
@ -44,6 +44,7 @@ include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = xpcom
|
||||
LIBRARY_NAME = xptcmd
|
||||
MOZILLA_INTERNAL_API = 1
|
||||
|
||||
#
|
||||
# The default is this buildable, but non-functioning code.
|
||||
|
||||
@ -85,8 +85,19 @@ static const XPCOMFunctions kFrozenFunctions = {
|
||||
&NS_CStringContainerInit2_P,
|
||||
&NS_StringGetMutableData_P,
|
||||
&NS_CStringGetMutableData_P,
|
||||
&NS_InitXPCOM3_P
|
||||
};
|
||||
&NS_InitXPCOM3_P,
|
||||
|
||||
// these functions were added post 1.8
|
||||
&NS_DebugBreak_P,
|
||||
&NS_LogInit_P,
|
||||
&NS_LogTerm_P,
|
||||
&NS_LogAddRef_P,
|
||||
&NS_LogRelease_P,
|
||||
&NS_LogCtor_P,
|
||||
&NS_LogDtor_P,
|
||||
&NS_LogCOMPtrAddRef_P,
|
||||
&NS_LogCOMPtrRelease_P
|
||||
};
|
||||
|
||||
EXPORT_XPCOM_API(nsresult)
|
||||
NS_GetFrozenFunctions(XPCOMFunctions *functions, const char* /* libraryPath */)
|
||||
@ -221,6 +232,72 @@ NS_Free(void* ptr)
|
||||
NS_Free_P(ptr);
|
||||
}
|
||||
|
||||
#undef NS_DebugBreak
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_DebugBreak(PRUint32 aSeverity, const char *aStr, const char *aExpr,
|
||||
const char *aFile, PRInt32 aLine)
|
||||
{
|
||||
NS_DebugBreak_P(aSeverity, aStr, aExpr, aFile, aLine);
|
||||
}
|
||||
|
||||
#undef NS_LogInit
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogInit()
|
||||
{
|
||||
NS_LogInit_P();
|
||||
}
|
||||
|
||||
#undef NS_LogTerm
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogTerm()
|
||||
{
|
||||
NS_LogTerm_P();
|
||||
}
|
||||
|
||||
#undef NS_LogAddRef
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogAddRef(void* aPtr, nsrefcnt aNewRefCnt,
|
||||
const char *aTypeName, PRUint32 aInstanceSize)
|
||||
{
|
||||
NS_LogAddRef_P(aPtr, aNewRefCnt, aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
#undef NS_LogRelease
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogRelease(void* aPtr, nsrefcnt aNewRefCnt, const char *aTypeName)
|
||||
{
|
||||
NS_LogRelease_P(aPtr, aNewRefCnt, aTypeName);
|
||||
}
|
||||
|
||||
#undef NS_LogCtor
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogCtor(void *aPtr, const char *aTypeName, PRUint32 aInstanceSize)
|
||||
{
|
||||
NS_LogCtor_P(aPtr, aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
#undef NS_LogDtor
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogDtor(void *aPtr, const char *aTypeName, PRUint32 aInstanceSize)
|
||||
{
|
||||
NS_LogDtor_P(aPtr, aTypeName, aInstanceSize);
|
||||
}
|
||||
|
||||
#undef NS_LogCOMPtrAddRef
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogCOMPtrAddRef(void *aCOMPtr, nsISupports* aObject)
|
||||
{
|
||||
NS_LogCOMPtrAddRef_P(aCOMPtr, aObject);
|
||||
}
|
||||
|
||||
#undef NS_LogCOMPtrRelease
|
||||
EXPORT_XPCOM_API(void)
|
||||
NS_LogCOMPtrRelease(void *aCOMPtr, nsISupports* aObject)
|
||||
{
|
||||
NS_LogCOMPtrRelease_P(aCOMPtr, aObject);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Stubs for nsXPCOMPrivate.h
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user