LCOV - code coverage report
Current view: top level - xpcom/base - nsDebugImpl.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 44 159 27.7 %
Date: 2017-07-14 16:53:18 Functions: 6 24 25.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : // Chromium headers must come before Mozilla headers.
       8             : #include "base/process_util.h"
       9             : 
      10             : #include "mozilla/Atomics.h"
      11             : #include "mozilla/Printf.h"
      12             : 
      13             : #include "nsDebugImpl.h"
      14             : #include "nsDebug.h"
      15             : #ifdef MOZ_CRASHREPORTER
      16             : # include "nsExceptionHandler.h"
      17             : #endif
      18             : #include "nsString.h"
      19             : #include "nsXULAppAPI.h"
      20             : #include "prprf.h"
      21             : #include "nsError.h"
      22             : #include "prerror.h"
      23             : #include "prerr.h"
      24             : #include "prenv.h"
      25             : 
      26             : #ifdef ANDROID
      27             : #include <android/log.h>
      28             : #endif
      29             : 
      30             : #ifdef _WIN32
      31             : /* for getenv() */
      32             : #include <stdlib.h>
      33             : #endif
      34             : 
      35             : #include "nsTraceRefcnt.h"
      36             : 
      37             : #if defined(XP_UNIX)
      38             : #include <signal.h>
      39             : #endif
      40             : 
      41             : #if defined(XP_WIN)
      42             : #include <tchar.h>
      43             : #include "nsString.h"
      44             : #endif
      45             : 
      46             : #if defined(XP_MACOSX) || defined(__DragonFly__) || defined(__FreeBSD__) \
      47             :  || defined(__NetBSD__) || defined(__OpenBSD__)
      48             : #include <stdbool.h>
      49             : #include <unistd.h>
      50             : #include <sys/param.h>
      51             : #include <sys/sysctl.h>
      52             : #endif
      53             : 
      54             : #if defined(__OpenBSD__)
      55             : #include <sys/proc.h>
      56             : #endif
      57             : 
      58             : #if defined(__DragonFly__) || defined(__FreeBSD__)
      59             : #include <sys/user.h>
      60             : #endif
      61             : 
      62             : #if defined(__NetBSD__)
      63             : #undef KERN_PROC
      64             : #define KERN_PROC KERN_PROC2
      65             : #define KINFO_PROC struct kinfo_proc2
      66             : #else
      67             : #define KINFO_PROC struct kinfo_proc
      68             : #endif
      69             : 
      70             : #if defined(XP_MACOSX)
      71             : #define KP_FLAGS kp_proc.p_flag
      72             : #elif defined(__DragonFly__)
      73             : #define KP_FLAGS kp_flags
      74             : #elif defined(__FreeBSD__)
      75             : #define KP_FLAGS ki_flag
      76             : #elif defined(__OpenBSD__) && !defined(_P_TRACED)
      77             : #define KP_FLAGS p_psflags
      78             : #define P_TRACED PS_TRACED
      79             : #else
      80             : #define KP_FLAGS p_flag
      81             : #endif
      82             : 
      83             : #include "mozilla/mozalloc_abort.h"
      84             : 
      85             : static void
      86             : Abort(const char* aMsg);
      87             : 
      88             : static void
      89             : RealBreak();
      90             : 
      91             : static void
      92             : Break(const char* aMsg);
      93             : 
      94             : #if defined(_WIN32)
      95             : #include <windows.h>
      96             : #include <signal.h>
      97             : #include <malloc.h> // for _alloca
      98             : #elif defined(XP_UNIX)
      99             : #include <stdlib.h>
     100             : #endif
     101             : 
     102             : using namespace mozilla;
     103             : 
     104             : static const char* sMultiprocessDescription = nullptr;
     105             : 
     106             : static Atomic<int32_t> gAssertionCount;
     107             : 
     108           0 : NS_IMPL_QUERY_INTERFACE(nsDebugImpl, nsIDebug2)
     109             : 
     110             : NS_IMETHODIMP_(MozExternalRefCountType)
     111           0 : nsDebugImpl::AddRef()
     112             : {
     113           0 :   return 2;
     114             : }
     115             : 
     116             : NS_IMETHODIMP_(MozExternalRefCountType)
     117           0 : nsDebugImpl::Release()
     118             : {
     119           0 :   return 1;
     120             : }
     121             : 
     122             : NS_IMETHODIMP
     123           0 : nsDebugImpl::Assertion(const char* aStr, const char* aExpr,
     124             :                        const char* aFile, int32_t aLine)
     125             : {
     126           0 :   NS_DebugBreak(NS_DEBUG_ASSERTION, aStr, aExpr, aFile, aLine);
     127           0 :   return NS_OK;
     128             : }
     129             : 
     130             : NS_IMETHODIMP
     131           0 : nsDebugImpl::Warning(const char* aStr, const char* aFile, int32_t aLine)
     132             : {
     133           0 :   NS_DebugBreak(NS_DEBUG_WARNING, aStr, nullptr, aFile, aLine);
     134           0 :   return NS_OK;
     135             : }
     136             : 
     137             : NS_IMETHODIMP
     138           0 : nsDebugImpl::Break(const char* aFile, int32_t aLine)
     139             : {
     140           0 :   NS_DebugBreak(NS_DEBUG_BREAK, nullptr, nullptr, aFile, aLine);
     141           0 :   return NS_OK;
     142             : }
     143             : 
     144             : NS_IMETHODIMP
     145           0 : nsDebugImpl::Abort(const char* aFile, int32_t aLine)
     146             : {
     147           0 :   NS_DebugBreak(NS_DEBUG_ABORT, nullptr, nullptr, aFile, aLine);
     148           0 :   return NS_OK;
     149             : }
     150             : 
     151             : // From toolkit/library/rust/lib.rs
     152             : extern "C" void intentional_panic(const char* message);
     153             : 
     154             : NS_IMETHODIMP
     155           0 : nsDebugImpl::RustPanic(const char* aMessage)
     156             : {
     157           0 :   intentional_panic(aMessage);
     158           0 :   return NS_OK;
     159             : }
     160             : 
     161             : NS_IMETHODIMP
     162           0 : nsDebugImpl::GetIsDebugBuild(bool* aResult)
     163             : {
     164             : #ifdef DEBUG
     165           0 :   *aResult = true;
     166             : #else
     167             :   *aResult = false;
     168             : #endif
     169           0 :   return NS_OK;
     170             : }
     171             : 
     172             : NS_IMETHODIMP
     173           0 : nsDebugImpl::GetAssertionCount(int32_t* aResult)
     174             : {
     175           0 :   *aResult = gAssertionCount;
     176           0 :   return NS_OK;
     177             : }
     178             : 
     179             : NS_IMETHODIMP
     180           0 : nsDebugImpl::GetIsDebuggerAttached(bool* aResult)
     181             : {
     182           0 :   *aResult = false;
     183             : 
     184             : #if defined(XP_WIN)
     185             :   *aResult = ::IsDebuggerPresent();
     186             : #elif defined(XP_MACOSX) || defined(__DragonFly__) || defined(__FreeBSD__) \
     187             :    || defined(__NetBSD__) || defined(__OpenBSD__)
     188             :   // Specify the info we're looking for
     189             :   int mib[] = {
     190             :     CTL_KERN,
     191             :     KERN_PROC,
     192             :     KERN_PROC_PID,
     193             :     getpid(),
     194             : #if defined(__NetBSD__) || defined(__OpenBSD__)
     195             :     sizeof(KINFO_PROC),
     196             :     1,
     197             : #endif
     198             :   };
     199             :   u_int mibSize = sizeof(mib) / sizeof(int);
     200             : 
     201             :   KINFO_PROC info;
     202             :   size_t infoSize = sizeof(info);
     203             :   memset(&info, 0, infoSize);
     204             : 
     205             :   if (sysctl(mib, mibSize, &info, &infoSize, nullptr, 0)) {
     206             :     // if the call fails, default to false
     207             :     *aResult = false;
     208             :     return NS_OK;
     209             :   }
     210             : 
     211             :   if (info.KP_FLAGS & P_TRACED) {
     212             :     *aResult = true;
     213             :   }
     214             : #endif
     215             : 
     216           0 :   return NS_OK;
     217             : }
     218             : 
     219             : /* static */ void
     220           4 : nsDebugImpl::SetMultiprocessMode(const char* aDesc)
     221             : {
     222           4 :   sMultiprocessDescription = aDesc;
     223           4 : }
     224             : 
     225             : /**
     226             :  * Implementation of the nsDebug methods. Note that this code is
     227             :  * always compiled in, in case some other module that uses it is
     228             :  * compiled with debugging even if this library is not.
     229             :  */
     230             : enum nsAssertBehavior
     231             : {
     232             :   NS_ASSERT_UNINITIALIZED,
     233             :   NS_ASSERT_WARN,
     234             :   NS_ASSERT_SUSPEND,
     235             :   NS_ASSERT_STACK,
     236             :   NS_ASSERT_TRAP,
     237             :   NS_ASSERT_ABORT,
     238             :   NS_ASSERT_STACK_AND_ABORT
     239             : };
     240             : 
     241             : static nsAssertBehavior
     242           0 : GetAssertBehavior()
     243             : {
     244             :   static nsAssertBehavior gAssertBehavior = NS_ASSERT_UNINITIALIZED;
     245           0 :   if (gAssertBehavior != NS_ASSERT_UNINITIALIZED) {
     246           0 :     return gAssertBehavior;
     247             :   }
     248             : 
     249           0 :   gAssertBehavior = NS_ASSERT_WARN;
     250             : 
     251           0 :   const char* assertString = PR_GetEnv("XPCOM_DEBUG_BREAK");
     252           0 :   if (!assertString || !*assertString) {
     253           0 :     return gAssertBehavior;
     254             :   }
     255           0 :   if (!strcmp(assertString, "warn")) {
     256           0 :     return gAssertBehavior = NS_ASSERT_WARN;
     257             :   }
     258           0 :   if (!strcmp(assertString, "suspend")) {
     259           0 :     return gAssertBehavior = NS_ASSERT_SUSPEND;
     260             :   }
     261           0 :   if (!strcmp(assertString, "stack")) {
     262           0 :     return gAssertBehavior = NS_ASSERT_STACK;
     263             :   }
     264           0 :   if (!strcmp(assertString, "abort")) {
     265           0 :     return gAssertBehavior = NS_ASSERT_ABORT;
     266             :   }
     267           0 :   if (!strcmp(assertString, "trap") || !strcmp(assertString, "break")) {
     268           0 :     return gAssertBehavior = NS_ASSERT_TRAP;
     269             :   }
     270           0 :   if (!strcmp(assertString, "stack-and-abort")) {
     271           0 :     return gAssertBehavior = NS_ASSERT_STACK_AND_ABORT;
     272             :   }
     273             : 
     274           0 :   fprintf(stderr, "Unrecognized value of XPCOM_DEBUG_BREAK\n");
     275           0 :   return gAssertBehavior;
     276             : }
     277             : 
     278          22 : struct FixedBuffer final : public mozilla::PrintfTarget
     279             : {
     280          22 :   FixedBuffer() : curlen(0)
     281             :   {
     282          22 :     buffer[0] = '\0';
     283          22 :   }
     284             : 
     285             :   char buffer[500];
     286             :   uint32_t curlen;
     287             : 
     288             :   bool append(const char* sp, size_t len);
     289             : };
     290             : 
     291             : bool
     292         305 : FixedBuffer::append(const char* aBuf, size_t aLen)
     293             : {
     294         305 :   if (!aLen) {
     295           0 :     return true;
     296             :   }
     297             : 
     298         305 :   if (curlen + aLen >= sizeof(buffer)) {
     299           0 :     aLen = sizeof(buffer) - curlen - 1;
     300             :   }
     301             : 
     302         305 :   if (aLen) {
     303         305 :     memcpy(buffer + curlen, aBuf, aLen);
     304         305 :     curlen += aLen;
     305         305 :     buffer[curlen] = '\0';
     306             :   }
     307             : 
     308         305 :   return true;
     309             : }
     310             : 
     311             : EXPORT_XPCOM_API(void)
     312          11 : NS_DebugBreak(uint32_t aSeverity, const char* aStr, const char* aExpr,
     313             :               const char* aFile, int32_t aLine)
     314             : {
     315          11 :   FixedBuffer nonPIDBuf;
     316          11 :   FixedBuffer buf;
     317          11 :   const char* sevString = "WARNING";
     318             : 
     319          11 :   switch (aSeverity) {
     320             :     case NS_DEBUG_ASSERTION:
     321           0 :       sevString = "###!!! ASSERTION";
     322           0 :       break;
     323             : 
     324             :     case NS_DEBUG_BREAK:
     325           0 :       sevString = "###!!! BREAK";
     326           0 :       break;
     327             : 
     328             :     case NS_DEBUG_ABORT:
     329           0 :       sevString = "###!!! ABORT";
     330           0 :       break;
     331             : 
     332             :     default:
     333          11 :       aSeverity = NS_DEBUG_WARNING;
     334             :   }
     335             : 
     336          11 :   nonPIDBuf.print("%s: ", sevString);
     337          11 :   if (aStr) {
     338           4 :     nonPIDBuf.print("%s: ", aStr);
     339             :   }
     340          11 :   if (aExpr) {
     341           7 :     nonPIDBuf.print("'%s', ", aExpr);
     342             :   }
     343          11 :   if (aFile) {
     344          11 :     nonPIDBuf.print("file %s, ", aFile);
     345             :   }
     346          11 :   if (aLine != -1) {
     347          11 :     nonPIDBuf.print("line %d", aLine);
     348             :   }
     349             : 
     350             :   // Print "[PID]" or "[Desc PID]" at the beginning of the message.
     351          11 :   buf.print("[");
     352          11 :   if (sMultiprocessDescription) {
     353           8 :     buf.print("%s ", sMultiprocessDescription);
     354             :   }
     355          11 :   buf.print("%d] %s", base::GetCurrentProcId(), nonPIDBuf.buffer);
     356             : 
     357             : 
     358             :   // errors on platforms without a debugdlg ring a bell on stderr
     359             : #if !defined(XP_WIN)
     360          11 :   if (aSeverity != NS_DEBUG_WARNING) {
     361           0 :     fprintf(stderr, "\07");
     362             :   }
     363             : #endif
     364             : 
     365             : #ifdef ANDROID
     366             :   __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", buf.buffer);
     367             : #endif
     368             : 
     369             :   // Write the message to stderr unless it's a warning and MOZ_IGNORE_WARNINGS
     370             :   // is set.
     371          11 :   if (!(PR_GetEnv("MOZ_IGNORE_WARNINGS") && aSeverity == NS_DEBUG_WARNING)) {
     372          11 :     fprintf(stderr, "%s\n", buf.buffer);
     373          11 :     fflush(stderr);
     374             :   }
     375             : 
     376          11 :   switch (aSeverity) {
     377             :     case NS_DEBUG_WARNING:
     378          11 :       return;
     379             : 
     380             :     case NS_DEBUG_BREAK:
     381           0 :       Break(buf.buffer);
     382           0 :       return;
     383             : 
     384             :     case NS_DEBUG_ABORT: {
     385             : #if defined(MOZ_CRASHREPORTER)
     386             :       // Updating crash annotations in the child causes us to do IPC. This can
     387             :       // really cause trouble if we're asserting from within IPC code. So we
     388             :       // have to do without the annotations in that case.
     389           0 :       if (XRE_IsParentProcess()) {
     390             :         // Don't include the PID in the crash report annotation to
     391             :         // allow faceting on crash-stats.mozilla.org.
     392           0 :         nsCString note("xpcom_runtime_abort(");
     393           0 :         note += nonPIDBuf.buffer;
     394           0 :         note += ")";
     395           0 :         CrashReporter::AppendAppNotesToCrashReport(note);
     396           0 :         CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AbortMessage"),
     397           0 :                                            nsDependentCString(nonPIDBuf.buffer));
     398             :       }
     399             : #endif  // MOZ_CRASHREPORTER
     400             : 
     401             : #if defined(DEBUG) && defined(_WIN32)
     402             :       RealBreak();
     403             : #endif
     404             : #if defined(DEBUG)
     405           0 :       nsTraceRefcnt::WalkTheStack(stderr);
     406             : #endif
     407           0 :       Abort(buf.buffer);
     408           0 :       return;
     409             :     }
     410             :   }
     411             : 
     412             :   // Now we deal with assertions
     413           0 :   gAssertionCount++;
     414             : 
     415           0 :   switch (GetAssertBehavior()) {
     416             :     case NS_ASSERT_WARN:
     417           0 :       return;
     418             : 
     419             :     case NS_ASSERT_SUSPEND:
     420             : #ifdef XP_UNIX
     421           0 :       fprintf(stderr, "Suspending process; attach with the debugger.\n");
     422           0 :       kill(0, SIGSTOP);
     423             : #else
     424             :       Break(buf.buffer);
     425             : #endif
     426           0 :       return;
     427             : 
     428             :     case NS_ASSERT_STACK:
     429           0 :       nsTraceRefcnt::WalkTheStack(stderr);
     430           0 :       return;
     431             : 
     432             :     case NS_ASSERT_STACK_AND_ABORT:
     433           0 :       nsTraceRefcnt::WalkTheStack(stderr);
     434             :       // Fall through to abort
     435             :       MOZ_FALLTHROUGH;
     436             : 
     437             :     case NS_ASSERT_ABORT:
     438           0 :       Abort(buf.buffer);
     439           0 :       return;
     440             : 
     441             :     case NS_ASSERT_TRAP:
     442             :     case NS_ASSERT_UNINITIALIZED: // Default to "trap" behavior
     443           0 :       Break(buf.buffer);
     444           0 :       return;
     445             :   }
     446             : }
     447             : 
     448             : static void
     449           0 : Abort(const char* aMsg)
     450             : {
     451           0 :   mozalloc_abort(aMsg);
     452             : }
     453             : 
     454             : static void
     455           0 : RealBreak()
     456             : {
     457             : #if defined(_WIN32)
     458             :   ::DebugBreak();
     459             : #elif defined(XP_MACOSX)
     460             :   raise(SIGTRAP);
     461             : #elif defined(__GNUC__) && (defined(__i386__) || defined(__i386) || defined(__x86_64__))
     462           0 :   asm("int $3");
     463             : #elif defined(__arm__)
     464             :   asm(
     465             : #ifdef __ARM_ARCH_4T__
     466             :     /* ARMv4T doesn't support the BKPT instruction, so if the compiler target
     467             :      * is ARMv4T, we want to ensure the assembler will understand that ARMv5T
     468             :      * instruction, while keeping the resulting object tagged as ARMv4T.
     469             :      */
     470             :     ".arch armv5t\n"
     471             :     ".object_arch armv4t\n"
     472             : #endif
     473             :     "BKPT #0");
     474             : #elif defined(__aarch64__)
     475             :   asm("brk #0");
     476             : #elif defined(SOLARIS)
     477             : #if defined(__i386__) || defined(__i386) || defined(__x86_64__)
     478             :   asm("int $3");
     479             : #else
     480             :   raise(SIGTRAP);
     481             : #endif
     482             : #else
     483             : #warning do not know how to break on this platform
     484             : #endif
     485           0 : }
     486             : 
     487             : // Abort() calls this function, don't call it!
     488             : static void
     489           0 : Break(const char* aMsg)
     490             : {
     491             : #if defined(_WIN32)
     492             :   static int ignoreDebugger;
     493             :   if (!ignoreDebugger) {
     494             :     const char* shouldIgnoreDebugger = getenv("XPCOM_DEBUG_DLG");
     495             :     ignoreDebugger =
     496             :       1 + (shouldIgnoreDebugger && !strcmp(shouldIgnoreDebugger, "1"));
     497             :   }
     498             :   if ((ignoreDebugger == 2) || !::IsDebuggerPresent()) {
     499             :     DWORD code = IDRETRY;
     500             : 
     501             :     /* Create the debug dialog out of process to avoid the crashes caused by
     502             :      * Windows events leaking into our event loop from an in process dialog.
     503             :      * We do this by launching windbgdlg.exe (built in xpcom/windbgdlg).
     504             :      * See http://bugzilla.mozilla.org/show_bug.cgi?id=54792
     505             :      */
     506             :     PROCESS_INFORMATION pi;
     507             :     STARTUPINFOW si;
     508             :     wchar_t executable[MAX_PATH];
     509             :     wchar_t* pName;
     510             : 
     511             :     memset(&pi, 0, sizeof(pi));
     512             : 
     513             :     memset(&si, 0, sizeof(si));
     514             :     si.cb          = sizeof(si);
     515             :     si.wShowWindow = SW_SHOW;
     516             : 
     517             :     // 2nd arg of CreateProcess is in/out
     518             :     wchar_t* msgCopy = (wchar_t*)_alloca((strlen(aMsg) + 1) * sizeof(wchar_t));
     519             :     wcscpy(msgCopy, NS_ConvertUTF8toUTF16(aMsg).get());
     520             : 
     521             :     if (GetModuleFileNameW(GetModuleHandleW(L"xpcom.dll"), executable, MAX_PATH) &&
     522             :         (pName = wcsrchr(executable, '\\')) != nullptr &&
     523             :         wcscpy(pName + 1, L"windbgdlg.exe") &&
     524             :         CreateProcessW(executable, msgCopy, nullptr, nullptr,
     525             :                        false, DETACHED_PROCESS | NORMAL_PRIORITY_CLASS,
     526             :                        nullptr, nullptr, &si, &pi)) {
     527             :       WaitForSingleObject(pi.hProcess, INFINITE);
     528             :       GetExitCodeProcess(pi.hProcess, &code);
     529             :       CloseHandle(pi.hProcess);
     530             :       CloseHandle(pi.hThread);
     531             :     }
     532             : 
     533             :     switch (code) {
     534             :       case IDABORT:
     535             :         //This should exit us
     536             :         raise(SIGABRT);
     537             :         //If we are ignored exit this way..
     538             :         _exit(3);
     539             : 
     540             :       case IDIGNORE:
     541             :         return;
     542             :     }
     543             :   }
     544             : 
     545             :   RealBreak();
     546             : #elif defined(XP_MACOSX)
     547             :   /* Note that we put this Mac OS X test above the GNUC/x86 test because the
     548             :    * GNUC/x86 test is also true on Intel Mac OS X and we want the PPC/x86
     549             :    * impls to be the same.
     550             :    */
     551             :   RealBreak();
     552             : #elif defined(__GNUC__) && (defined(__i386__) || defined(__i386) || defined(__x86_64__))
     553           0 :   RealBreak();
     554             : #elif defined(__arm__) || defined(__aarch64__)
     555             :   RealBreak();
     556             : #elif defined(SOLARIS)
     557             :   RealBreak();
     558             : #else
     559             : #warning do not know how to break on this platform
     560             : #endif
     561           0 : }
     562             : 
     563             : nsresult
     564           0 : nsDebugImpl::Create(nsISupports* aOuter, const nsIID& aIID, void** aInstancePtr)
     565             : {
     566             :   static const nsDebugImpl* sImpl;
     567             : 
     568           0 :   if (NS_WARN_IF(aOuter)) {
     569           0 :     return NS_ERROR_NO_AGGREGATION;
     570             :   }
     571             : 
     572           0 :   if (!sImpl) {
     573           0 :     sImpl = new nsDebugImpl();
     574             :   }
     575             : 
     576           0 :   return const_cast<nsDebugImpl*>(sImpl)->QueryInterface(aIID, aInstancePtr);
     577             : }
     578             : 
     579             : ////////////////////////////////////////////////////////////////////////////////
     580             : 
     581             : nsresult
     582          10 : NS_ErrorAccordingToNSPR()
     583             : {
     584          10 :   PRErrorCode err = PR_GetError();
     585          10 :   switch (err) {
     586           0 :     case PR_OUT_OF_MEMORY_ERROR:         return NS_ERROR_OUT_OF_MEMORY;
     587           0 :     case PR_WOULD_BLOCK_ERROR:           return NS_BASE_STREAM_WOULD_BLOCK;
     588          10 :     case PR_FILE_NOT_FOUND_ERROR:        return NS_ERROR_FILE_NOT_FOUND;
     589           0 :     case PR_READ_ONLY_FILESYSTEM_ERROR:  return NS_ERROR_FILE_READ_ONLY;
     590           0 :     case PR_NOT_DIRECTORY_ERROR:         return NS_ERROR_FILE_NOT_DIRECTORY;
     591           0 :     case PR_IS_DIRECTORY_ERROR:          return NS_ERROR_FILE_IS_DIRECTORY;
     592           0 :     case PR_LOOP_ERROR:                  return NS_ERROR_FILE_UNRESOLVABLE_SYMLINK;
     593           0 :     case PR_FILE_EXISTS_ERROR:           return NS_ERROR_FILE_ALREADY_EXISTS;
     594           0 :     case PR_FILE_IS_LOCKED_ERROR:        return NS_ERROR_FILE_IS_LOCKED;
     595           0 :     case PR_FILE_TOO_BIG_ERROR:          return NS_ERROR_FILE_TOO_BIG;
     596           0 :     case PR_NO_DEVICE_SPACE_ERROR:       return NS_ERROR_FILE_NO_DEVICE_SPACE;
     597           0 :     case PR_NAME_TOO_LONG_ERROR:         return NS_ERROR_FILE_NAME_TOO_LONG;
     598           0 :     case PR_DIRECTORY_NOT_EMPTY_ERROR:   return NS_ERROR_FILE_DIR_NOT_EMPTY;
     599           0 :     case PR_NO_ACCESS_RIGHTS_ERROR:      return NS_ERROR_FILE_ACCESS_DENIED;
     600           0 :     default:                             return NS_ERROR_FAILURE;
     601             :   }
     602             : }
     603             : 
     604             : void
     605           0 : NS_ABORT_OOM(size_t aSize)
     606             : {
     607             : #if defined(MOZ_CRASHREPORTER)
     608           0 :   CrashReporter::AnnotateOOMAllocationSize(aSize);
     609             : #endif
     610           0 :   MOZ_CRASH("OOM");
     611             : }

Generated by: LCOV version 1.13