LCOV - code coverage report
Current view: top level - gfx/src - gfxCrashReporterUtils.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 28 47 59.6 %
Date: 2017-07-14 16:53:18 Functions: 9 17 52.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "gfxCrashReporterUtils.h"
       7             : 
       8             : #if defined(MOZ_CRASHREPORTER)
       9             : #define MOZ_GFXFEATUREREPORTER 1
      10             : #endif
      11             : 
      12             : #ifdef MOZ_GFXFEATUREREPORTER
      13             : #include "gfxCrashReporterUtils.h"
      14             : #include <string.h>                     // for strcmp
      15             : #include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
      16             : #include "mozilla/Services.h"           // for GetObserverService
      17             : #include "mozilla/StaticMutex.h"
      18             : #include "mozilla/SystemGroup.h"        // for SystemGroup
      19             : #include "mozilla/mozalloc.h"           // for operator new, etc
      20             : #include "mozilla/RefPtr.h"             // for RefPtr
      21             : #include "MainThreadUtils.h"            // for NS_IsMainThread
      22             : #include "nsCOMPtr.h"                   // for nsCOMPtr
      23             : #include "nsError.h"                    // for NS_OK, NS_FAILED, nsresult
      24             : #include "nsExceptionHandler.h"         // for AppendAppNotesToCrashReport
      25             : #include "nsID.h"
      26             : #include "nsIEventTarget.h"             // for NS_DISPATCH_NORMAL
      27             : #include "nsIObserver.h"                // for nsIObserver, etc
      28             : #include "nsIObserverService.h"         // for nsIObserverService
      29             : #include "nsIRunnable.h"                // for nsIRunnable
      30             : #include "nsISupports.h"
      31             : #include "nsTArray.h"                   // for nsTArray
      32             : #include "nscore.h"                     // for NS_IMETHOD, NS_IMETHODIMP, etc
      33             : 
      34             : namespace mozilla {
      35             : 
      36             : static nsTArray<nsCString> *gFeaturesAlreadyReported = nullptr;
      37           3 : static StaticMutex gFeaturesAlreadyReportedMutex;
      38             : 
      39             : class ObserverToDestroyFeaturesAlreadyReported final : public nsIObserver
      40             : {
      41             : 
      42             : public:
      43             :   NS_DECL_ISUPPORTS
      44             :   NS_DECL_NSIOBSERVER
      45             : 
      46           2 :   ObserverToDestroyFeaturesAlreadyReported() {}
      47             : private:
      48           0 :   virtual ~ObserverToDestroyFeaturesAlreadyReported() {}
      49             : };
      50             : 
      51           6 : NS_IMPL_ISUPPORTS(ObserverToDestroyFeaturesAlreadyReported,
      52             :                   nsIObserver)
      53             : 
      54             : NS_IMETHODIMP
      55           0 : ObserverToDestroyFeaturesAlreadyReported::Observe(nsISupports* aSubject,
      56             :                                                   const char* aTopic,
      57             :                                                   const char16_t* aData)
      58             : {
      59           0 :   if (!strcmp(aTopic, "xpcom-shutdown")) {
      60           0 :     StaticMutexAutoLock al(gFeaturesAlreadyReportedMutex);
      61           0 :     if (gFeaturesAlreadyReported) {
      62           0 :       delete gFeaturesAlreadyReported;
      63           0 :       gFeaturesAlreadyReported = nullptr;
      64             :     }
      65             :   }
      66           0 :   return NS_OK;
      67             : }
      68             : 
      69           6 : class RegisterObserverRunnable : public Runnable {
      70             : public:
      71           3 :   RegisterObserverRunnable() : Runnable("RegisterObserverRunnable") {}
      72           2 :   NS_IMETHOD Run() override {
      73             :     // LeakLog made me do this. Basically, I just wanted gFeaturesAlreadyReported to be a static nsTArray<nsCString>,
      74             :     // and LeakLog was complaining about leaks like this:
      75             :     //    leaked 1 instance of nsTArray_base with size 8 bytes
      76             :     //    leaked 7 instances of nsStringBuffer with size 8 bytes each (56 bytes total)
      77             :     // So this is a work-around using a pointer, and using a nsIObserver to deallocate on xpcom shutdown.
      78             :     // Yay for fighting bloat.
      79           4 :     nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
      80           2 :     if (!observerService)
      81           0 :       return NS_OK;
      82           4 :     RefPtr<ObserverToDestroyFeaturesAlreadyReported> observer = new ObserverToDestroyFeaturesAlreadyReported;
      83           2 :     observerService->AddObserver(observer, "xpcom-shutdown", false);
      84           2 :     return NS_OK;
      85             :   }
      86             : };
      87             : 
      88           0 : class AppendAppNotesRunnable : public CancelableRunnable {
      89             : public:
      90           0 :   explicit AppendAppNotesRunnable(const nsACString& aFeatureStr)
      91           0 :     : CancelableRunnable("AppendAppNotesRunnable")
      92           0 :     , mFeatureString(aFeatureStr)
      93             :   {
      94           0 :   }
      95             : 
      96           0 :   NS_IMETHOD Run() override {
      97           0 :     CrashReporter::AppendAppNotesToCrashReport(mFeatureString);
      98           0 :     return NS_OK;
      99             :   }
     100             : 
     101             : private:
     102             :   nsAutoCString mFeatureString;
     103             : };
     104             : 
     105             : void
     106           6 : ScopedGfxFeatureReporter::WriteAppNote(char statusChar)
     107             : {
     108          12 :   StaticMutexAutoLock al(gFeaturesAlreadyReportedMutex);
     109             : 
     110           6 :   if (!gFeaturesAlreadyReported) {
     111           3 :     gFeaturesAlreadyReported = new nsTArray<nsCString>;
     112           6 :     nsCOMPtr<nsIRunnable> r = new RegisterObserverRunnable();
     113             :     SystemGroup::Dispatch("ScopedGfxFeatureReporter::RegisterObserverRunnable",
     114           3 :                           TaskCategory::Other, r.forget());
     115             :   }
     116             : 
     117          12 :   nsAutoCString featureString;
     118           6 :   featureString.AppendPrintf("%s%c ",
     119             :                              mFeature,
     120           6 :                              statusChar);
     121             : 
     122           6 :   if (!gFeaturesAlreadyReported->Contains(featureString)) {
     123           6 :     gFeaturesAlreadyReported->AppendElement(featureString);
     124           6 :     AppNote(featureString);
     125             :   }
     126           6 : }
     127             : 
     128             : void
     129           9 : ScopedGfxFeatureReporter::AppNote(const nsACString& aMessage)
     130             : {
     131           9 :   if (NS_IsMainThread()) {
     132           9 :     CrashReporter::AppendAppNotesToCrashReport(aMessage);
     133             :   } else {
     134           0 :     nsCOMPtr<nsIRunnable> r = new AppendAppNotesRunnable(aMessage);
     135             :     SystemGroup::Dispatch("ScopedGfxFeatureReporter::AppendAppNotesRunnable",
     136           0 :                           TaskCategory::Other, r.forget());
     137             :   }
     138           9 : }
     139             :   
     140             : } // end namespace mozilla
     141             : 
     142             : #else
     143             : 
     144             : namespace mozilla {
     145             : void ScopedGfxFeatureReporter::WriteAppNote(char) {}
     146             : void ScopedGfxFeatureReporter::AppNote(const nsACString&) {}
     147             :   
     148             : } // namespace mozilla
     149             : 
     150             : #endif

Generated by: LCOV version 1.13