xpcom/base/nsDebugImpl.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xpcom/base/nsDebugImpl.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,575 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +// Chromium headers must come before Mozilla headers.
    1.10 +#include "base/process_util.h"
    1.11 +
    1.12 +#include "mozilla/Atomics.h"
    1.13 +
    1.14 +#include "nsDebugImpl.h"
    1.15 +#include "nsDebug.h"
    1.16 +#ifdef MOZ_CRASHREPORTER
    1.17 +# include "nsExceptionHandler.h"
    1.18 +#endif
    1.19 +#include "nsString.h"
    1.20 +#include "prprf.h"
    1.21 +#include "prlog.h"
    1.22 +#include "nsError.h"
    1.23 +#include "prerror.h"
    1.24 +#include "prerr.h"
    1.25 +#include "prenv.h"
    1.26 +
    1.27 +#ifdef ANDROID
    1.28 +#include <android/log.h>
    1.29 +#endif
    1.30 +
    1.31 +#ifdef _WIN32
    1.32 +/* for getenv() */
    1.33 +#include <stdlib.h>
    1.34 +#endif
    1.35 +
    1.36 +#include "nsTraceRefcnt.h"
    1.37 +
    1.38 +#if defined(XP_UNIX)
    1.39 +#include <signal.h>
    1.40 +#endif
    1.41 +
    1.42 +#if defined(XP_WIN)
    1.43 +#include <tchar.h>
    1.44 +#include "nsString.h"
    1.45 +#ifdef MOZ_METRO
    1.46 +#include "nsWindowsHelpers.h"
    1.47 +#endif
    1.48 +#endif
    1.49 +
    1.50 +#if defined(XP_MACOSX)
    1.51 +#include <stdbool.h>
    1.52 +#include <unistd.h>
    1.53 +#include <sys/sysctl.h>
    1.54 +#endif
    1.55 +
    1.56 +#include "mozilla/mozalloc_abort.h"
    1.57 +
    1.58 +static void
    1.59 +Abort(const char *aMsg);
    1.60 +
    1.61 +static void
    1.62 +RealBreak();
    1.63 +
    1.64 +static void
    1.65 +Break(const char *aMsg);
    1.66 +
    1.67 +#if defined(_WIN32)
    1.68 +#include <windows.h>
    1.69 +#include <signal.h>
    1.70 +#include <malloc.h> // for _alloca
    1.71 +#elif defined(XP_UNIX)
    1.72 +#include <stdlib.h>
    1.73 +#endif
    1.74 +
    1.75 +using namespace mozilla;
    1.76 +
    1.77 +static const char *sMultiprocessDescription = nullptr;
    1.78 +
    1.79 +static Atomic<int32_t> gAssertionCount;
    1.80 +
    1.81 +NS_IMPL_QUERY_INTERFACE(nsDebugImpl, nsIDebug, nsIDebug2)
    1.82 +
    1.83 +NS_IMETHODIMP_(MozExternalRefCountType)
    1.84 +nsDebugImpl::AddRef()
    1.85 +{
    1.86 +  return 2;
    1.87 +}
    1.88 +
    1.89 +NS_IMETHODIMP_(MozExternalRefCountType)
    1.90 +nsDebugImpl::Release()
    1.91 +{
    1.92 +  return 1;
    1.93 +}
    1.94 +
    1.95 +NS_IMETHODIMP
    1.96 +nsDebugImpl::Assertion(const char *aStr, const char *aExpr,
    1.97 +                       const char *aFile, int32_t aLine)
    1.98 +{
    1.99 +  NS_DebugBreak(NS_DEBUG_ASSERTION, aStr, aExpr, aFile, aLine);
   1.100 +  return NS_OK;
   1.101 +}
   1.102 +
   1.103 +NS_IMETHODIMP
   1.104 +nsDebugImpl::Warning(const char *aStr, const char *aFile, int32_t aLine)
   1.105 +{
   1.106 +  NS_DebugBreak(NS_DEBUG_WARNING, aStr, nullptr, aFile, aLine);
   1.107 +  return NS_OK;
   1.108 +}
   1.109 +
   1.110 +NS_IMETHODIMP
   1.111 +nsDebugImpl::Break(const char *aFile, int32_t aLine)
   1.112 +{
   1.113 +  NS_DebugBreak(NS_DEBUG_BREAK, nullptr, nullptr, aFile, aLine);
   1.114 +  return NS_OK;
   1.115 +}
   1.116 +
   1.117 +NS_IMETHODIMP
   1.118 +nsDebugImpl::Abort(const char *aFile, int32_t aLine)
   1.119 +{
   1.120 +  NS_DebugBreak(NS_DEBUG_ABORT, nullptr, nullptr, aFile, aLine);
   1.121 +  return NS_OK;
   1.122 +}
   1.123 +
   1.124 +NS_IMETHODIMP
   1.125 +nsDebugImpl::GetIsDebugBuild(bool* aResult)
   1.126 +{
   1.127 +#ifdef DEBUG
   1.128 +  *aResult = true;
   1.129 +#else
   1.130 +  *aResult = false;
   1.131 +#endif
   1.132 +  return NS_OK;
   1.133 +}
   1.134 +
   1.135 +NS_IMETHODIMP
   1.136 +nsDebugImpl::GetAssertionCount(int32_t* aResult)
   1.137 +{
   1.138 +  *aResult = gAssertionCount;
   1.139 +  return NS_OK;
   1.140 +}
   1.141 +
   1.142 +NS_IMETHODIMP
   1.143 +nsDebugImpl::GetIsDebuggerAttached(bool* aResult)
   1.144 +{
   1.145 +  *aResult = false;
   1.146 +
   1.147 +#if defined(XP_WIN)
   1.148 +  *aResult = ::IsDebuggerPresent();
   1.149 +#elif defined(XP_MACOSX)
   1.150 +  // Specify the info we're looking for
   1.151 +  int mib[4];
   1.152 +  mib[0] = CTL_KERN;
   1.153 +  mib[1] = KERN_PROC;
   1.154 +  mib[2] = KERN_PROC_PID;
   1.155 +  mib[3] = getpid();
   1.156 +  size_t mibSize = sizeof(mib) / sizeof(int);
   1.157 +
   1.158 +  struct kinfo_proc info;
   1.159 +  size_t infoSize = sizeof(info);
   1.160 +  memset(&info, 0, infoSize);
   1.161 +
   1.162 +  if (sysctl(mib, mibSize, &info, &infoSize, nullptr, 0)) {
   1.163 +    // if the call fails, default to false
   1.164 +    *aResult = false;
   1.165 +    return NS_OK;
   1.166 +  }
   1.167 +
   1.168 +  if (info.kp_proc.p_flag & P_TRACED) {
   1.169 +    *aResult = true;
   1.170 +  }
   1.171 +#endif
   1.172 +
   1.173 +  return NS_OK;
   1.174 +}
   1.175 +
   1.176 +/* static */ void
   1.177 +nsDebugImpl::SetMultiprocessMode(const char *aDesc)
   1.178 +{
   1.179 +  sMultiprocessDescription = aDesc;
   1.180 +}
   1.181 +
   1.182 +/**
   1.183 + * Implementation of the nsDebug methods. Note that this code is
   1.184 + * always compiled in, in case some other module that uses it is
   1.185 + * compiled with debugging even if this library is not.
   1.186 + */
   1.187 +static PRLogModuleInfo* gDebugLog;
   1.188 +
   1.189 +static void InitLog(void)
   1.190 +{
   1.191 +  if (0 == gDebugLog) {
   1.192 +    gDebugLog = PR_NewLogModule("nsDebug");
   1.193 +  }
   1.194 +}
   1.195 +
   1.196 +enum nsAssertBehavior {
   1.197 +  NS_ASSERT_UNINITIALIZED,
   1.198 +  NS_ASSERT_WARN,
   1.199 +  NS_ASSERT_SUSPEND,
   1.200 +  NS_ASSERT_STACK,
   1.201 +  NS_ASSERT_TRAP,
   1.202 +  NS_ASSERT_ABORT,
   1.203 +  NS_ASSERT_STACK_AND_ABORT
   1.204 +};
   1.205 +
   1.206 +static nsAssertBehavior GetAssertBehavior()
   1.207 +{
   1.208 +  static nsAssertBehavior gAssertBehavior = NS_ASSERT_UNINITIALIZED;
   1.209 +  if (gAssertBehavior != NS_ASSERT_UNINITIALIZED)
   1.210 +    return gAssertBehavior;
   1.211 +
   1.212 +#if defined(XP_WIN) && defined(MOZ_METRO)
   1.213 +  if (IsRunningInWindowsMetro())
   1.214 +    gAssertBehavior = NS_ASSERT_WARN;
   1.215 +  else
   1.216 +    gAssertBehavior = NS_ASSERT_TRAP;
   1.217 +#elif defined(XP_WIN)
   1.218 +  gAssertBehavior = NS_ASSERT_TRAP;
   1.219 +#else
   1.220 +  gAssertBehavior = NS_ASSERT_WARN;
   1.221 +#endif
   1.222 +
   1.223 +  const char *assertString = PR_GetEnv("XPCOM_DEBUG_BREAK");
   1.224 +  if (!assertString || !*assertString)
   1.225 +    return gAssertBehavior;
   1.226 +
   1.227 +   if (!strcmp(assertString, "warn"))
   1.228 +     return gAssertBehavior = NS_ASSERT_WARN;
   1.229 +
   1.230 +   if (!strcmp(assertString, "suspend"))
   1.231 +     return gAssertBehavior = NS_ASSERT_SUSPEND;
   1.232 +
   1.233 +   if (!strcmp(assertString, "stack"))
   1.234 +     return gAssertBehavior = NS_ASSERT_STACK;
   1.235 +
   1.236 +   if (!strcmp(assertString, "abort"))
   1.237 +     return gAssertBehavior = NS_ASSERT_ABORT;
   1.238 +
   1.239 +   if (!strcmp(assertString, "trap") || !strcmp(assertString, "break"))
   1.240 +     return gAssertBehavior = NS_ASSERT_TRAP;
   1.241 +
   1.242 +   if (!strcmp(assertString, "stack-and-abort"))
   1.243 +     return gAssertBehavior = NS_ASSERT_STACK_AND_ABORT;
   1.244 +
   1.245 +   fprintf(stderr, "Unrecognized value of XPCOM_DEBUG_BREAK\n");
   1.246 +   return gAssertBehavior;
   1.247 +}
   1.248 +
   1.249 +struct FixedBuffer
   1.250 +{
   1.251 +  FixedBuffer() : curlen(0) { buffer[0] = '\0'; }
   1.252 +
   1.253 +  char buffer[1000];
   1.254 +  uint32_t curlen;
   1.255 +};
   1.256 +
   1.257 +static int
   1.258 +StuffFixedBuffer(void *closure, const char *buf, uint32_t len)
   1.259 +{
   1.260 +  if (!len)
   1.261 +    return 0;
   1.262 +  
   1.263 +  FixedBuffer *fb = (FixedBuffer*) closure;
   1.264 +
   1.265 +  // strip the trailing null, we add it again later
   1.266 +  if (buf[len - 1] == '\0')
   1.267 +    --len;
   1.268 +
   1.269 +  if (fb->curlen + len >= sizeof(fb->buffer))
   1.270 +    len = sizeof(fb->buffer) - fb->curlen - 1;
   1.271 +
   1.272 +  if (len) {
   1.273 +    memcpy(fb->buffer + fb->curlen, buf, len);
   1.274 +    fb->curlen += len;
   1.275 +    fb->buffer[fb->curlen] = '\0';
   1.276 +  }
   1.277 +
   1.278 +  return len;
   1.279 +}
   1.280 +
   1.281 +EXPORT_XPCOM_API(void)
   1.282 +NS_DebugBreak(uint32_t aSeverity, const char *aStr, const char *aExpr,
   1.283 +              const char *aFile, int32_t aLine)
   1.284 +{
   1.285 +   InitLog();
   1.286 +
   1.287 +   FixedBuffer buf;
   1.288 +   PRLogModuleLevel ll = PR_LOG_WARNING;
   1.289 +   const char *sevString = "WARNING";
   1.290 +
   1.291 +   switch (aSeverity) {
   1.292 +   case NS_DEBUG_ASSERTION:
   1.293 +     sevString = "###!!! ASSERTION";
   1.294 +     ll = PR_LOG_ERROR;
   1.295 +     break;
   1.296 +
   1.297 +   case NS_DEBUG_BREAK:
   1.298 +     sevString = "###!!! BREAK";
   1.299 +     ll = PR_LOG_ALWAYS;
   1.300 +     break;
   1.301 +
   1.302 +   case NS_DEBUG_ABORT:
   1.303 +     sevString = "###!!! ABORT";
   1.304 +     ll = PR_LOG_ALWAYS;
   1.305 +     break;
   1.306 +
   1.307 +   default:
   1.308 +     aSeverity = NS_DEBUG_WARNING;
   1.309 +   };
   1.310 +
   1.311 +#  define PrintToBuffer(...) PR_sxprintf(StuffFixedBuffer, &buf, __VA_ARGS__)
   1.312 +
   1.313 +   // Print "[PID]" or "[Desc PID]" at the beginning of the message.
   1.314 +   PrintToBuffer("[");
   1.315 +   if (sMultiprocessDescription) {
   1.316 +     PrintToBuffer("%s ", sMultiprocessDescription);
   1.317 +   }
   1.318 +   PrintToBuffer("%d] ", base::GetCurrentProcId());
   1.319 +
   1.320 +   PrintToBuffer("%s: ", sevString);
   1.321 +
   1.322 +   if (aStr)
   1.323 +     PrintToBuffer("%s: ", aStr);
   1.324 +
   1.325 +   if (aExpr)
   1.326 +     PrintToBuffer("'%s', ", aExpr);
   1.327 +
   1.328 +   if (aFile)
   1.329 +     PrintToBuffer("file %s, ", aFile);
   1.330 +
   1.331 +   if (aLine != -1)
   1.332 +     PrintToBuffer("line %d", aLine);
   1.333 +
   1.334 +#  undef PrintToBuffer
   1.335 +
   1.336 +   // Write out the message to the debug log
   1.337 +   PR_LOG(gDebugLog, ll, ("%s", buf.buffer));
   1.338 +   PR_LogFlush();
   1.339 +
   1.340 +   // errors on platforms without a debugdlg ring a bell on stderr
   1.341 +#if !defined(XP_WIN)
   1.342 +   if (ll != PR_LOG_WARNING)
   1.343 +     fprintf(stderr, "\07");
   1.344 +#endif
   1.345 +
   1.346 +#ifdef ANDROID
   1.347 +   __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", buf.buffer);
   1.348 +#endif
   1.349 +
   1.350 +   // Write the message to stderr unless it's a warning and MOZ_IGNORE_WARNINGS
   1.351 +   // is set.
   1.352 +   if (!(PR_GetEnv("MOZ_IGNORE_WARNINGS") && aSeverity == NS_DEBUG_WARNING)) {
   1.353 +     fprintf(stderr, "%s\n", buf.buffer);
   1.354 +     fflush(stderr);
   1.355 +   }
   1.356 +
   1.357 +   switch (aSeverity) {
   1.358 +   case NS_DEBUG_WARNING:
   1.359 +     return;
   1.360 +
   1.361 +   case NS_DEBUG_BREAK:
   1.362 +     Break(buf.buffer);
   1.363 +     return;
   1.364 +
   1.365 +   case NS_DEBUG_ABORT: {
   1.366 +#if defined(MOZ_CRASHREPORTER)
   1.367 +     nsCString note("xpcom_runtime_abort(");
   1.368 +     note += buf.buffer;
   1.369 +     note += ")";
   1.370 +     CrashReporter::AppendAppNotesToCrashReport(note);
   1.371 +     CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AbortMessage"),
   1.372 +                                        nsDependentCString(buf.buffer));
   1.373 +#endif  // MOZ_CRASHREPORTER
   1.374 +
   1.375 +#if defined(DEBUG) && defined(_WIN32)
   1.376 +     RealBreak();
   1.377 +#endif
   1.378 +#ifdef DEBUG
   1.379 +     nsTraceRefcnt::WalkTheStack(stderr);
   1.380 +#endif
   1.381 +     Abort(buf.buffer);
   1.382 +     return;
   1.383 +   }
   1.384 +   }
   1.385 +
   1.386 +   // Now we deal with assertions
   1.387 +   gAssertionCount++;
   1.388 +
   1.389 +   switch (GetAssertBehavior()) {
   1.390 +   case NS_ASSERT_WARN:
   1.391 +     return;
   1.392 +
   1.393 +   case NS_ASSERT_SUSPEND:
   1.394 +#ifdef XP_UNIX
   1.395 +      fprintf(stderr, "Suspending process; attach with the debugger.\n");
   1.396 +      kill(0, SIGSTOP);
   1.397 +#else
   1.398 +      Break(buf.buffer);
   1.399 +#endif
   1.400 +      return;
   1.401 +
   1.402 +   case NS_ASSERT_STACK:
   1.403 +     nsTraceRefcnt::WalkTheStack(stderr);
   1.404 +     return;
   1.405 +
   1.406 +   case NS_ASSERT_STACK_AND_ABORT:
   1.407 +     nsTraceRefcnt::WalkTheStack(stderr);
   1.408 +     // Fall through to abort
   1.409 +
   1.410 +   case NS_ASSERT_ABORT:
   1.411 +     Abort(buf.buffer);
   1.412 +     return;
   1.413 +
   1.414 +   case NS_ASSERT_TRAP:
   1.415 +   case NS_ASSERT_UNINITIALIZED: // Default to "trap" behavior
   1.416 +     Break(buf.buffer);
   1.417 +     return;
   1.418 +   }   
   1.419 +}
   1.420 +
   1.421 +static void
   1.422 +Abort(const char *aMsg)
   1.423 +{
   1.424 +  mozalloc_abort(aMsg);
   1.425 +}
   1.426 +
   1.427 +static void
   1.428 +RealBreak()
   1.429 +{
   1.430 +#if defined(_WIN32)
   1.431 +  ::DebugBreak();
   1.432 +#elif defined(XP_MACOSX)
   1.433 +   raise(SIGTRAP);
   1.434 +#elif defined(__GNUC__) && (defined(__i386__) || defined(__i386) || defined(__x86_64__))
   1.435 +   asm("int $3");
   1.436 +#elif defined(__arm__)
   1.437 +   asm(
   1.438 +#ifdef __ARM_ARCH_4T__
   1.439 +/* ARMv4T doesn't support the BKPT instruction, so if the compiler target
   1.440 + * is ARMv4T, we want to ensure the assembler will understand that ARMv5T
   1.441 + * instruction, while keeping the resulting object tagged as ARMv4T.
   1.442 + */
   1.443 +       ".arch armv5t\n"
   1.444 +       ".object_arch armv4t\n"
   1.445 +#endif
   1.446 +       "BKPT #0");
   1.447 +#elif defined(SOLARIS)
   1.448 +#if defined(__i386__) || defined(__i386) || defined(__x86_64__)
   1.449 +   asm("int $3");
   1.450 +#else
   1.451 +   raise(SIGTRAP);
   1.452 +#endif
   1.453 +#else
   1.454 +#warning do not know how to break on this platform
   1.455 +#endif
   1.456 +}
   1.457 +
   1.458 +// Abort() calls this function, don't call it!
   1.459 +static void
   1.460 +Break(const char *aMsg)
   1.461 +{
   1.462 +#if defined(_WIN32)
   1.463 +  static int ignoreDebugger;
   1.464 +  if (!ignoreDebugger) {
   1.465 +    const char *shouldIgnoreDebugger = getenv("XPCOM_DEBUG_DLG");
   1.466 +    ignoreDebugger = 1 + (shouldIgnoreDebugger && !strcmp(shouldIgnoreDebugger, "1"));
   1.467 +  }
   1.468 +  if ((ignoreDebugger == 2) || !::IsDebuggerPresent()) {
   1.469 +    DWORD code = IDRETRY;
   1.470 +
   1.471 +    /* Create the debug dialog out of process to avoid the crashes caused by 
   1.472 +     * Windows events leaking into our event loop from an in process dialog.
   1.473 +     * We do this by launching windbgdlg.exe (built in xpcom/windbgdlg).
   1.474 +     * See http://bugzilla.mozilla.org/show_bug.cgi?id=54792
   1.475 +     */
   1.476 +    PROCESS_INFORMATION pi;
   1.477 +    STARTUPINFOW si;
   1.478 +    wchar_t executable[MAX_PATH];
   1.479 +    wchar_t* pName;
   1.480 +
   1.481 +    memset(&pi, 0, sizeof(pi));
   1.482 +
   1.483 +    memset(&si, 0, sizeof(si));
   1.484 +    si.cb          = sizeof(si);
   1.485 +    si.wShowWindow = SW_SHOW;
   1.486 +
   1.487 +    // 2nd arg of CreateProcess is in/out
   1.488 +    wchar_t *msgCopy = (wchar_t*) _alloca((strlen(aMsg) + 1)*sizeof(wchar_t));
   1.489 +    wcscpy(msgCopy, NS_ConvertUTF8toUTF16(aMsg).get());
   1.490 +
   1.491 +    if(GetModuleFileNameW(GetModuleHandleW(L"xpcom.dll"), executable, MAX_PATH) &&
   1.492 +       nullptr != (pName = wcsrchr(executable, '\\')) &&
   1.493 +       nullptr != wcscpy(pName + 1, L"windbgdlg.exe") &&
   1.494 +       CreateProcessW(executable, msgCopy, nullptr, nullptr,
   1.495 +                      false, DETACHED_PROCESS | NORMAL_PRIORITY_CLASS,
   1.496 +                      nullptr, nullptr, &si, &pi)) {
   1.497 +      WaitForSingleObject(pi.hProcess, INFINITE);
   1.498 +      GetExitCodeProcess(pi.hProcess, &code);
   1.499 +      CloseHandle(pi.hProcess);
   1.500 +      CloseHandle(pi.hThread);
   1.501 +    }
   1.502 +
   1.503 +    switch(code) {
   1.504 +    case IDABORT:
   1.505 +      //This should exit us
   1.506 +      raise(SIGABRT);
   1.507 +      //If we are ignored exit this way..
   1.508 +      _exit(3);
   1.509 +         
   1.510 +    case IDIGNORE:
   1.511 +      return;
   1.512 +    }
   1.513 +  }
   1.514 +
   1.515 +  RealBreak();
   1.516 +#elif defined(XP_MACOSX)
   1.517 +   /* Note that we put this Mac OS X test above the GNUC/x86 test because the
   1.518 +    * GNUC/x86 test is also true on Intel Mac OS X and we want the PPC/x86
   1.519 +    * impls to be the same.
   1.520 +    */
   1.521 +   RealBreak();
   1.522 +#elif defined(__GNUC__) && (defined(__i386__) || defined(__i386) || defined(__x86_64__))
   1.523 +   RealBreak();
   1.524 +#elif defined(__arm__)
   1.525 +   RealBreak();
   1.526 +#elif defined(SOLARIS)
   1.527 +   RealBreak();
   1.528 +#else
   1.529 +#warning do not know how to break on this platform
   1.530 +#endif
   1.531 +}
   1.532 +
   1.533 +static const nsDebugImpl kImpl;
   1.534 +
   1.535 +nsresult
   1.536 +nsDebugImpl::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
   1.537 +{
   1.538 +  if (NS_WARN_IF(outer))
   1.539 +    return NS_ERROR_NO_AGGREGATION;
   1.540 +
   1.541 +  return const_cast<nsDebugImpl*>(&kImpl)->
   1.542 +    QueryInterface(aIID, aInstancePtr);
   1.543 +}
   1.544 +
   1.545 +////////////////////////////////////////////////////////////////////////////////
   1.546 +
   1.547 +nsresult
   1.548 +NS_ErrorAccordingToNSPR()
   1.549 +{
   1.550 +    PRErrorCode err = PR_GetError();
   1.551 +    switch (err) {
   1.552 +      case PR_OUT_OF_MEMORY_ERROR:              return NS_ERROR_OUT_OF_MEMORY;
   1.553 +      case PR_WOULD_BLOCK_ERROR:                return NS_BASE_STREAM_WOULD_BLOCK;
   1.554 +      case PR_FILE_NOT_FOUND_ERROR:             return NS_ERROR_FILE_NOT_FOUND;
   1.555 +      case PR_READ_ONLY_FILESYSTEM_ERROR:       return NS_ERROR_FILE_READ_ONLY;
   1.556 +      case PR_NOT_DIRECTORY_ERROR:              return NS_ERROR_FILE_NOT_DIRECTORY;
   1.557 +      case PR_IS_DIRECTORY_ERROR:               return NS_ERROR_FILE_IS_DIRECTORY;
   1.558 +      case PR_LOOP_ERROR:                       return NS_ERROR_FILE_UNRESOLVABLE_SYMLINK;
   1.559 +      case PR_FILE_EXISTS_ERROR:                return NS_ERROR_FILE_ALREADY_EXISTS;
   1.560 +      case PR_FILE_IS_LOCKED_ERROR:             return NS_ERROR_FILE_IS_LOCKED;
   1.561 +      case PR_FILE_TOO_BIG_ERROR:               return NS_ERROR_FILE_TOO_BIG;
   1.562 +      case PR_NO_DEVICE_SPACE_ERROR:            return NS_ERROR_FILE_NO_DEVICE_SPACE;
   1.563 +      case PR_NAME_TOO_LONG_ERROR:              return NS_ERROR_FILE_NAME_TOO_LONG;
   1.564 +      case PR_DIRECTORY_NOT_EMPTY_ERROR:        return NS_ERROR_FILE_DIR_NOT_EMPTY;
   1.565 +      case PR_NO_ACCESS_RIGHTS_ERROR:           return NS_ERROR_FILE_ACCESS_DENIED;
   1.566 +      default:                                  return NS_ERROR_FAILURE;
   1.567 +    }
   1.568 +}
   1.569 +
   1.570 +void
   1.571 +NS_ABORT_OOM(size_t size)
   1.572 +{
   1.573 +#ifdef MOZ_CRASHREPORTER
   1.574 +  CrashReporter::AnnotateOOMAllocationSize(size);
   1.575 +#endif
   1.576 +  MOZ_CRASH();
   1.577 +}
   1.578 +

mercurial