Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/build/XPCOMInit.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "base/basictypes.h"
8
9
#include "mozilla/Atomics.h"
10
#include "mozilla/Poison.h"
11
#include "mozilla/SharedThreadPool.h"
12
#include "mozilla/XPCOM.h"
13
#include "nsXULAppAPI.h"
14
15
#ifndef ANDROID
16
#include "nsTerminator.h"
17
#endif
18
19
#include "nsXPCOMPrivate.h"
20
#include "nsXPCOMCIDInternal.h"
21
22
#include "mozilla/layers/ImageBridgeChild.h"
23
#include "mozilla/layers/CompositorBridgeParent.h"
24
#include "mozilla/dom/VideoDecoderManagerChild.h"
25
26
#include "prlink.h"
27
28
#include "nsCycleCollector.h"
29
#include "nsObserverList.h"
30
#include "nsObserverService.h"
31
#include "nsScriptableInputStream.h"
32
#include "nsBinaryStream.h"
33
#include "nsStorageStream.h"
34
#include "nsPipe.h"
35
#include "nsScriptableBase64Encoder.h"
36
37
#include "nsMemoryImpl.h"
38
#include "nsDebugImpl.h"
39
#include "nsTraceRefcnt.h"
40
#include "nsErrorService.h"
41
42
#include "nsArray.h"
43
#include "nsINIParserImpl.h"
44
#include "nsSupportsPrimitives.h"
45
#include "nsConsoleService.h"
46
47
#include "nsComponentManager.h"
48
#include "nsCategoryManagerUtils.h"
49
#include "nsIServiceManager.h"
50
51
#include "nsThreadManager.h"
52
#include "nsThreadPool.h"
53
54
#include "nsTimerImpl.h"
55
#include "TimerThread.h"
56
57
#include "nsThread.h"
58
#include "nsProcess.h"
59
#include "nsEnvironment.h"
60
#include "nsVersionComparatorImpl.h"
61
62
#include "nsIFile.h"
63
#include "nsLocalFile.h"
64
#if defined(XP_UNIX)
65
#include "nsNativeCharsetUtils.h"
66
#endif
67
#include "nsDirectoryService.h"
68
#include "nsDirectoryServiceDefs.h"
69
#include "nsCategoryManager.h"
70
#include "nsICategoryManager.h"
71
#include "nsMultiplexInputStream.h"
72
73
#include "nsStringStream.h"
74
extern nsresult nsStringInputStreamConstructor(nsISupports*, REFNSIID, void**);
75
76
#include "nsAtomTable.h"
77
#include "nsISupportsImpl.h"
78
79
#include "nsHashPropertyBag.h"
80
81
#include "nsUnicharInputStream.h"
82
#include "nsVariant.h"
83
84
#include "nsUUIDGenerator.h"
85
86
#include "nsIOUtil.h"
87
88
#include "SpecialSystemDirectory.h"
89
90
#if defined(XP_WIN)
91
#include "nsWindowsRegKey.h"
92
#endif
93
94
#ifdef MOZ_WIDGET_COCOA
95
#include "nsMacUtilsImpl.h"
96
#endif
97
98
#include "nsSystemInfo.h"
99
#include "nsMemoryReporterManager.h"
100
#include "nsMemoryInfoDumper.h"
101
#include "nsSecurityConsoleMessage.h"
102
#include "nsMessageLoop.h"
103
#include "nss.h"
104
#include "ssl.h"
105
106
#include <locale.h>
107
#include "mozilla/Services.h"
108
#include "mozilla/Omnijar.h"
109
#include "mozilla/ScriptPreloader.h"
110
#include "mozilla/SystemGroup.h"
111
#include "mozilla/Telemetry.h"
112
#include "mozilla/BackgroundHangMonitor.h"
113
114
#include "nsChromeRegistry.h"
115
#include "nsChromeProtocolHandler.h"
116
#include "mozilla/PoisonIOInterposer.h"
117
#include "mozilla/LateWriteChecks.h"
118
119
#include "mozilla/scache/StartupCache.h"
120
121
#include "base/at_exit.h"
122
#include "base/command_line.h"
123
#include "base/message_loop.h"
124
125
#include "mozilla/ipc/BrowserProcessSubThread.h"
126
#include "mozilla/AvailableMemoryTracker.h"
127
#include "mozilla/ClearOnShutdown.h"
128
#include "mozilla/CountingAllocatorBase.h"
129
#include "mozilla/UniquePtr.h"
130
131
#include "mozilla/ipc/GeckoChildProcessHost.h"
132
133
#include "ogg/ogg.h"
134
#if defined(MOZ_VPX) && !defined(MOZ_VPX_NO_MEM_REPORTING)
135
#if defined(HAVE_STDINT_H)
136
// mozilla-config.h defines HAVE_STDINT_H, and then it's defined *again* in
137
// vpx_config.h (which we include via vpx_mem.h, below). This redefinition
138
// triggers a build warning on MSVC, so we have to #undef it first.
139
#undef HAVE_STDINT_H
140
#endif
141
#include "vpx_mem/vpx_mem.h"
142
#endif
143
144
#include "GeckoProfiler.h"
145
146
#include "jsapi.h"
147
#include "js/Initialization.h"
148
149
#include "gfxPlatform.h"
150
151
using namespace mozilla;
152
using base::AtExitManager;
153
using mozilla::ipc::BrowserProcessSubThread;
154
155
// From toolkit/library/rust/lib.rs
156
extern "C" void GkRust_Init();
157
extern "C" void GkRust_Shutdown();
158
159
namespace {
160
161
static AtExitManager* sExitManager;
162
static MessageLoop* sMessageLoop;
163
static bool sCommandLineWasInitialized;
164
static BrowserProcessSubThread* sIOThread;
165
static BackgroundHangMonitor* sMainHangMonitor;
166
167
} /* anonymous namespace */
168
169
// Registry Factory creation function defined in nsRegistry.cpp
170
// We hook into this function locally to create and register the registry
171
// Since noone outside xpcom needs to know about this and nsRegistry.cpp
172
// does not have a local include file, we are putting this definition
173
// here rather than in nsIRegistry.h
174
extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
175
extern nsresult NS_CategoryManagerGetFactory(nsIFactory**);
176
177
#ifdef XP_WIN
178
extern nsresult CreateAnonTempFileRemover();
179
#endif
180
181
NS_GENERIC_FACTORY_CONSTRUCTOR(nsProcess)
182
183
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsID)
184
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsString)
185
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCString)
186
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRBool)
187
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint8)
188
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint16)
189
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint32)
190
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint64)
191
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRTime)
192
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsChar)
193
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt16)
194
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt32)
195
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt64)
196
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsFloat)
197
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsDouble)
198
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsInterfacePointer)
199
200
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsConsoleService, Init)
201
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimer)
202
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryOutputStream)
203
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryInputStream)
204
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageStream)
205
NS_GENERIC_FACTORY_CONSTRUCTOR(nsVersionComparatorImpl)
206
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptableBase64Encoder)
207
208
NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariantCC)
209
210
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHashPropertyBagCC)
211
212
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
213
214
#ifdef MOZ_WIDGET_COCOA
215
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl)
216
#endif
217
218
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemInfo, Init)
219
220
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMemoryReporterManager, Init)
221
222
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMemoryInfoDumper)
223
224
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIOUtil)
225
226
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSecurityConsoleMessage)
227
228
static nsresult
229
nsThreadManagerGetSingleton(nsISupports* aOuter,
230
                            const nsIID& aIID,
231
                            void** aInstancePtr)
232
0
{
233
0
  NS_ASSERTION(aInstancePtr, "null outptr");
234
0
  if (NS_WARN_IF(aOuter)) {
235
0
    return NS_ERROR_NO_AGGREGATION;
236
0
  }
237
0
238
0
  return nsThreadManager::get().QueryInterface(aIID, aInstancePtr);
239
0
}
240
241
nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = nullptr;
242
bool gXPCOMShuttingDown = false;
243
bool gXPCOMThreadsShutDown = false;
244
char16_t* gGREBinPath = nullptr;
245
246
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
247
static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID);
248
249
NS_DEFINE_NAMED_CID(NS_CHROMEREGISTRY_CID);
250
NS_DEFINE_NAMED_CID(NS_CHROMEPROTOCOLHANDLER_CID);
251
252
NS_DEFINE_NAMED_CID(NS_SECURITY_CONSOLE_MESSAGE_CID);
253
254
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsChromeRegistry,
255
                                         nsChromeRegistry::GetSingleton)
256
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
257
258
static already_AddRefed<nsIFactory>
259
CreateINIParserFactory(const mozilla::Module& aModule,
260
                       const mozilla::Module::CIDEntry& aEntry)
261
0
{
262
0
  nsCOMPtr<nsIFactory> f = new nsINIParserFactory();
263
0
  return f.forget();
264
0
}
265
266
#define COMPONENT(NAME, Ctor) static NS_DEFINE_CID(kNS_##NAME##_CID, NS_##NAME##_CID);
267
#define COMPONENT_M(NAME, Ctor, Selector) static NS_DEFINE_CID(kNS_##NAME##_CID, NS_##NAME##_CID);
268
#include "XPCOMModule.inc"
269
#undef COMPONENT
270
#undef COMPONENT_M
271
272
#define COMPONENT(NAME, Ctor) { &kNS_##NAME##_CID, false, nullptr, Ctor },
273
#define COMPONENT_M(NAME, Ctor, Selector) { &kNS_##NAME##_CID, false, nullptr, Ctor, Selector },
274
const mozilla::Module::CIDEntry kXPCOMCIDEntries[] = {
275
  { &kComponentManagerCID, true, nullptr, nsComponentManagerImpl::Create, Module::ALLOW_IN_GPU_PROCESS },
276
  { &kINIParserFactoryCID, false, CreateINIParserFactory },
277
#include "XPCOMModule.inc"
278
  { &kNS_CHROMEREGISTRY_CID, false, nullptr, nsChromeRegistryConstructor },
279
  { &kNS_CHROMEPROTOCOLHANDLER_CID, false, nullptr, nsChromeProtocolHandlerConstructor },
280
  { &kNS_SECURITY_CONSOLE_MESSAGE_CID, false, nullptr, nsSecurityConsoleMessageConstructor },
281
  { nullptr }
282
};
283
#undef COMPONENT
284
#undef COMPONENT_M
285
286
#define COMPONENT(NAME, Ctor) { NS_##NAME##_CONTRACTID, &kNS_##NAME##_CID },
287
#define COMPONENT_M(NAME, Ctor, Selector) { NS_##NAME##_CONTRACTID, &kNS_##NAME##_CID, Selector },
288
const mozilla::Module::ContractIDEntry kXPCOMContracts[] = {
289
#include "XPCOMModule.inc"
290
  { NS_CHROMEREGISTRY_CONTRACTID, &kNS_CHROMEREGISTRY_CID },
291
  { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome", &kNS_CHROMEPROTOCOLHANDLER_CID },
292
  { NS_INIPARSERFACTORY_CONTRACTID, &kINIParserFactoryCID },
293
  { NS_SECURITY_CONSOLE_MESSAGE_CONTRACTID, &kNS_SECURITY_CONSOLE_MESSAGE_CID },
294
  { nullptr }
295
};
296
#undef COMPONENT
297
#undef COMPONENT_M
298
299
const mozilla::Module kXPCOMModule = {
300
  mozilla::Module::kVersion, kXPCOMCIDEntries, kXPCOMContracts,
301
  nullptr,
302
  nullptr,
303
  nullptr,
304
  nullptr,
305
  Module::ALLOW_IN_GPU_PROCESS
306
};
307
308
// gDebug will be freed during shutdown.
309
static nsIDebug2* gDebug = nullptr;
310
311
EXPORT_XPCOM_API(nsresult)
312
NS_GetDebug(nsIDebug2** aResult)
313
0
{
314
0
  return nsDebugImpl::Create(nullptr,  NS_GET_IID(nsIDebug2), (void**)aResult);
315
0
}
316
317
EXPORT_XPCOM_API(nsresult)
318
NS_InitXPCOM(nsIServiceManager** aResult,
319
             nsIFile* aBinDirectory)
320
0
{
321
0
  return NS_InitXPCOM2(aResult, aBinDirectory, nullptr);
322
0
}
323
324
class ICUReporter final
325
  : public nsIMemoryReporter
326
  , public CountingAllocatorBase<ICUReporter>
327
{
328
public:
329
  NS_DECL_ISUPPORTS
330
331
  static void* Alloc(const void*, size_t aSize)
332
2.52k
  {
333
2.52k
    return CountingMalloc(aSize);
334
2.52k
  }
335
336
  static void* Realloc(const void*, void* aPtr, size_t aSize)
337
0
  {
338
0
    return CountingRealloc(aPtr, aSize);
339
0
  }
340
341
  static void Free(const void*, void* aPtr)
342
2.47k
  {
343
2.47k
    return CountingFree(aPtr);
344
2.47k
  }
345
346
private:
347
  NS_IMETHOD
348
  CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
349
                 bool aAnonymize) override
350
0
  {
351
0
    MOZ_COLLECT_REPORT(
352
0
      "explicit/icu", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
353
0
      "Memory used by ICU, a Unicode and globalization support library.");
354
0
355
0
    return NS_OK;
356
0
  }
357
358
0
  ~ICUReporter() {}
359
};
360
361
NS_IMPL_ISUPPORTS(ICUReporter, nsIMemoryReporter)
362
363
/* static */ template<> CountingAllocatorBase<ICUReporter>::AmountType
364
CountingAllocatorBase<ICUReporter>::sAmount(0);
365
366
class OggReporter final
367
  : public nsIMemoryReporter
368
  , public CountingAllocatorBase<OggReporter>
369
{
370
public:
371
  NS_DECL_ISUPPORTS
372
373
private:
374
  NS_IMETHOD
375
  CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
376
                 bool aAnonymize) override
377
0
  {
378
0
    MOZ_COLLECT_REPORT(
379
0
      "explicit/media/libogg", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
380
0
      "Memory allocated through libogg for Ogg, Theora, and related media "
381
0
      "files.");
382
0
383
0
    return NS_OK;
384
0
  }
385
386
0
  ~OggReporter() {}
387
};
388
389
NS_IMPL_ISUPPORTS(OggReporter, nsIMemoryReporter)
390
391
/* static */ template<> CountingAllocatorBase<OggReporter>::AmountType
392
CountingAllocatorBase<OggReporter>::sAmount(0);
393
394
#ifdef MOZ_VPX
395
class VPXReporter final
396
  : public nsIMemoryReporter
397
  , public CountingAllocatorBase<VPXReporter>
398
{
399
public:
400
  NS_DECL_ISUPPORTS
401
402
private:
403
  NS_IMETHOD
404
  CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
405
                 bool aAnonymize) override
406
  {
407
    MOZ_COLLECT_REPORT(
408
      "explicit/media/libvpx", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
409
      "Memory allocated through libvpx for WebM media files.");
410
411
    return NS_OK;
412
  }
413
414
  ~VPXReporter() {}
415
};
416
417
NS_IMPL_ISUPPORTS(VPXReporter, nsIMemoryReporter)
418
419
/* static */ template<> Atomic<size_t>
420
CountingAllocatorBase<VPXReporter>::sAmount(0);
421
#endif /* MOZ_VPX */
422
423
#ifdef ENABLE_BIGINT
424
class GMPReporter final
425
  : public nsIMemoryReporter
426
  , public CountingAllocatorBase<GMPReporter>
427
{
428
public:
429
  NS_DECL_ISUPPORTS
430
431
  static void* Alloc(size_t size)
432
  {
433
    return CountingMalloc(size);
434
  }
435
436
  static void* Realloc(void* ptr, size_t oldSize, size_t newSize)
437
  {
438
    return CountingRealloc(ptr, newSize);
439
  }
440
441
  static void Free(void* ptr, size_t size)
442
  {
443
    return CountingFree(ptr);
444
  }
445
446
private:
447
  NS_IMETHOD
448
  CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
449
                 bool aAnonymize) override
450
  {
451
    MOZ_COLLECT_REPORT(
452
      "explicit/gmp", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
453
      "Memory allocated through libgmp for BigInt arithmetic.");
454
455
    return NS_OK;
456
  }
457
458
  ~GMPReporter() {}
459
};
460
461
NS_IMPL_ISUPPORTS(GMPReporter, nsIMemoryReporter)
462
463
/* static */ template<> Atomic<size_t>
464
CountingAllocatorBase<GMPReporter>::sAmount(0);
465
#endif // ENABLE_BIGINT
466
467
static bool sInitializedJS = false;
468
469
// Note that on OSX, aBinDirectory will point to .app/Contents/Resources/browser
470
EXPORT_XPCOM_API(nsresult)
471
NS_InitXPCOM2(nsIServiceManager** aResult,
472
              nsIFile* aBinDirectory,
473
              nsIDirectoryServiceProvider* aAppFileLocationProvider)
474
3
{
475
3
  static bool sInitialized = false;
476
3
  if (sInitialized) {
477
0
    return NS_ERROR_FAILURE;
478
0
  }
479
3
480
3
  sInitialized = true;
481
3
482
3
  mozPoisonValueInit();
483
3
484
3
  NS_LogInit();
485
3
486
3
  NS_InitAtomTable();
487
3
488
3
  // We don't have the arguments by hand here.  If logging has already been
489
3
  // initialized by a previous call to LogModule::Init with the arguments
490
3
  // passed, passing (0, nullptr) is alright here.
491
3
  mozilla::LogModule::Init(0, nullptr);
492
3
493
3
  GkRust_Init();
494
3
495
3
  nsresult rv = NS_OK;
496
3
497
3
  // We are not shutting down
498
3
  gXPCOMShuttingDown = false;
499
3
500
3
#ifdef XP_UNIX
501
3
  // Discover the current value of the umask, and save it where
502
3
  // nsSystemInfo::Init can retrieve it when necessary.  There is no way
503
3
  // to read the umask without changing it, and the setting is process-
504
3
  // global, so this must be done while we are still single-threaded; the
505
3
  // nsSystemInfo object is typically created much later, when some piece
506
3
  // of chrome JS wants it.  The system call is specified as unable to fail.
507
3
  nsSystemInfo::gUserUmask = ::umask(0777);
508
3
  ::umask(nsSystemInfo::gUserUmask);
509
3
#endif
510
3
511
3
  // Set up chromium libs
512
3
  NS_ASSERTION(!sExitManager && !sMessageLoop, "Bad logic!");
513
3
514
3
  if (!AtExitManager::AlreadyRegistered()) {
515
3
    sExitManager = new AtExitManager();
516
3
  }
517
3
518
3
  MessageLoop* messageLoop = MessageLoop::current();
519
3
  if (!messageLoop) {
520
3
    sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_PARENT);
521
3
    sMessageLoop->set_thread_name("Gecko");
522
3
    // Set experimental values for main thread hangs:
523
3
    // 128ms for transient hangs and 8192ms for permanent hangs
524
3
    sMessageLoop->set_hang_timeouts(128, 8192);
525
3
  } else if (messageLoop->type() == MessageLoop::TYPE_MOZILLA_CHILD) {
526
0
    messageLoop->set_thread_name("Gecko_Child");
527
0
    messageLoop->set_hang_timeouts(128, 8192);
528
0
  }
529
3
530
3
  if (XRE_IsParentProcess() &&
531
3
      !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) {
532
3
    UniquePtr<BrowserProcessSubThread> ioThread = MakeUnique<BrowserProcessSubThread>(BrowserProcessSubThread::IO);
533
3
534
3
    base::Thread::Options options;
535
3
    options.message_loop_type = MessageLoop::TYPE_IO;
536
3
    if (NS_WARN_IF(!ioThread->StartWithOptions(options))) {
537
0
      return NS_ERROR_FAILURE;
538
0
    }
539
3
540
3
    sIOThread = ioThread.release();
541
3
  }
542
3
543
3
  // Establish the main thread here.
544
3
  rv = nsThreadManager::get().Init();
545
3
  if (NS_WARN_IF(NS_FAILED(rv))) {
546
0
    return rv;
547
0
  }
548
3
549
3
  // Init the SystemGroup for dispatching main thread runnables.
550
3
  SystemGroup::InitStatic();
551
3
552
3
  // Set up the timer globals/timer thread
553
3
  rv = nsTimerImpl::Startup();
554
3
  if (NS_WARN_IF(NS_FAILED(rv))) {
555
0
    return rv;
556
0
  }
557
3
558
3
#ifndef ANDROID
559
3
  // If the locale hasn't already been setup by our embedder,
560
3
  // get us out of the "C" locale and into the system
561
3
  if (strcmp(setlocale(LC_ALL, nullptr), "C") == 0) {
562
3
    setlocale(LC_ALL, "");
563
3
  }
564
3
#endif
565
3
566
3
  nsDirectoryService::RealInit();
567
3
568
3
  bool value;
569
3
570
3
  if (aBinDirectory) {
571
0
    rv = aBinDirectory->IsDirectory(&value);
572
0
573
0
    if (NS_SUCCEEDED(rv) && value) {
574
0
      nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR,
575
0
                                        aBinDirectory);
576
0
    }
577
0
  }
578
3
579
3
  if (aAppFileLocationProvider) {
580
3
    rv = nsDirectoryService::gService->RegisterProvider(aAppFileLocationProvider);
581
3
    if (NS_FAILED(rv)) {
582
0
      return rv;
583
0
    }
584
3
  }
585
3
586
3
  nsCOMPtr<nsIFile> xpcomLib;
587
3
  nsDirectoryService::gService->Get(NS_GRE_BIN_DIR,
588
3
                                    NS_GET_IID(nsIFile),
589
3
                                    getter_AddRefs(xpcomLib));
590
3
  MOZ_ASSERT(xpcomLib);
591
3
592
3
  // set gGREBinPath
593
3
  nsAutoString path;
594
3
  xpcomLib->GetPath(path);
595
3
  gGREBinPath = ToNewUnicode(path);
596
3
597
3
  xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
598
3
  nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
599
3
600
3
  if (!mozilla::Omnijar::IsInitialized()) {
601
3
    mozilla::Omnijar::Init();
602
3
  }
603
3
604
3
  if ((sCommandLineWasInitialized = !CommandLine::IsInitialized())) {
605
#ifdef OS_WIN
606
    CommandLine::Init(0, nullptr);
607
#else
608
    nsCOMPtr<nsIFile> binaryFile;
609
0
    nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
610
0
                                      NS_GET_IID(nsIFile),
611
0
                                      getter_AddRefs(binaryFile));
612
0
    if (NS_WARN_IF(!binaryFile)) {
613
0
      return NS_ERROR_FAILURE;
614
0
    }
615
0
616
0
    rv = binaryFile->AppendNative(NS_LITERAL_CSTRING("nonexistent-executable"));
617
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
618
0
      return rv;
619
0
    }
620
0
621
0
    nsCString binaryPath;
622
0
    rv = binaryFile->GetNativePath(binaryPath);
623
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
624
0
      return rv;
625
0
    }
626
0
627
0
    static char const* const argv = { strdup(binaryPath.get()) };
628
0
    CommandLine::Init(1, &argv);
629
0
#endif
630
0
  }
631
3
632
3
  NS_ASSERTION(nsComponentManagerImpl::gComponentManager == nullptr,
633
3
               "CompMgr not null at init");
634
3
635
3
  // Create the Component/Service Manager
636
3
  nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
637
3
  NS_ADDREF(nsComponentManagerImpl::gComponentManager);
638
3
639
3
  // Global cycle collector initialization.
640
3
  if (!nsCycleCollector_init()) {
641
0
    return NS_ERROR_UNEXPECTED;
642
0
  }
643
3
644
3
  // And start it up for this thread too.
645
3
  nsCycleCollector_startup();
646
3
647
3
  // Register ICU memory functions.  This really shouldn't be necessary: the
648
3
  // JS engine should do this on its own inside JS_Init, and memory-reporting
649
3
  // code should call a JSAPI function to observe ICU memory usage.  But we
650
3
  // can't define the alloc/free functions in the JS engine, because it can't
651
3
  // depend on the XPCOM-based memory reporting goop.  So for now, we have
652
3
  // this oddness.
653
3
  mozilla::SetICUMemoryFunctions();
654
3
655
3
  // Do the same for libogg.
656
3
  ogg_set_mem_functions(OggReporter::CountingMalloc,
657
3
                        OggReporter::CountingCalloc,
658
3
                        OggReporter::CountingRealloc,
659
3
                        OggReporter::CountingFree);
660
3
661
#if defined(MOZ_VPX) && !defined(MOZ_VPX_NO_MEM_REPORTING)
662
  // And for VPX.
663
  vpx_mem_set_functions(VPXReporter::CountingMalloc,
664
                        VPXReporter::CountingCalloc,
665
                        VPXReporter::CountingRealloc,
666
                        VPXReporter::CountingFree,
667
                        memcpy,
668
                        memset,
669
                        memmove);
670
#endif
671
672
#ifdef ENABLE_BIGINT
673
  // And for libgmp.
674
  mozilla::SetGMPMemoryFunctions();
675
#endif
676
677
3
  // Initialize the JS engine.
678
3
  const char* jsInitFailureReason = JS_InitWithFailureDiagnostic();
679
3
  if (jsInitFailureReason) {
680
0
    MOZ_CRASH_UNSAFE_OOL(jsInitFailureReason);
681
0
  }
682
3
  sInitializedJS = true;
683
3
684
3
  rv = nsComponentManagerImpl::gComponentManager->Init();
685
3
  if (NS_FAILED(rv)) {
686
0
    NS_RELEASE(nsComponentManagerImpl::gComponentManager);
687
0
    return rv;
688
0
  }
689
3
690
3
  if (aResult) {
691
3
    NS_ADDREF(*aResult = nsComponentManagerImpl::gComponentManager);
692
3
  }
693
3
694
3
  // After autoreg, but before we actually instantiate any components,
695
3
  // add any services listed in the "xpcom-directory-providers" category
696
3
  // to the directory service.
697
3
  nsDirectoryService::gService->RegisterCategoryProviders();
698
3
699
3
  // Init SharedThreadPool (which needs the service manager).
700
3
  SharedThreadPool::InitStatics();
701
3
702
3
  // Force layout to spin up so that nsContentUtils is available for cx stack
703
3
  // munging.  Note that layout registers a number of static atoms, and also
704
3
  // seals the static atom table, so NS_RegisterStaticAtom may not be called
705
3
  // beyond this point.
706
3
  nsCOMPtr<nsISupports> componentLoader =
707
3
    do_GetService("@mozilla.org/moz/jsloader;1");
708
3
709
3
  mozilla::ScriptPreloader::GetSingleton();
710
3
  mozilla::scache::StartupCache::GetSingleton();
711
3
  mozilla::AvailableMemoryTracker::Init();
712
3
713
3
  // Notify observers of xpcom autoregistration start
714
3
  NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY,
715
3
                                nullptr,
716
3
                                NS_XPCOM_STARTUP_OBSERVER_ID);
717
#ifdef XP_WIN
718
  CreateAnonTempFileRemover();
719
#endif
720
721
3
  // The memory reporter manager is up and running -- register our reporters.
722
3
  RegisterStrongMemoryReporter(new ICUReporter());
723
3
  RegisterStrongMemoryReporter(new OggReporter());
724
#ifdef MOZ_VPX
725
  RegisterStrongMemoryReporter(new VPXReporter());
726
#endif
727
728
3
  mozilla::Telemetry::Init();
729
3
730
3
  mozilla::BackgroundHangMonitor::Startup();
731
3
732
3
  const MessageLoop* const loop = MessageLoop::current();
733
3
  sMainHangMonitor = new mozilla::BackgroundHangMonitor(
734
3
    loop->thread_name().c_str(),
735
3
    loop->transient_hang_timeout(),
736
3
    loop->permanent_hang_timeout());
737
3
738
3
  return NS_OK;
739
3
}
740
741
EXPORT_XPCOM_API(nsresult)
742
NS_InitMinimalXPCOM()
743
0
{
744
0
  mozPoisonValueInit();
745
0
  NS_SetMainThread();
746
0
  mozilla::TimeStamp::Startup();
747
0
  NS_LogInit();
748
0
  NS_InitAtomTable();
749
0
750
0
  // We don't have the arguments by hand here.  If logging has already been
751
0
  // initialized by a previous call to LogModule::Init with the arguments
752
0
  // passed, passing (0, nullptr) is alright here.
753
0
  mozilla::LogModule::Init(0, nullptr);
754
0
755
0
  GkRust_Init();
756
0
757
0
  nsresult rv = nsThreadManager::get().Init();
758
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
759
0
    return rv;
760
0
  }
761
0
762
0
  // Init the SystemGroup for dispatching main thread runnables.
763
0
  SystemGroup::InitStatic();
764
0
765
0
  // Set up the timer globals/timer thread.
766
0
  rv = nsTimerImpl::Startup();
767
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
768
0
    return rv;
769
0
  }
770
0
771
0
  // Create the Component/Service Manager
772
0
  nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
773
0
  NS_ADDREF(nsComponentManagerImpl::gComponentManager);
774
0
775
0
  rv = nsComponentManagerImpl::gComponentManager->Init();
776
0
  if (NS_FAILED(rv)) {
777
0
    NS_RELEASE(nsComponentManagerImpl::gComponentManager);
778
0
    return rv;
779
0
  }
780
0
781
0
  // Global cycle collector initialization.
782
0
  if (!nsCycleCollector_init()) {
783
0
    return NS_ERROR_UNEXPECTED;
784
0
  }
785
0
786
0
  SharedThreadPool::InitStatics();
787
0
  mozilla::Telemetry::Init();
788
0
  mozilla::BackgroundHangMonitor::Startup();
789
0
790
0
  return NS_OK;
791
0
}
792
793
//
794
// NS_ShutdownXPCOM()
795
//
796
// The shutdown sequence for xpcom would be
797
//
798
// - Notify "xpcom-shutdown" for modules to release primary (root) references
799
// - Shutdown XPCOM timers
800
// - Notify "xpcom-shutdown-threads" for thread joins
801
// - Shutdown the event queues
802
// - Release the Global Service Manager
803
//   - Release all service instances held by the global service manager
804
//   - Release the Global Service Manager itself
805
// - Release the Component Manager
806
//   - Release all factories cached by the Component Manager
807
//   - Notify module loaders to shut down
808
//   - Unload Libraries
809
//   - Release Contractid Cache held by Component Manager
810
//   - Release dll abstraction held by Component Manager
811
//   - Release the Registry held by Component Manager
812
//   - Finally, release the component manager itself
813
//
814
EXPORT_XPCOM_API(nsresult)
815
NS_ShutdownXPCOM(nsIServiceManager* aServMgr)
816
0
{
817
0
  return mozilla::ShutdownXPCOM(aServMgr);
818
0
}
819
820
namespace mozilla {
821
822
void
823
SetICUMemoryFunctions()
824
3
{
825
3
  static bool sICUReporterInitialized = false;
826
3
  if (!sICUReporterInitialized) {
827
3
    if (!JS_SetICUMemoryFunctions(ICUReporter::Alloc, ICUReporter::Realloc,
828
3
                                  ICUReporter::Free)) {
829
0
      MOZ_CRASH("JS_SetICUMemoryFunctions failed.");
830
0
    }
831
3
    sICUReporterInitialized = true;
832
3
  }
833
3
}
834
835
#ifdef ENABLE_BIGINT
836
void
837
SetGMPMemoryFunctions()
838
{
839
  static bool sGMPReporterInitialized = false;
840
  if (!sGMPReporterInitialized) {
841
    JS::SetGMPMemoryFunctions(GMPReporter::Alloc,
842
                              GMPReporter::Realloc,
843
                              GMPReporter::Free);
844
    sGMPReporterInitialized = true;
845
  }
846
}
847
#endif
848
849
nsresult
850
ShutdownXPCOM(nsIServiceManager* aServMgr)
851
0
{
852
0
  // Make sure the hang monitor is enabled for shutdown.
853
0
  BackgroundHangMonitor().NotifyActivity();
854
0
855
0
  if (!NS_IsMainThread()) {
856
0
    MOZ_CRASH("Shutdown on wrong thread");
857
0
  }
858
0
859
0
  nsresult rv;
860
0
  nsCOMPtr<nsISimpleEnumerator> moduleLoaders;
861
0
862
0
  // Notify observers of xpcom shutting down
863
0
  {
864
0
    // Block it so that the COMPtr will get deleted before we hit
865
0
    // servicemanager shutdown
866
0
867
0
    nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
868
0
    if (NS_WARN_IF(!thread)) {
869
0
      return NS_ERROR_UNEXPECTED;
870
0
    }
871
0
872
0
    RefPtr<nsObserverService> observerService;
873
0
    CallGetService("@mozilla.org/observer-service;1",
874
0
                   (nsObserverService**)getter_AddRefs(observerService));
875
0
876
0
    if (observerService) {
877
0
      mozilla::KillClearOnShutdown(ShutdownPhase::WillShutdown);
878
0
      observerService->NotifyObservers(nullptr,
879
0
                                       NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID,
880
0
                                       nullptr);
881
0
882
0
      nsCOMPtr<nsIServiceManager> mgr;
883
0
      rv = NS_GetServiceManager(getter_AddRefs(mgr));
884
0
      if (NS_SUCCEEDED(rv)) {
885
0
        mozilla::KillClearOnShutdown(ShutdownPhase::Shutdown);
886
0
        observerService->NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
887
0
                                         nullptr);
888
0
      }
889
0
890
0
#ifndef ANDROID
891
0
      mozilla::XPCOMShutdownNotified();
892
0
#endif
893
0
    }
894
0
895
0
    // This must happen after the shutdown of media and widgets, which
896
0
    // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
897
0
    NS_ProcessPendingEvents(thread);
898
0
    gfxPlatform::ShutdownLayersIPC();
899
0
    mozilla::dom::VideoDecoderManagerChild::Shutdown();
900
0
901
0
    mozilla::scache::StartupCache::DeleteSingleton();
902
0
    if (observerService)
903
0
    {
904
0
      mozilla::KillClearOnShutdown(ShutdownPhase::ShutdownThreads);
905
0
      observerService->NotifyObservers(nullptr,
906
0
                                       NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
907
0
                                       nullptr);
908
0
    }
909
0
910
0
    gXPCOMThreadsShutDown = true;
911
0
    NS_ProcessPendingEvents(thread);
912
0
913
0
    // Shutdown the timer thread and all timers that might still be alive before
914
0
    // shutting down the component manager
915
0
    nsTimerImpl::Shutdown();
916
0
917
0
    NS_ProcessPendingEvents(thread);
918
0
919
0
    // Shutdown all remaining threads.  This method does not return until
920
0
    // all threads created using the thread manager (with the exception of
921
0
    // the main thread) have exited.
922
0
    nsThreadManager::get().Shutdown();
923
0
924
0
    NS_ProcessPendingEvents(thread);
925
0
926
0
    BackgroundHangMonitor().NotifyActivity();
927
0
928
0
    // Late-write checks needs to find the profile directory, so it has to
929
0
    // be initialized before mozilla::services::Shutdown or (because of
930
0
    // xpcshell tests replacing the service) modules being unloaded.
931
0
    mozilla::InitLateWriteChecks();
932
0
933
0
    // We save the "xpcom-shutdown-loaders" observers to notify after
934
0
    // the observerservice is gone.
935
0
    if (observerService) {
936
0
      mozilla::KillClearOnShutdown(ShutdownPhase::ShutdownLoaders);
937
0
      observerService->EnumerateObservers(NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
938
0
                                          getter_AddRefs(moduleLoaders));
939
0
940
0
      observerService->Shutdown();
941
0
    }
942
0
  }
943
0
944
0
  // Free ClearOnShutdown()'ed smart pointers.  This needs to happen *after*
945
0
  // we've finished notifying observers of XPCOM shutdown, because shutdown
946
0
  // observers themselves might call ClearOnShutdown().
947
0
  mozilla::KillClearOnShutdown(ShutdownPhase::ShutdownFinal);
948
0
949
0
  // XPCOM is officially in shutdown mode NOW
950
0
  // Set this only after the observers have been notified as this
951
0
  // will cause servicemanager to become inaccessible.
952
0
  mozilla::services::Shutdown();
953
0
954
0
  // We may have AddRef'd for the caller of NS_InitXPCOM, so release it
955
0
  // here again:
956
0
  NS_IF_RELEASE(aServMgr);
957
0
958
0
  // Shutdown global servicemanager
959
0
  if (nsComponentManagerImpl::gComponentManager) {
960
0
    nsComponentManagerImpl::gComponentManager->FreeServices();
961
0
  }
962
0
963
0
  // Release the directory service
964
0
  nsDirectoryService::gService = nullptr;
965
0
966
0
  free(gGREBinPath);
967
0
  gGREBinPath = nullptr;
968
0
969
0
  if (moduleLoaders) {
970
0
    bool more;
971
0
    nsCOMPtr<nsISupports> el;
972
0
    while (NS_SUCCEEDED(moduleLoaders->HasMoreElements(&more)) && more) {
973
0
      moduleLoaders->GetNext(getter_AddRefs(el));
974
0
975
0
      // Don't worry about weak-reference observers here: there is
976
0
      // no reason for weak-ref observers to register for
977
0
      // xpcom-shutdown-loaders
978
0
979
0
      // FIXME: This can cause harmless writes from sqlite committing
980
0
      // log files. We have to ignore them before we can move
981
0
      // the mozilla::PoisonWrite call before this point. See bug
982
0
      // 834945 for the details.
983
0
      nsCOMPtr<nsIObserver> obs(do_QueryInterface(el));
984
0
      if (obs) {
985
0
        obs->Observe(nullptr, NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID, nullptr);
986
0
      }
987
0
    }
988
0
989
0
    moduleLoaders = nullptr;
990
0
  }
991
0
992
0
  // Clear the profiler's JS context before cycle collection. The profiler will
993
0
  // notify the JS engine that it can let go of any data it's holding on to for
994
0
  // profiling purposes.
995
0
  PROFILER_CLEAR_JS_CONTEXT();
996
0
997
0
  bool shutdownCollect;
998
#ifdef NS_FREE_PERMANENT_DATA
999
  shutdownCollect = true;
1000
#else
1001
  shutdownCollect = !!PR_GetEnv("MOZ_CC_RUN_DURING_SHUTDOWN");
1002
0
#endif
1003
0
  nsCycleCollector_shutdown(shutdownCollect);
1004
0
1005
0
  PROFILER_ADD_MARKER("Shutdown xpcom");
1006
0
  // If we are doing any shutdown checks, poison writes.
1007
0
  if (gShutdownChecks != SCM_NOTHING) {
1008
#ifdef XP_MACOSX
1009
    mozilla::OnlyReportDirtyWrites();
1010
#endif /* XP_MACOSX */
1011
    mozilla::BeginLateWriteChecks();
1012
0
  }
1013
0
1014
0
  // Shutdown xpcom. This will release all loaders and cause others holding
1015
0
  // a refcount to the component manager to release it.
1016
0
  if (nsComponentManagerImpl::gComponentManager) {
1017
0
    rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
1018
0
    NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
1019
0
  } else {
1020
0
    NS_WARNING("Component Manager was never created ...");
1021
0
  }
1022
0
1023
0
  if (sInitializedJS) {
1024
0
    // Shut down the JS engine.
1025
0
    JS_ShutDown();
1026
0
    sInitializedJS = false;
1027
0
  }
1028
0
1029
0
  // After all threads have been joined and the component manager has been shut
1030
0
  // down, any remaining objects that could be holding NSS resources (should)
1031
0
  // have been released, so we can safely shut down NSS.
1032
0
  if (NSS_IsInitialized()) {
1033
0
    SSL_ClearSessionCache();
1034
0
    if (NSS_Shutdown() != SECSuccess) {
1035
0
      // If you're seeing this crash and/or warning, some NSS resources are
1036
0
      // still in use (see bugs 1417680 and 1230312).
1037
#if defined(DEBUG) && !defined(ANDROID)
1038
      MOZ_CRASH("NSS_Shutdown failed");
1039
#else
1040
0
      NS_WARNING("NSS_Shutdown failed");
1041
0
#endif
1042
0
    }
1043
0
  }
1044
0
1045
0
  // Finally, release the component manager last because it unloads the
1046
0
  // libraries:
1047
0
  if (nsComponentManagerImpl::gComponentManager) {
1048
0
    nsrefcnt cnt;
1049
0
    NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
1050
0
    NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
1051
0
  }
1052
0
  nsComponentManagerImpl::gComponentManager = nullptr;
1053
0
  nsCategoryManager::Destroy();
1054
0
1055
0
  // Shut down SystemGroup for main thread dispatching.
1056
0
  SystemGroup::Shutdown();
1057
0
1058
0
  GkRust_Shutdown();
1059
0
1060
0
  NS_ShutdownAtomTable();
1061
0
1062
0
  NS_IF_RELEASE(gDebug);
1063
0
1064
0
  delete sIOThread;
1065
0
  sIOThread = nullptr;
1066
0
1067
0
  delete sMessageLoop;
1068
0
  sMessageLoop = nullptr;
1069
0
1070
0
  if (sCommandLineWasInitialized) {
1071
0
    CommandLine::Terminate();
1072
0
    sCommandLineWasInitialized = false;
1073
0
  }
1074
0
1075
0
  delete sExitManager;
1076
0
  sExitManager = nullptr;
1077
0
1078
0
  Omnijar::CleanUp();
1079
0
1080
0
  BackgroundHangMonitor::Shutdown();
1081
0
1082
0
  delete sMainHangMonitor;
1083
0
  sMainHangMonitor = nullptr;
1084
0
1085
0
  NS_LogTerm();
1086
0
1087
0
  return NS_OK;
1088
0
}
1089
1090
} // namespace mozilla