xpcom/base/nsDebugImpl.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial