NS_IMETHODIMP
nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
                                           nsISupports* aContext)
{
  nsresult  rv = NS_OK;

  if (mRequests.IndexOfObject(GetBaseRequest(request)) == -1) {
    NS_ASSERTION(mRequests.Count() == 0,
                 "Only our initial stream should be unknown!");
    TrackRequest(request);
  }
  
  if (mHaveFiredOnStartRequest) {
    return NS_OK;
  }
  
  mHaveFiredOnStartRequest = PR_TRUE;
  
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
  NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
  
  // deal with 404 (Not Found) HTTP response,
  // just return, this causes the request to be ignored.
  nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
  if (httpChannel) {
    PRUint32 responseCode = 0;
    rv = httpChannel->GetResponseStatus(&responseCode);
    if (NS_FAILED(rv)) {
      // NPP_Notify() will be called from OnStopRequest
      // in nsNPAPIPluginStreamListener::CleanUpStream
      // return error will cancel this request
      // ...and we also need to tell the plugin that
      mRequestFailed = PR_TRUE;
      return NS_ERROR_FAILURE;
    }
    
    if (responseCode > 206) { // not normal
      PRBool bWantsAllNetworkStreams = PR_FALSE;
      mPluginInstance->GetValueFromPlugin(NPPVpluginWantsAllNetworkStreams,
                                          (void*)&bWantsAllNetworkStreams);
      if (!bWantsAllNetworkStreams) {
        mRequestFailed = PR_TRUE;
        return NS_ERROR_FAILURE;
      }
    }
  }
  
  // do a little sanity check to make sure our frame isn't gone
  // by getting the tag type and checking for an error, we can determine if
  // the frame is gone
  if (mOwner) {
    nsCOMPtr<nsIPluginTagInfo> pti = do_QueryInterface(mOwner);
    NS_ENSURE_TRUE(pti, NS_ERROR_FAILURE);
    nsPluginTagType tagType;
    if (NS_FAILED(pti->GetTagType(&tagType)))
      return NS_ERROR_FAILURE;  // something happened to our object frame, so bail!
  }
  
  // Get the notification callbacks from the channel and save it as
  // week ref we'll use it in nsPluginStreamInfo::RequestRead() when
  // we'll create channel for byte range request.
  nsCOMPtr<nsIInterfaceRequestor> callbacks;
  channel->GetNotificationCallbacks(getter_AddRefs(callbacks));
  if (callbacks)
    mWeakPtrChannelCallbacks = do_GetWeakReference(callbacks);
  
  nsCOMPtr<nsILoadGroup> loadGroup;
  channel->GetLoadGroup(getter_AddRefs(loadGroup));
  if (loadGroup)
    mWeakPtrChannelLoadGroup = do_GetWeakReference(loadGroup);
  
  PRInt32 length;
  rv = channel->GetContentLength(&length);
  
  // it's possible for the server to not send a Content-Length.
  // we should still work in this case.
  if (NS_FAILED(rv) || length == -1) {
    // check out if this is file channel
    nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(channel);
    if (fileChannel) {
      // file does not exist
      mRequestFailed = PR_TRUE;
      return NS_ERROR_FAILURE;
    }
    mLength = 0;
  }
  else {
    mLength = length;
  }
  
  nsCAutoString aContentType; // XXX but we already got the type above!
  rv = channel->GetContentType(aContentType);
  if (NS_FAILED(rv))
    return rv;
  
  nsCOMPtr<nsIURI> aURL;
  rv = channel->GetURI(getter_AddRefs(aURL));
  if (NS_FAILED(rv))
    return rv;
  
  aURL->GetSpec(mURLSpec);
  
  if (!aContentType.IsEmpty())
    mContentType = aContentType;
  
#ifdef PLUGIN_LOGGING
  PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NOISY,
         ("nsPluginStreamListenerPeer::OnStartRequest this=%p request=%p mime=%s, url=%s\n",
          this, request, aContentType.get(), mURLSpec.get()));
  
  PR_LogFlush();
#endif
  
  NPWindow* window = nsnull;
  
  // if we don't have an nsNPAPIPluginInstance (mPluginInstance), it means
  // we weren't able to load a plugin previously because we
  // didn't have the mimetype.  Now that we do (aContentType),
  // we'll try again with SetUpPluginInstance()
  // which is called by InstantiateEmbeddedPlugin()
  // NOTE: we don't want to try again if we didn't get the MIME type this time
  
  if (!mPluginInstance && mOwner && !aContentType.IsEmpty()) {
    nsCOMPtr<nsIPluginInstance> pluginInstCOMPtr;
    mOwner->GetInstance(getter_AddRefs(pluginInstCOMPtr));
    mPluginInstance = static_cast<nsNPAPIPluginInstance*>(pluginInstCOMPtr.get());

    mOwner->GetWindow(window);
    if (!mPluginInstance && window) {
      nsRefPtr<nsPluginHost> pluginHost = dont_AddRef(nsPluginHost::GetInst());
      
      // determine if we need to try embedded again. FullPage takes a different code path
      PRInt32 mode;
      mOwner->GetMode(&mode);
      if (mode == NP_EMBED) {
        // Make sure to not allow new streams to be opened here; we've
        // already got a stream for this data; we just need a properly
        // set up plugin instance.
        rv = pluginHost->DoInstantiateEmbeddedPlugin(aContentType.get(), aURL,
                                                     mOwner, PR_FALSE);
      }
      else {
        rv = pluginHost->SetUpPluginInstance(aContentType.get(), aURL, mOwner);
      }
      
      if (NS_OK == rv) {
        mOwner->GetInstance(getter_AddRefs(pluginInstCOMPtr));
        mPluginInstance = static_cast<nsNPAPIPluginInstance*>(pluginInstCOMPtr.get());
        if (mPluginInstance) {
          mPluginInstance->Start();
          mOwner->CreateWidget();
          // If we've got a native window, the let the plugin know about it.
          nsCOMPtr<nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH> owner = do_QueryInterface(mOwner);
          if (owner)
            owner->SetWindow();
        }
      }
    }
  }
  
  // Set up the stream listener...
  rv = SetUpStreamListener(request, aURL);
  if (NS_FAILED(rv)) return rv;
  
  return rv;
}
NS_IMETHODIMP
nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
                                           nsISupports* aContext)
{
  nsresult rv = NS_OK;
  AUTO_PROFILER_LABEL("nsPluginStreamListenerPeer::OnStartRequest", OTHER);

  if (mRequests.IndexOfObject(request) == -1) {
    NS_ASSERTION(mRequests.Count() == 0,
                 "Only our initial stream should be unknown!");
    TrackRequest(request);
  }

  if (mHaveFiredOnStartRequest) {
    return NS_OK;
  }

  mHaveFiredOnStartRequest = true;

  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
  NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);

  // deal with 404 (Not Found) HTTP response,
  // just return, this causes the request to be ignored.
  nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
  if (httpChannel) {
    uint32_t responseCode = 0;
    rv = httpChannel->GetResponseStatus(&responseCode);
    if (NS_FAILED(rv)) {
      // NPP_Notify() will be called from OnStopRequest
      // in nsNPAPIPluginStreamListener::CleanUpStream
      // return error will cancel this request
      // ...and we also need to tell the plugin that
      mRequestFailed = true;
      return NS_ERROR_FAILURE;
    }

    if (responseCode > 206) { // not normal
      uint32_t wantsAllNetworkStreams = 0;

      // We don't always have an instance here already, but if we do, check
      // to see if it wants all streams.
      if (mPluginInstance) {
        rv = mPluginInstance->GetValueFromPlugin(NPPVpluginWantsAllNetworkStreams,
                                                 &wantsAllNetworkStreams);
        // If the call returned an error code make sure we still use our default value.
        if (NS_FAILED(rv)) {
          wantsAllNetworkStreams = 0;
        }
      }

      if (!wantsAllNetworkStreams) {
        mRequestFailed = true;
        return NS_ERROR_FAILURE;
      }
    }
  }

  nsAutoCString contentType;
  rv = channel->GetContentType(contentType);
  if (NS_FAILED(rv))
    return rv;

  // Check ShouldProcess with content policy
  RefPtr<nsPluginInstanceOwner> owner;
  if (mPluginInstance) {
    owner = mPluginInstance->GetOwner();
  }
  nsCOMPtr<nsIDOMElement> element;
  nsCOMPtr<nsIDocument> doc;
  if (owner) {
    owner->GetDOMElement(getter_AddRefs(element));
    owner->GetDocument(getter_AddRefs(doc));
  }
  nsCOMPtr<nsIPrincipal> principal = doc ? doc->NodePrincipal() : nullptr;

  int16_t shouldLoad = nsIContentPolicy::ACCEPT;
  rv = NS_CheckContentProcessPolicy(nsIContentPolicy::TYPE_OBJECT_SUBREQUEST,
                                    mURL,
                                    principal, // loading principal
                                    principal, // triggering principal
                                    element,
                                    contentType,
                                    nullptr,
                                    &shouldLoad);
  if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
    mRequestFailed = true;
    return NS_ERROR_CONTENT_BLOCKED;
  }

  // Get the notification callbacks from the channel and save it as
  // week ref we'll use it in nsPluginStreamInfo::RequestRead() when
  // we'll create channel for byte range request.
  nsCOMPtr<nsIInterfaceRequestor> callbacks;
  channel->GetNotificationCallbacks(getter_AddRefs(callbacks));
  if (callbacks)
    mWeakPtrChannelCallbacks = do_GetWeakReference(callbacks);

  nsCOMPtr<nsILoadGroup> loadGroup;
  channel->GetLoadGroup(getter_AddRefs(loadGroup));
  if (loadGroup)
    mWeakPtrChannelLoadGroup = do_GetWeakReference(loadGroup);

  int64_t length;
  rv = channel->GetContentLength(&length);

  // it's possible for the server to not send a Content-Length.
  // we should still work in this case.
  if (NS_FAILED(rv) || length < 0 || length > UINT32_MAX) {
    // check out if this is file channel
    nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(channel);
    if (fileChannel) {
      // file does not exist
      mRequestFailed = true;
      return NS_ERROR_FAILURE;
    }
    mLength = 0;
  }
  else {
    mLength = uint32_t(length);
  }

  nsCOMPtr<nsIURI> aURL;
  rv = channel->GetURI(getter_AddRefs(aURL));
  if (NS_FAILED(rv))
    return rv;

  aURL->GetSpec(mURLSpec);

  if (!contentType.IsEmpty())
    mContentType = contentType;

#ifdef PLUGIN_LOGGING
  MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NOISY,
         ("nsPluginStreamListenerPeer::OnStartRequest this=%p request=%p mime=%s, url=%s\n",
          this, request, contentType.get(), mURLSpec.get()));

  PR_LogFlush();
#endif

  // Set up the stream listener...
  rv = SetUpStreamListener(request, aURL);
  if (NS_FAILED(rv)) {
    return rv;
  }

  return rv;
}
NS_IMETHODIMP
nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
                                           nsISupports* aContext)
{
  nsresult rv = NS_OK;
  PROFILER_LABEL("nsPluginStreamListenerPeer", "OnStartRequest");

  if (mRequests.IndexOfObject(GetBaseRequest(request)) == -1) {
    NS_ASSERTION(mRequests.Count() == 0,
                 "Only our initial stream should be unknown!");
    TrackRequest(request);
  }

  if (mHaveFiredOnStartRequest) {
    return NS_OK;
  }

  mHaveFiredOnStartRequest = true;

  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
  NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);

  // deal with 404 (Not Found) HTTP response,
  // just return, this causes the request to be ignored.
  nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
  if (httpChannel) {
    uint32_t responseCode = 0;
    rv = httpChannel->GetResponseStatus(&responseCode);
    if (NS_FAILED(rv)) {
      // NPP_Notify() will be called from OnStopRequest
      // in nsNPAPIPluginStreamListener::CleanUpStream
      // return error will cancel this request
      // ...and we also need to tell the plugin that
      mRequestFailed = true;
      return NS_ERROR_FAILURE;
    }

    if (responseCode > 206) { // not normal
      uint32_t wantsAllNetworkStreams = 0;

      // We don't always have an instance here already, but if we do, check
      // to see if it wants all streams.
      if (mPluginInstance) {
        rv = mPluginInstance->GetValueFromPlugin(NPPVpluginWantsAllNetworkStreams,
                                                 &wantsAllNetworkStreams);
        // If the call returned an error code make sure we still use our default value.
        if (NS_FAILED(rv)) {
          wantsAllNetworkStreams = 0;
        }
      }

      if (!wantsAllNetworkStreams) {
        mRequestFailed = true;
        return NS_ERROR_FAILURE;
      }
    }
  }

  // Get the notification callbacks from the channel and save it as
  // week ref we'll use it in nsPluginStreamInfo::RequestRead() when
  // we'll create channel for byte range request.
  nsCOMPtr<nsIInterfaceRequestor> callbacks;
  channel->GetNotificationCallbacks(getter_AddRefs(callbacks));
  if (callbacks)
    mWeakPtrChannelCallbacks = do_GetWeakReference(callbacks);

  nsCOMPtr<nsILoadGroup> loadGroup;
  channel->GetLoadGroup(getter_AddRefs(loadGroup));
  if (loadGroup)
    mWeakPtrChannelLoadGroup = do_GetWeakReference(loadGroup);

  int64_t length;
  rv = channel->GetContentLength(&length);

  // it's possible for the server to not send a Content-Length.
  // we should still work in this case.
  if (NS_FAILED(rv) || length < 0 || length > UINT32_MAX) {
    // check out if this is file channel
    nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(channel);
    if (fileChannel) {
      // file does not exist
      mRequestFailed = true;
      return NS_ERROR_FAILURE;
    }
    mLength = 0;
  }
  else {
    mLength = uint32_t(length);
  }

  nsAutoCString aContentType; // XXX but we already got the type above!
  rv = channel->GetContentType(aContentType);
  if (NS_FAILED(rv))
    return rv;

  nsCOMPtr<nsIURI> aURL;
  rv = channel->GetURI(getter_AddRefs(aURL));
  if (NS_FAILED(rv))
    return rv;

  aURL->GetSpec(mURLSpec);

  if (!aContentType.IsEmpty())
    mContentType = aContentType;

#ifdef PLUGIN_LOGGING
  PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NOISY,
         ("nsPluginStreamListenerPeer::OnStartRequest this=%p request=%p mime=%s, url=%s\n",
          this, request, aContentType.get(), mURLSpec.get()));

  PR_LogFlush();
#endif

  // Set up the stream listener...
  rv = SetUpStreamListener(request, aURL);
  if (NS_FAILED(rv)) return rv;

  return rv;
}
示例#4
0
PR_IMPLEMENT(void) PR_LogPrint(const char *fmt, ...)
{
    va_list ap;
    char line[LINE_BUF_SIZE];
    char *line_long = NULL;
    PRUint32 nb_tid = 0, nb;
    PRThread *me;
    PRExplodedTime now;

    if (!_pr_initialized) _PR_ImplicitInitialization();

    if (!logFile) {
        return;
    }

    if (outputTimeStamp) {
        PR_ExplodeTime(PR_Now(), PR_GMTParameters, &now);
        nb_tid = PR_snprintf(line, sizeof(line)-1,
                             "%04d-%02d-%02d %02d:%02d:%02d.%06d UTC - ",
                             now.tm_year, now.tm_month + 1, now.tm_mday,
                             now.tm_hour, now.tm_min, now.tm_sec,
                             now.tm_usec);
    }

    me = PR_GetCurrentThread();
    nb_tid += PR_snprintf(line+nb_tid, sizeof(line)-nb_tid-1, "%ld[%p]: ",
#if defined(_PR_BTHREADS)
                          me, me);
#else
                          me ? me->id : 0L, me);
#endif

    va_start(ap, fmt);
    nb = nb_tid + PR_vsnprintf(line+nb_tid, sizeof(line)-nb_tid-1, fmt, ap);
    va_end(ap);

    /*
     * Check if we might have run out of buffer space (in case we have a
     * long line), and malloc a buffer just this once.
     */
    if (nb == sizeof(line)-2) {
        va_start(ap, fmt);
        line_long = PR_vsmprintf(fmt, ap);
        va_end(ap);
        /* If this failed, we'll fall back to writing the truncated line. */
    }

    if (line_long) {
        nb = strlen(line_long);
        _PR_LOCK_LOG();
        if (logBuf != 0) {
            _PUT_LOG(logFile, logBuf, logp - logBuf);
            logp = logBuf;
        }
        /*
         * Write out the thread id (with an optional timestamp) and the
         * malloc'ed buffer.
         */
        _PUT_LOG(logFile, line, nb_tid);
        _PUT_LOG(logFile, line_long, nb);
        /* Ensure there is a trailing newline. */
        if (!nb || (line_long[nb-1] != '\n')) {
            char eol[2];
            eol[0] = '\n';
            eol[1] = '\0';
            _PUT_LOG(logFile, eol, 1);
        }
        _PR_UNLOCK_LOG();
        PR_smprintf_free(line_long);
    } else {
        /* Ensure there is a trailing newline. */
        if (nb && (line[nb-1] != '\n')) {
            line[nb++] = '\n';
            line[nb] = '\0';
        }
        _PR_LOCK_LOG();
        if (logBuf == 0) {
            _PUT_LOG(logFile, line, nb);
        } else {
            /* If nb can't fit into logBuf, write out logBuf first. */
            if (logp + nb > logEndp) {
                _PUT_LOG(logFile, logBuf, logp - logBuf);
                logp = logBuf;
            }
            /* nb is guaranteed to fit into logBuf. */
            memcpy(logp, line, nb);
            logp += nb;
        }
        _PR_UNLOCK_LOG();
    }
    PR_LogFlush();
}
示例#5
0
NS_IMETHODIMP 
nsDebugImpl::Break(const char *aFile, PRInt32 aLine)
{
#ifndef TEMP_MAC_HACK
  // Write out the assertion message to the debug log
   InitLog();

   PR_LOG(gDebugLog, PR_LOG_ERROR, 
         ("###!!! Break: at file %s, line %d", aFile, aLine));
   PR_LogFlush();

  fprintf(stderr, "Break: at file %s, line %d\n",aFile, aLine);  fflush(stderr);
  fflush(stderr);

#if defined(_WIN32)
#ifdef _M_IX86
   ::DebugBreak();
#endif
#elif defined(XP_UNIX) && !defined(UNIX_CRASH_ON_ASSERT)
    fprintf(stderr, "\07");

    char *assertBehavior = getenv("XPCOM_DEBUG_BREAK");

    if (!assertBehavior) {

      // the default; nothing else to do
      ;

    } else if ( strcmp(assertBehavior, "suspend")== 0 ) {

      // the suspend case is first because we wanna send the signal before 
      // other threads have had a chance to get too far from the state that
      // caused this assertion (in case they happen to have been involved).
      //
      fprintf(stderr, "Suspending process; attach with the debugger.\n");
      kill(0, SIGSTOP);

    } else if ( strcmp(assertBehavior, "warn")==0 ) {
      
      // same as default; nothing else to do (see "suspend" case comment for
      // why this compare isn't done as part of the default case)
      //
      ;

    } 
    else if ( strcmp(assertBehavior,"stack")==0 ) {

      // walk the stack
      //
      nsTraceRefcntImpl::WalkTheStack(stderr);
    } 
    else if ( strcmp(assertBehavior,"abort")==0 ) {

      // same as UNIX_CRASH_ON_ASSERT
      //
      Abort(aFile, aLine);

    } else if ( strcmp(assertBehavior,"trap")==0 ) {

      DebugBreak();

    } else {

      fprintf(stderr, "unrecognized value of XPCOM_DEBUG_BREAK env var!\n");

    }    
    fflush(stderr); // this shouldn't really be necessary, i don't think,
                    // but maybe there's some lame stdio that buffers stderr

#elif defined(XP_BEOS)
  {
#ifdef UNIX_CRASH_ON_ASSERT
	char buf[2000];
	sprintf(buf, "Break: at file %s, line %d", aFile, aLine);
	DEBUGGER(buf);
#endif
  }
#else
  Abort(aFile, aLine);
#endif
#endif // TEMP_MAC_HACK
  return NS_OK;
}
示例#6
0
NS_IMETHODIMP
nsDebugImpl::Assertion(const char *aStr, const char *aExpr, const char *aFile, PRInt32 aLine)
{
   InitLog();

   char buf[1000];
   PR_snprintf(buf, sizeof(buf),
              "###!!! ASSERTION: %s: '%s', file %s, line %d",
              aStr, aExpr, aFile, aLine);

   // Write out the assertion message to the debug log
   PR_LOG(gDebugLog, PR_LOG_ERROR, ("%s", buf));
   PR_LogFlush();

   // And write it out to the stderr
   fprintf(stderr, "%s\n", buf);
   fflush(stderr);

#if defined(_WIN32)
   char* assertBehavior = getenv("XPCOM_DEBUG_BREAK");
   if (assertBehavior && strcmp(assertBehavior, "warn") == 0)
     return NS_OK;

   if(!InDebugger())
      {
      DWORD code = IDRETRY;

      /* Create the debug dialog out of process to avoid the crashes caused by 
       * Windows events leaking into our event loop from an in process dialog.
       * We do this by launching windbgdlg.exe (built in xpcom/windbgdlg).
       * See http://bugzilla.mozilla.org/show_bug.cgi?id=54792
       */
      PROCESS_INFORMATION pi;
      STARTUPINFO si;
      char executable[MAX_PATH];
      char* pName;

      memset(&pi, 0, sizeof(pi));

      memset(&si, 0, sizeof(si));
      si.cb          = sizeof(si);
      si.wShowWindow = SW_SHOW;

      if(GetModuleFileName(GetModuleHandle(XPCOM_DLL), executable, MAX_PATH) &&
         NULL != (pName = strrchr(executable, '\\')) &&
         NULL != strcpy(pName+1, "windbgdlg.exe") &&
#ifdef DEBUG_jband
         (printf("Launching %s\n", executable), PR_TRUE) &&
#endif         
         CreateProcess(executable, buf, NULL, NULL, PR_FALSE,
                       DETACHED_PROCESS | NORMAL_PRIORITY_CLASS,
                       NULL, NULL, &si, &pi) &&
         WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, INFINITE) &&
         GetExitCodeProcess(pi.hProcess, &code))
      {
        CloseHandle(pi.hProcess);
      }                         

      switch(code)
         {
         case IDABORT:
            //This should exit us
            raise(SIGABRT);
            //If we are ignored exit this way..
            _exit(3);
            break;
         
         case IDIGNORE:
            return NS_OK;
            // Fall Through
         }
      }
#endif

#if defined(XP_OS2)
   char* assertBehavior = getenv("XPCOM_DEBUG_BREAK");
   if (assertBehavior && strcmp(assertBehavior, "warn") == 0)
     return NS_OK;

      char msg[1200];
      PR_snprintf(msg, sizeof(msg),
                "%s\n\nClick Cancel to Debug Application.\n"
                "Click Enter to continue running the Application.", buf);
      ULONG code = MBID_ERROR;
      code = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg, 
                           "nsDebug::Assertion", 0,
                           MB_ERROR | MB_ENTERCANCEL);

      /* It is possible that we are executing on a thread that doesn't have a
       * message queue.  In that case, the message won't appear, and code will
       * be 0xFFFF.  We'll give the user a chance to debug it by calling
       * Break()
       * Actually, that's a really bad idea since this happens a lot with threadsafe
       * assertions and since it means that you can't actually run the debug build
       * outside a debugger without it crashing constantly.
       */
      if(( code == MBID_ENTER ) || (code == MBID_ERROR))
      {
         return NS_OK;
         // If Retry, Fall Through
      }
#endif

      Break(aFile, aLine);
      return NS_OK;
}