Bug 675396 - Fennec Desktop: "error while loading shared libraries: libmozsqlite3.so". r=glandium
authorMounir Lamouri <mounir.lamouri@gmail.com>
Wed, 03 Aug 2011 11:22:07 -0700
changeset 73775 144add433e72577f4f2824ede07b91f08d868382
parent 73774 36b1761da39dbd75e2fe83786e3ecf0a589af4d3
child 73776 225a79ce27bcb6d379b4cd82ee05273ab22bf974
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersglandium
bugs675396
milestone8.0a1
Bug 675396 - Fennec Desktop: "error while loading shared libraries: libmozsqlite3.so". r=glandium
mobile/app/Makefile.in
mobile/app/nsBrowserApp.cpp
--- a/mobile/app/Makefile.in
+++ b/mobile/app/Makefile.in
@@ -49,46 +49,43 @@ DIST_FILES = application.ini
 
 ifndef LIBXUL_SDK
 PROGRAM=$(MOZ_APP_NAME)$(BIN_SUFFIX)
 
 CPPSRCS = nsBrowserApp.cpp
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
+LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
+
+DEFINES += -DXPCOM_GLUE
+STL_FLAGS=
 
 LIBS += $(JEMALLOC_LIBS)
 
-ifeq (Linux_1, $(OS_ARCH)_$(GNU_LD))
-OS_LDFLAGS += -Wl,-rpath='$$ORIGIN'
-NSDISTMODE = copy
-endif
-
 LIBS += \
-  $(XPCOM_GLUE_LDOPTS) \
-  $(NSPR_LIBS) \
+  $(EXTRA_DSO_LIBS) \
+  $(XPCOM_STANDALONE_GLUE_LDOPTS) \
   $(NULL)
 
-ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
-LIBS += $(DIST)/bin/XUL
-else
-EXTRA_DSO_LIBS += xul
-LIBS += $(EXTRA_DSO_LIBS)
-endif
 ifeq ($(OS_ARCH),WINNT)
 OS_LIBS += $(call EXPAND_LIBNAME,version)
 endif
 
 ifdef _MSC_VER
 # Always enter a Windows program through wmain, whether or not we're
 # a console application.
 WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
 endif
 endif #LIBXUL_SDK
 
+# This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that
+# shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall.
+NSDISTMODE = copy
+
 include $(topsrcdir)/config/rules.mk
 
 GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
 GRE_BUILDID = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build BuildID)
 ifndef MOZ_BUILD_DATE
 APP_BUILDID = $(shell $(PYTHON) $(topsrcdir)/toolkit/xre/make-platformini.py --print-buildid)
 else
 APP_BUILDID = $(MOZ_BUILD_DATE)
--- a/mobile/app/nsBrowserApp.cpp
+++ b/mobile/app/nsBrowserApp.cpp
@@ -31,39 +31,49 @@
  * 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 "nsXPCOMGlue.h"
 #include "nsXULAppAPI.h"
-#ifdef XP_WIN
+#if defined(XP_WIN)
 #include <windows.h>
 #include <stdlib.h>
+#elif defined(XP_UNIX)
+#include <sys/time.h>
+#include <sys/resource.h>
 #endif
 
 #include <stdio.h>
 #include <stdarg.h>
+#include <string.h>
 
 #include "plstr.h"
 #include "prprf.h"
 #include "prenv.h"
 
 #include "nsCOMPtr.h"
 #include "nsILocalFile.h"
 #include "nsStringGlue.h"
 
 #ifdef XP_WIN
-// we want to use the DLL blocklist if possible
-#define XRE_WANT_DLL_BLOCKLIST
 // we want a wmain entry point
 #include "nsWindowsWMain.cpp"
+#define snprintf _snprintf
+#define strcasecmp _stricmp
 #endif
+#include "BinaryPath.h"
+
+#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
+
+#include "mozilla/Telemetry.h"
 
 static void Output(const char *fmt, ... )
 {
   va_list ap;
   va_start(ap, fmt);
 
 #if defined(XP_WIN) && !MOZ_WINCONSOLE
   PRUnichar msg[2048];
@@ -80,50 +90,79 @@ static void Output(const char *fmt, ... 
  * Return true if |arg| matches the given argument name.
  */
 static PRBool IsArg(const char* arg, const char* s)
 {
   if (*arg == '-')
   {
     if (*++arg == '-')
       ++arg;
-    return !PL_strcasecmp(arg, s);
+    return !strcasecmp(arg, s);
   }
 
 #if defined(XP_WIN) || defined(XP_OS2)
   if (*arg == '/')
-    return !PL_strcasecmp(++arg, s);
+    return !strcasecmp(++arg, s);
 #endif
 
   return PR_FALSE;
 }
 
+/**
+ * A helper class which calls NS_LogInit/NS_LogTerm in its scope.
+ */
 class ScopedLogging
 {
 public:
   ScopedLogging() { NS_LogInit(); }
   ~ScopedLogging() { NS_LogTerm(); }
 };
 
-int main(int argc, char* argv[])
-{
-  ScopedLogging log;
+XRE_GetFileFromPathType XRE_GetFileFromPath;
+XRE_CreateAppDataType XRE_CreateAppData;
+XRE_FreeAppDataType XRE_FreeAppData;
+#ifdef XRE_HAS_DLL_BLOCKLIST
+XRE_SetupDllBlocklistType XRE_SetupDllBlocklist;
+#endif
+XRE_TelemetryAccumulateType XRE_TelemetryAccumulate;
+XRE_mainType XRE_main;
 
+static const nsDynamicFunctionLoad kXULFuncs[] = {
+    { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
+    { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
+    { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
+#ifdef XRE_HAS_DLL_BLOCKLIST
+    { "XRE_SetupDllBlocklist", (NSFuncPtr*) &XRE_SetupDllBlocklist },
+#endif
+    { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
+    { "XRE_main", (NSFuncPtr*) &XRE_main },
+    { nsnull, nsnull }
+};
+
+static int do_main(const char *exePath, int argc, char* argv[])
+{
   nsCOMPtr<nsILocalFile> appini;
-  nsresult rv = XRE_GetBinaryPath(argv[0], getter_AddRefs(appini));
+#ifdef XP_WIN
+  // exePath comes from mozilla::BinaryPath::Get, which returns a UTF-8
+  // encoded path, so it is safe to convert it
+  nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), PR_FALSE,
+                                getter_AddRefs(appini));
+#else
+  nsresult rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_FALSE,
+                                      getter_AddRefs(appini));
+#endif
   if (NS_FAILED(rv)) {
-    Output("Couldn't calculate the application directory.");
     return 255;
   }
+
   appini->SetNativeLeafName(NS_LITERAL_CSTRING("application.ini"));
 
   // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
   // Note that -app must be the *first* argument.
-  char *appEnv = nsnull;
-  const char *appDataFile = PR_GetEnv("XUL_APP_FILE");
+  const char *appDataFile = getenv("XUL_APP_FILE");
   if (appDataFile && *appDataFile) {
     rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
     if (NS_FAILED(rv)) {
       Output("Invalid path found: '%s'", appDataFile);
       return 255;
     }
   }
   else if (argc > 1 && IsArg(argv[1], "app")) {
@@ -133,28 +172,115 @@ int main(int argc, char* argv[])
     }
 
     rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
     if (NS_FAILED(rv)) {
       Output("application.ini path not recognized: '%s'", argv[2]);
       return 255;
     }
 
-    appEnv = PR_smprintf("XUL_APP_FILE=%s", argv[2]);
-    PR_SetEnv(appEnv);
+    char appEnv[MAXPATHLEN];
+    snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]);
+    if (putenv(appEnv)) {
+      Output("Couldn't set %s.\n", appEnv);
+      return 255;
+    }
     argv[2] = argv[0];
     argv += 2;
     argc -= 2;
   }
 
   nsXREAppData *appData;
   rv = XRE_CreateAppData(appini, &appData);
   if (NS_FAILED(rv)) {
     Output("Couldn't read application.ini");
     return 255;
   }
 
   int result = XRE_main(argc, argv, appData);
   XRE_FreeAppData(appData);
-  if (appEnv)
-    PR_smprintf_free(appEnv);
   return result;
 }
+
+int main(int argc, char* argv[])
+{
+  char exePath[MAXPATHLEN];
+
+  nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
+  if (NS_FAILED(rv)) {
+    Output("Couldn't calculate the application directory.\n");
+    return 255;
+  }
+
+  char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
+  if (!lastSlash || (lastSlash - exePath > MAXPATHLEN - sizeof(XPCOM_DLL) - 1))
+    return 255;
+
+  strcpy(++lastSlash, XPCOM_DLL);
+
+  int gotCounters;
+#if defined(XP_UNIX)
+  struct rusage initialRUsage;
+  gotCounters = !getrusage(RUSAGE_SELF, &initialRUsage);
+#elif defined(XP_WIN)
+  // GetProcessIoCounters().ReadOperationCount seems to have little to
+  // do with actual read operations. It reports 0 or 1 at this stage
+  // in the program. Luckily 1 coincides with when prefetch is
+  // enabled. If Windows prefetch didn't happen we can do our own
+  // faster dll preloading.
+  IO_COUNTERS ioCounters;
+  gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
+  if (gotCounters && !ioCounters.ReadOperationCount)
+#endif
+  {
+      XPCOMGlueEnablePreload();
+  }
+
+
+  rv = XPCOMGlueStartup(exePath);
+  if (NS_FAILED(rv)) {
+    Output("Couldn't load XPCOM.\n");
+    return 255;
+  }
+
+  rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
+  if (NS_FAILED(rv)) {
+    Output("Couldn't load XRE functions.\n");
+    return 255;
+  }
+
+#ifdef XRE_HAS_DLL_BLOCKLIST
+  XRE_SetupDllBlocklist();
+#endif
+
+  if (gotCounters) {
+#if defined(XP_WIN)
+    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS,
+                            int(ioCounters.ReadOperationCount));
+    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_TRANSFER,
+                            int(ioCounters.ReadTransferCount / 1024));
+    IO_COUNTERS newIoCounters;
+    if (GetProcessIoCounters(GetCurrentProcess(), &newIoCounters)) {
+      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_OPS,
+                              int(newIoCounters.ReadOperationCount - ioCounters.ReadOperationCount));
+      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_TRANSFER,
+                              int((newIoCounters.ReadTransferCount - ioCounters.ReadTransferCount) / 1024));
+    }
+#elif defined(XP_UNIX)
+    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_HARD_FAULTS,
+                            int(initialRUsage.ru_majflt));
+    struct rusage newRUsage;
+    if (!getrusage(RUSAGE_SELF, &newRUsage)) {
+      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_HARD_FAULTS,
+                              int(newRUsage.ru_majflt - initialRUsage.ru_majflt));
+    }
+#endif
+  }
+
+  int result;
+  {
+    ScopedLogging log;
+    result = do_main(exePath, argc, argv);
+  }
+
+  XPCOMGlueShutdown();
+  return result;
+}