Bug 381049 - Pass swallowed crashes inside MSAA/IA2 methods to breakpad, patch=aaronlev, r=me, ted.mielczarek, sr=benjamin, a=dsicore
authorsurkov.alexander@gmail.com
Fri, 08 Feb 2008 18:40:47 -0800
changeset 11440 14564e1a4935b5b243ce1444bdbae5286aa69ee5
parent 11439 aa11ee56b6003d40c21ef5e75cfb2670c64c05b4
child 11441 8837d59c51edb6c6558624f2bef74ef0c45cd754
push idunknown
push userunknown
push dateunknown
reviewersme, ted.mielczarek, benjamin, dsicore
bugs381049
milestone1.9b4pre
Bug 381049 - Pass swallowed crashes inside MSAA/IA2 methods to breakpad, patch=aaronlev, r=me, ted.mielczarek, sr=benjamin, a=dsicore
accessible/src/msaa/nsAccessNodeWrap.cpp
accessible/src/msaa/nsAccessNodeWrap.h
accessible/src/msaa/nsAccessibleWrap.cpp
toolkit/crashreporter/Makefile.in
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/crashreporter/nsExceptionHandler.h
toolkit/crashreporter/nsICrashReporter.idl
toolkit/xre/nsAppRunner.cpp
xpcom/system/Makefile.in
xpcom/system/nsICrashReporter.idl
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -564,8 +564,28 @@ void nsAccessNodeWrap::ShutdownAccessibi
   ::DestroyCaret();
 
   if (!gIsAccessibilityActive) {
     return;
   }
 
   nsAccessNode::ShutdownXPAccessibility();
 }
+
+int nsAccessNodeWrap::FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo)
+{
+  if (aCode == EXCEPTION_ACCESS_VIOLATION) {
+#ifdef MOZ_CRASHREPORTER
+    // MSAA swallows crashes (because it is COM-based)
+    // but we still need to learn about those crashes so we can fix them
+    // Make sure to pass them to the crash reporter
+    nsCOMPtr<nsICrashReporter> crashReporter =
+      do_GetService("@mozilla.org/toolkit/crash-reporter;1");
+    if (crashReporter) {
+      crashReporter->WriteMinidumpForException(aExceptionInfo);
+    }
+#endif
+  }
+  else {
+    NS_NOTREACHED("We should only be catching crash exceptions");
+  }
+  return EXCEPTION_CONTINUE_SEARCH;
+}
--- a/accessible/src/msaa/nsAccessNodeWrap.h
+++ b/accessible/src/msaa/nsAccessNodeWrap.h
@@ -53,16 +53,19 @@
 #include "nsAccessNode.h"
 #include "OLEIDL.H"
 #include "OLEACC.H"
 #include <winuser.h>
 #ifndef WINABLEAPI
 #include <winable.h>
 #endif
 #undef ERROR /// Otherwise we can't include nsIDOMNSEvent.h if we include this
+#ifdef MOZ_CRASHREPORTER
+#include "nsICrashReporter.h"
+#endif
 
 typedef LRESULT (STDAPICALLTYPE *LPFNNOTIFYWINEVENT)(DWORD event,HWND hwnd,LONG idObjectType,LONG idObject);
 typedef LRESULT (STDAPICALLTYPE *LPFNGETGUITHREADINFO)(DWORD idThread, GUITHREADINFO* pgui);
 
 class nsAccessNodeWrap :  public nsAccessNode,
                           public nsIWinAccessNode,
                           public ISimpleDOMNode,
                           public IServiceProvider
@@ -141,16 +144,18 @@ class nsAccessNodeWrap :  public nsAcces
 
     /// the accessible library and cached methods
     static HINSTANCE gmAccLib;
     static HINSTANCE gmUserLib;
     static LPFNACCESSIBLEOBJECTFROMWINDOW gmAccessibleObjectFromWindow;
     static LPFNNOTIFYWINEVENT gmNotifyWinEvent;
     static LPFNGETGUITHREADINFO gmGetGUIThreadInfo;
 
+    static int FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo);
+
   protected:
     void GetAccessibleFor(nsIDOMNode *node, nsIAccessible **newAcc);
     ISimpleDOMNode* MakeAccessNode(nsIDOMNode *node);
 
     static PRBool gIsEnumVariantSupportDisabled;
 
     /**
      * It is used in nsHyperTextAccessibleWrap for IA2::newText/oldText
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -57,16 +57,23 @@
 #include "nsRootAccessible.h"
 #include "nsIServiceManager.h"
 #include "nsTextFormatter.h"
 #include "nsIView.h"
 #include "nsRoleMap.h"
 #include "nsEventMap.h"
 #include "nsArrayUtils.h"
 
+// Avoid warning C4509:
+// nonstandard extension used: 'nsAccessibleWrap::[methodname]' 
+// uses SEH and 'xpAccessible' has destructor
+// At this point we're catching a crash which is of much greater
+// importance than the missing dereference for the nsCOMPtr<>
+#pragma warning( disable : 4509 )
+
 /* For documentation of the accessibility architecture,
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 //#define DEBUG_LEAKS
 
 #ifdef DEBUG_LEAKS
 static gAccessibles = 0;
@@ -98,16 +105,17 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsAccessibl
 
 //-----------------------------------------------------
 // IUnknown interface methods - see iunknown.h for documentation
 //-----------------------------------------------------
 
 // Microsoft COM QueryInterface
 STDMETHODIMP nsAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 {
+__try {
   *ppv = NULL;
 
   if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid)
     *ppv = static_cast<IAccessible*>(this);
   else if (IID_IEnumVARIANT == iid && !gIsEnumVariantSupportDisabled) {
     long numChildren;
     get_accChildCount(&numChildren);
     if (numChildren > 0)  // Don't support this interface for leaf elements
@@ -134,16 +142,17 @@ STDMETHODIMP nsAccessibleWrap::QueryInte
     if (SUCCEEDED(hr))
       return hr;
   }
 
   if (NULL == *ppv)
     return nsAccessNodeWrap::QueryInterface(iid, ppv);
 
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 //-----------------------------------------------------
 // IAccessible methods
 //-----------------------------------------------------
 
 
@@ -175,16 +184,17 @@ STDMETHODIMP nsAccessibleWrap::NotifyWin
   if (gmNotifyWinEvent)
     return gmNotifyWinEvent(event, hwnd, idObjectType, idObject);
 
   return E_FAIL;
 }
 
 STDMETHODIMP nsAccessibleWrap::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispParent)
 {
+__try {
   *ppdispParent = NULL;
   if (!mWeakShell)
     return E_FAIL;  // We've been shut down
 
   nsIFrame *frame = GetFrame();
   HWND hwnd = 0;
   if (frame) {
     nsIView *view = frame->GetViewExternal();
@@ -228,105 +238,114 @@ STDMETHODIMP nsAccessibleWrap::get_accPa
 
   nsCOMPtr<nsIAccessible> xpParentAccessible(GetParent());
   NS_ASSERTION(xpParentAccessible, "No parent accessible where we're not direct child of window");
   if (!xpParentAccessible) {
     return E_UNEXPECTED;
   }
   *ppdispParent = NativeAccessible(xpParentAccessible);
 
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP nsAccessibleWrap::get_accChildCount( long __RPC_FAR *pcountChildren)
 {
+__try {
   *pcountChildren = 0;
   if (MustPrune(this)) {
     return NS_OK;
   }
 
   PRInt32 numChildren;
   GetChildCount(&numChildren);
   *pcountChildren = numChildren;
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP nsAccessibleWrap::get_accChild(
       /* [in] */ VARIANT varChild,
       /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispChild)
 {
+__try {
   *ppdispChild = NULL;
-
   if (!mWeakShell || varChild.vt != VT_I4)
     return E_FAIL;
 
   if (varChild.lVal == CHILDID_SELF) {
     *ppdispChild = static_cast<IDispatch*>(this);
     AddRef();
     return S_OK;
   }
 
   nsCOMPtr<nsIAccessible> childAccessible;
   if (!MustPrune(this)) {
     GetChildAt(varChild.lVal - 1, getter_AddRefs(childAccessible));
     if (childAccessible) {
       *ppdispChild = NativeAccessible(childAccessible);
     }
   }
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return (*ppdispChild)? S_OK: E_FAIL;
 }
 
 STDMETHODIMP nsAccessibleWrap::get_accName(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszName)
 {
+__try {
   *pszName = NULL;
   nsCOMPtr<nsIAccessible> xpAccessible;
   GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
   if (xpAccessible) {
     nsAutoString name;
     if (NS_FAILED(xpAccessible->GetName(name)))
       return S_FALSE;
     if (!name.IsVoid()) {
       *pszName = ::SysAllocString(name.get());
     }
 #ifdef DEBUG_A11Y
     NS_ASSERTION(mIsInitialized, "Access node was not initialized");
 #endif
   }
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 
 STDMETHODIMP nsAccessibleWrap::get_accValue(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszValue)
 {
+__try {
   *pszValue = NULL;
   nsCOMPtr<nsIAccessible> xpAccessible;
   GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
   if (xpAccessible) {
     nsAutoString value;
     if (NS_FAILED(xpAccessible->GetValue(value)))
       return S_FALSE;
 
     *pszValue = ::SysAllocString(value.get());
   }
-
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_accDescription(VARIANT varChild,
                                      BSTR __RPC_FAR *pszDescription)
 {
+__try {
   *pszDescription = NULL;
+
   nsCOMPtr<nsIAccessible> xpAccessible;
   GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
   if (!xpAccessible)
     return E_FAIL;
 
   // For items that are a choice in a list of choices, use MSAA description
   // field to shoehorn positional info, it's becoming a defacto standard use for
   // the field.
@@ -412,23 +431,25 @@ nsAccessibleWrap::get_accDescription(VAR
     // Signal to screen readers that this description is speakable
     // and is not a formatted positional information description
     // Don't localize the "Description: " part of this string, it will be
     // parsed out by assistive technologies.
     description = NS_LITERAL_STRING("Description: ") + description;
   }
 
   *pszDescription = ::SysAllocString(description.get());
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP nsAccessibleWrap::get_accRole(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ VARIANT __RPC_FAR *pvarRole)
 {
+__try {
   VariantInit(pvarRole);
 
   nsCOMPtr<nsIAccessible> xpAccessible;
   GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
 
   if (!xpAccessible)
     return E_FAIL;
 
@@ -488,38 +509,40 @@ STDMETHODIMP nsAccessibleWrap::get_accRo
       }
     }
     if (!roleString.IsEmpty()) {
       pvarRole->vt = VT_BSTR;
       pvarRole->bstrVal = ::SysAllocString(roleString.get());
       return S_OK;
     }
   }
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP nsAccessibleWrap::get_accState(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ VARIANT __RPC_FAR *pvarState)
 {
+__try {
   VariantInit(pvarState);
   pvarState->vt = VT_I4;
   pvarState->lVal = 0;
 
   nsCOMPtr<nsIAccessible> xpAccessible;
   GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
   if (!xpAccessible)
     return E_FAIL;
 
   PRUint32 state = 0;
   if (NS_FAILED(xpAccessible->GetFinalState(&state, nsnull)))
     return E_FAIL;
 
   pvarState->lVal = state;
-
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 
 STDMETHODIMP nsAccessibleWrap::get_accHelp(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszHelp)
 {
@@ -536,41 +559,43 @@ STDMETHODIMP nsAccessibleWrap::get_accHe
   *pidTopic = 0;
   return E_NOTIMPL;
 }
 
 STDMETHODIMP nsAccessibleWrap::get_accKeyboardShortcut(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszKeyboardShortcut)
 {
+__try {
   *pszKeyboardShortcut = NULL;
   nsCOMPtr<nsIAccessible> xpAccessible;
   GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
   if (xpAccessible) {
     nsAutoString shortcut;
     nsresult rv = xpAccessible->GetKeyboardShortcut(shortcut);
     if (NS_FAILED(rv))
       return S_FALSE;
 
     *pszKeyboardShortcut = ::SysAllocString(shortcut.get());
     return S_OK;
   }
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_FALSE;
 }
 
 STDMETHODIMP nsAccessibleWrap::get_accFocus(
       /* [retval][out] */ VARIANT __RPC_FAR *pvarChild)
 {
   // VT_EMPTY:    None. This object does not have the keyboard focus itself
   //              and does not contain a child that has the keyboard focus.
   // VT_I4:       lVal is CHILDID_SELF. The object itself has the keyboard focus.
   // VT_I4:       lVal contains the child ID of the child element with the keyboard focus.
   // VT_DISPATCH: pdispVal member is the address of the IDispatch interface
   //              for the child object with the keyboard focus.
-
+__try {
   if (!mDOMNode) {
     return E_FAIL; // This node is shut down
   }
 
   VariantInit(pvarChild);
 
   // Return the current IAccessible child that has focus
   nsCOMPtr<nsIAccessible> focusedAccessible;
@@ -582,16 +607,17 @@ STDMETHODIMP nsAccessibleWrap::get_accFo
   else if (focusedAccessible) {
     pvarChild->vt = VT_DISPATCH;
     pvarChild->pdispVal = NativeAccessible(focusedAccessible);
   }
   else {
     pvarChild->vt = VT_EMPTY;   // No focus or focus is not a child
   }
 
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 // This helper class implements IEnumVARIANT for a nsIArray containing nsIAccessible objects.
 
 class AccessibleEnumerator : public IEnumVARIANT
 {
 public:
@@ -619,28 +645,30 @@ private:
   nsCOMPtr<nsIArray> mArray;
   PRUint32 mCurIndex;
   nsAutoRefCnt mRefCnt;
 };
 
 HRESULT
 AccessibleEnumerator::QueryInterface(REFIID iid, void ** ppvObject)
 {
+__try {
   if (iid == IID_IEnumVARIANT) {
     *ppvObject = static_cast<IEnumVARIANT*>(this);
     AddRef();
     return S_OK;
   }
   if (iid == IID_IUnknown) {
     *ppvObject = static_cast<IUnknown*>(this);
     AddRef();
     return S_OK;
   }
 
   *ppvObject = NULL;
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_NOINTERFACE;
 }
 
 STDMETHODIMP_(ULONG)
 AccessibleEnumerator::AddRef(void)
 {
   return ++mRefCnt;
 }
@@ -652,16 +680,17 @@ AccessibleEnumerator::Release(void)
   if (r == 0)
     delete this;
   return r;
 }
 
 STDMETHODIMP
 AccessibleEnumerator::Next(unsigned long celt, VARIANT FAR* rgvar, unsigned long FAR* pceltFetched)
 {
+__try {
   PRUint32 length = 0;
   mArray->GetLength(&length);
 
   HRESULT hr = S_OK;
 
   // Can't get more elements than there are...
   if (celt > length - mCurIndex) {
     hr = S_FALSE;
@@ -678,39 +707,46 @@ AccessibleEnumerator::Next(unsigned long
       rgvar[i].pdispVal = nsAccessibleWrap::NativeAccessible(accel);
     }
   }
 
   if (pceltFetched)
     *pceltFetched = celt;
 
   return hr;
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
+
+  return S_OK;
 }
 
 STDMETHODIMP
 AccessibleEnumerator::Clone(IEnumVARIANT FAR* FAR* ppenum)
 {
+__try {
   *ppenum = new AccessibleEnumerator(*this);
   if (!*ppenum)
     return E_OUTOFMEMORY;
   NS_ADDREF(*ppenum);
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 AccessibleEnumerator::Skip(unsigned long celt)
 {
+__try {
   PRUint32 length = 0;
   mArray->GetLength(&length);
   // Check if we can skip the requested number of elements
   if (celt > length - mCurIndex) {
     mCurIndex = length;
     return S_FALSE;
   }
   mCurIndex += celt;
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 /**
   * This method is called when a client wants to know which children of a node
   *  are selected. Note that this method can only find selected children for
   *  nsIAccessible object which implement nsIAccessibleSelectable.
   *
@@ -723,16 +759,17 @@ AccessibleEnumerator::Skip(unsigned long
   *  those in an AccessibleEnumerator which we then put in the return VARIANT.
   *
   * returns a VT_EMPTY VARIANT if:
   *  - there are no selected children for this object
   *  - the object is not the type that can have children selected
   */
 STDMETHODIMP nsAccessibleWrap::get_accSelection(VARIANT __RPC_FAR *pvarChildren)
 {
+__try {
   VariantInit(pvarChildren);
   pvarChildren->vt = VT_EMPTY;
 
   nsCOMPtr<nsIAccessibleSelectable> 
     select(do_QueryInterface(static_cast<nsIAccessible*>(this)));
 
   if (select) {  // do we have an nsIAccessibleSelectable?
     // we have an accessible that can have children selected
@@ -745,41 +782,45 @@ STDMETHODIMP nsAccessibleWrap::get_accSe
 
       // 2) Put the enumerator in the VARIANT
       if (!pEnum)
         return E_OUTOFMEMORY;
       pvarChildren->vt = VT_UNKNOWN;    // this must be VT_UNKNOWN for an IEnumVARIANT
       NS_ADDREF(pvarChildren->punkVal = pEnum);
     }
   }
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP nsAccessibleWrap::get_accDefaultAction(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszDefaultAction)
 {
+__try {
   *pszDefaultAction = NULL;
   nsCOMPtr<nsIAccessible> xpAccessible;
   GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
   if (xpAccessible) {
     nsAutoString defaultAction;
     if (NS_FAILED(xpAccessible->GetActionName(0, defaultAction)))
       return S_FALSE;
 
     *pszDefaultAction = ::SysAllocString(defaultAction.get());
   }
 
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP nsAccessibleWrap::accSelect(
       /* [in] */ long flagsSelect,
       /* [optional][in] */ VARIANT varChild)
 {
+__try {
   // currently only handle focus and selection
   nsCOMPtr<nsIAccessible> xpAccessible;
   GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
   NS_ENSURE_TRUE(xpAccessible, E_FAIL);
 
   if (flagsSelect & (SELFLAG_TAKEFOCUS|SELFLAG_TAKESELECTION|SELFLAG_REMOVESELECTION))
   {
     if (flagsSelect & SELFLAG_TAKEFOCUS)
@@ -795,49 +836,53 @@ STDMETHODIMP nsAccessibleWrap::accSelect
       xpAccessible->SetSelected(PR_FALSE);
 
     if (flagsSelect & SELFLAG_EXTENDSELECTION)
       xpAccessible->ExtendSelection();
 
     return S_OK;
   }
 
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP nsAccessibleWrap::accLocation(
       /* [out] */ long __RPC_FAR *pxLeft,
       /* [out] */ long __RPC_FAR *pyTop,
       /* [out] */ long __RPC_FAR *pcxWidth,
       /* [out] */ long __RPC_FAR *pcyHeight,
       /* [optional][in] */ VARIANT varChild)
 {
+__try {
   nsCOMPtr<nsIAccessible> xpAccessible;
   GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
 
   if (xpAccessible) {
     PRInt32 x, y, width, height;
     if (NS_FAILED(xpAccessible->GetBounds(&x, &y, &width, &height)))
       return E_FAIL;
 
     *pxLeft = x;
     *pyTop = y;
     *pcxWidth = width;
     *pcyHeight = height;
     return S_OK;
   }
+} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return E_FAIL;
 }
 
 STDMETHODIMP nsAccessibleWrap::accNavigate(
       /* [in] */ long navDir,
       /* [optional][in] */ VARIANT varStart,
       /* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt)
 {
+__try {
   nsCOMPtr<nsIAccessible> xpAccessibleStart, xpAccessibleResult;
   GetXPAccessibleFor(varStart, getter_AddRefs(xpAccessibleStart));
   if (!xpAccessibleStart)
     return E_FAIL;
 
   VariantInit(pvarEndUpAt);
   PRUint32 xpRelation = 0;
 
@@ -932,24 +977,26 @@ STDMETHODIMP nsAccessibleWrap::accNaviga
     }
   }
 
   if (xpAccessibleResult) {
     pvarEndUpAt->pdispVal = NativeAccessible(xpAccessibleResult);
     pvarEndUpAt->vt = VT_DISPATCH;
     return NS_OK;
   }
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP nsAccessibleWrap::accHitTest(
       /* [in] */ long xLeft,
       /* [in] */ long yTop,
       /* [retval][out] */ VARIANT __RPC_FAR *pvarChild)
 {
+__try {
   VariantInit(pvarChild);
 
   // convert to window coords
   nsCOMPtr<nsIAccessible> xpAccessible;
 
   xLeft = xLeft;
   yTop = yTop;
 
@@ -979,29 +1026,32 @@ STDMETHODIMP nsAccessibleWrap::accHitTes
         return E_FAIL;
       }
     }
   } else {
     // no child at that point
     pvarChild->vt = VT_EMPTY;
     return S_FALSE;
   }
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP nsAccessibleWrap::accDoDefaultAction(
       /* [optional][in] */ VARIANT varChild)
 {
+__try {
   nsCOMPtr<nsIAccessible> xpAccessible;
   GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
 
   if (!xpAccessible || FAILED(xpAccessible->DoAction(0))) {
     return E_FAIL;
   }
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP nsAccessibleWrap::put_accName(
       /* [optional][in] */ VARIANT varChild,
       /* [in] */ BSTR szName)
 {
   return E_NOTIMPL;
@@ -1019,16 +1069,17 @@ STDMETHODIMP nsAccessibleWrap::put_accVa
 STDMETHODIMP
 nsAccessibleWrap::Next(ULONG aNumElementsRequested, VARIANT FAR* pvar, ULONG FAR* aNumElementsFetched)
 {
   // If there are two clients using this at the same time, and they are
   // each using a different mEnumVariant position it would be bad, because
   // we have only 1 object and can only keep of mEnumVARIANT position once
 
   // Children already cached via QI to IEnumVARIANT
+__try {
   *aNumElementsFetched = 0;
 
   PRInt32 numChildren;
   GetChildCount(&numChildren);
 
   if (aNumElementsRequested <= 0 || !pvar ||
       mEnumVARIANTPosition >= numChildren) {
     return E_FAIL;
@@ -1053,83 +1104,93 @@ nsAccessibleWrap::Next(ULONG aNumElement
       wasAccessibleFetched = PR_TRUE;
     }
     msaaAccessible->accNavigate(NAVDIR_NEXT, varStart, &pvar[*aNumElementsFetched] );
     if (!wasAccessibleFetched)
       msaaAccessible->nsAccessNode::Release(); // this accessible will not be received by the caller
   }
 
   mEnumVARIANTPosition += static_cast<PRUint16>(*aNumElementsFetched);
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return NOERROR;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::Skip(ULONG aNumElements)
 {
+__try {
   mEnumVARIANTPosition += static_cast<PRUint16>(aNumElements);
 
   PRInt32 numChildren;
   GetChildCount(&numChildren);
 
   if (mEnumVARIANTPosition > numChildren)
   {
     mEnumVARIANTPosition = numChildren;
     return S_FALSE;
   }
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return NOERROR;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::Reset(void)
 {
   mEnumVARIANTPosition = 0;
   return NOERROR;
 }
 
 
 // IAccessible2
 
 STDMETHODIMP
 nsAccessibleWrap::get_nRelations(long *aNRelations)
 {
+__try {
   PRUint32 count = 0;
   nsresult rv = GetRelationsCount(&count);
   *aNRelations = count;
 
-  return NS_FAILED(rv) ? E_FAIL : S_OK;
+  if (NS_FAILED(rv))
+    return E_FAIL;
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
+  return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_relation(long aRelationIndex,
                                IAccessibleRelation **aRelation)
 {
+__try {
   nsCOMPtr<nsIAccessibleRelation> relation;
   nsresult rv = GetRelation(aRelationIndex, getter_AddRefs(relation));
   if (NS_FAILED(rv))
     return E_FAIL;
 
   nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryInterface(relation));
   if (!winAccessNode)
     return E_FAIL;
 
   void *instancePtr = NULL;
   rv =  winAccessNode->QueryNativeInterface(IID_IAccessibleRelation,
                                             &instancePtr);
   if (NS_FAILED(rv))
     return E_FAIL;
 
   *aRelation = static_cast<IAccessibleRelation*>(instancePtr);
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_relations(long aMaxRelations,
                                 IAccessibleRelation **aRelation,
                                 long *aNRelations)
 {
+__try {
   *aNRelations = 0;
 
   nsCOMPtr<nsIArray> relations;
   nsresult rv = GetRelations(getter_AddRefs(relations));
   if (NS_FAILED(rv))
     return E_FAIL;
 
   PRUint32 length = 0;
@@ -1158,78 +1219,88 @@ nsAccessibleWrap::get_relations(long aMa
     for (PRUint32 index2 = 0; index2 < index; index2++) {
       aRelation[index2]->Release();
       aRelation[index2] = NULL;
     }
     return E_FAIL;
   }
 
   *aNRelations = count;
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::role(long *role)
 {
+__try {
   PRUint32 xpRole = 0;
   if (NS_FAILED(GetFinalRole(&xpRole)))
     return E_FAIL;
 
   NS_ASSERTION(gWindowsRoleMap[nsIAccessibleRole::ROLE_LAST_ENTRY].ia2Role == ROLE_WINDOWS_LAST_ENTRY,
                "MSAA role map skewed");
 
   *role = gWindowsRoleMap[xpRole].ia2Role;
-
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::scrollTo(enum IA2ScrollType aScrollType)
 {
+__try {
   if (NS_SUCCEEDED(ScrollTo(aScrollType)))
     return S_OK;
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::scrollToPoint(enum IA2CoordinateType aCoordType,
                                 long aX, long aY)
 {
+__try {
   PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
     nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
     nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
 
   return NS_SUCCEEDED(ScrollToPoint(geckoCoordType, aX, aY)) ?
     S_OK : E_FAIL;
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
+  return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_groupPosition(long *aGroupLevel,
                                     long *aSimilarItemsInGroup,
                                     long *aPositionInGroup)
 {
+__try {
   PRInt32 groupLevel = 0;
   PRInt32 similarItemsInGroup = 0;
   PRInt32 positionInGroup = 0;
   nsresult rv = GroupPosition(&groupLevel, &similarItemsInGroup,
                               &positionInGroup);
 
   if (NS_SUCCEEDED(rv)) {
    *aGroupLevel = groupLevel;
    *aSimilarItemsInGroup = similarItemsInGroup;
    *aPositionInGroup = positionInGroup;
     return S_OK;
   }
 
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_states(AccessibleStates *aStates)
 {
+__try {
   *aStates = 0;
 
   // XXX: bug 344674 should come with better approach that we have here.
 
   PRUint32 states = 0, extraStates = 0;
   nsresult rv = GetFinalState(&states, &extraStates);
   if (NS_FAILED(rv))
     return E_FAIL;
@@ -1267,16 +1338,17 @@ nsAccessibleWrap::get_states(AccessibleS
     *aStates |= IA2_STATE_STALE;
   if (extraStates & nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION)
     *aStates |= IA2_STATE_SUPPORTS_AUTOCOMPLETION;
   if (extraStates & nsIAccessibleStates::EXT_STATE_TRANSIENT)
     *aStates |= IA2_STATE_TRANSIENT;
   if (extraStates & nsIAccessibleStates::EXT_STATE_VERTICAL)
     *aStates |= IA2_STATE_VERTICAL;
 
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_extendedRole(BSTR *extendedRole)
 {
   return E_NOTIMPL;
 }
@@ -1310,50 +1382,57 @@ nsAccessibleWrap::get_localizedExtendedS
 {
   *nLocalizedExtendedStates = 0;
   return E_NOTIMPL;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_uniqueID(long *uniqueID)
 {
+__try {
   void *id;
   if (NS_SUCCEEDED(GetUniqueID(&id))) {
     *uniqueID = - reinterpret_cast<long>(id);
     return S_OK;
   }
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_windowHandle(HWND *windowHandle)
 {
+__try {
   void *handle = nsnull;
   nsresult rv = GetOwnerWindow(&handle);
   if (NS_FAILED(rv))
     return E_FAIL;
 
   *windowHandle = reinterpret_cast<HWND>(handle);
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_indexInParent(long *indexInParent)
 {
+__try {
   PRInt32 index;
   if (NS_SUCCEEDED(GetIndexInParent(&index))) {
     *indexInParent = index;
     return S_OK;
   }
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_locale(IA2Locale *aLocale)
 {
+__try {
   // Language codes consist of a primary code and a possibly empty series of
   // subcodes: language-code = primary-code ( "-" subcode )*
   // Two-letter primary codes are reserved for [ISO639] language abbreviations.
   // Any two-letter subcode is understood to be a [ISO3166] country code.
 
   nsAutoString lang;
   nsresult rv = GetLanguage(lang);
   if (NS_FAILED(rv))
@@ -1380,25 +1459,26 @@ nsAccessibleWrap::get_locale(IA2Locale *
     } else if (offset == 5) {
       aLocale->country = ::SysAllocStringLen(lang.get() + 3, 2);
     }
   }
 
   // Expose as a string if primary code or subcode cannot point to language or
   // country abbreviations or if there are more than one subcode.
   aLocale->variant = ::SysAllocString(lang.get());
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_attributes(BSTR *aAttributes)
 {
   // The format is name:value;name:value; with \ for escaping these
   // characters ":;=,\".
-
+__try {
   *aAttributes = NULL;
 
   nsCOMPtr<nsIPersistentProperties> attributes;
   if (NS_FAILED(GetAttributes(getter_AddRefs(attributes))))
     return E_FAIL;
 
   if (!attributes)
     return S_OK;
@@ -1443,37 +1523,40 @@ nsAccessibleWrap::get_attributes(BSTR *a
 
     AppendUTF8toUTF16(name, strAttrs);
     strAttrs.Append(':');
     strAttrs.Append(value);
     strAttrs.Append(';');
   }
 
   *aAttributes = ::SysAllocString(strAttrs.get());
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::Clone(IEnumVARIANT FAR* FAR* ppenum)
 {
+__try {
   // Clone could be bad, the cloned items aren't tracked for shutdown
   // Then again, as long as the client releases the items in time, we're okay
   *ppenum = nsnull;
 
   nsAccessibleWrap *accessibleWrap = new nsAccessibleWrap(mDOMNode, mWeakShell);
   if (!accessibleWrap)
     return E_FAIL;
 
   IAccessible *msaaAccessible = static_cast<IAccessible*>(accessibleWrap);
   msaaAccessible->AddRef();
   QueryInterface(IID_IEnumVARIANT, (void**)ppenum);
   if (*ppenum)
     (*ppenum)->Skip(mEnumVARIANTPosition); // QI addrefed
   msaaAccessible->Release();
 
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return NOERROR;
 }
 
 
 // For IDispatch support
 STDMETHODIMP
 nsAccessibleWrap::GetTypeInfoCount(UINT *p)
 {
--- a/toolkit/crashreporter/Makefile.in
+++ b/toolkit/crashreporter/Makefile.in
@@ -84,20 +84,16 @@ DIRS += \
   $(NULL)
 endif
 
 DIRS += client
 
 LOCAL_INCLUDES = -I$(srcdir)/google-breakpad/src
 DEFINES += -DUNICODE -D_UNICODE
 
-XPIDLSRCS = \
-	nsICrashReporter.idl \
-	$(NULL)
-
 EXPORTS = \
 	nsExceptionHandler.h \
 	$(NULL)
 
 CPPSRCS = \
 	nsExceptionHandler.cpp \
 	$(NULL)
 
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -829,9 +829,20 @@ SetRestartArgs(int argc, char **argv)
     envVar = "MOZ_CRASHREPORTER_RESTART_XUL_APP_FILE=";
     envVar += appfile;
     env = ToNewCString(envVar);
     PR_SetEnv(env);
   }
 
   return NS_OK;
 }
+
+#ifdef XP_WIN32
+nsresult WriteMinidumpForException(EXCEPTION_POINTERS* aExceptionInfo)
+{
+  if (!gExceptionHandler)
+    return NS_ERROR_NOT_INITIALIZED;
+
+  return gExceptionHandler->WriteMinidumpForException(aExceptionInfo) ? NS_OK : NS_ERROR_FAILURE;
+}
+#endif
+
 } // namespace CrashReporter
--- a/toolkit/crashreporter/nsExceptionHandler.h
+++ b/toolkit/crashreporter/nsExceptionHandler.h
@@ -37,20 +37,30 @@
 
 #ifndef nsExceptionHandler_h__
 #define nsExceptionHandler_h__
 
 #include "nscore.h"
 #include "nsXPCOM.h"
 #include "nsStringGlue.h"
 
+#if defined(XP_WIN32)
+#ifdef WIN32_LEAN_AND_MEAN
+#undef WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#endif
+
 namespace CrashReporter {
 nsresult SetExceptionHandler(nsILocalFile* aXREDirectory,
                              const char* aServerURL);
 nsresult SetMinidumpPath(const nsAString& aPath);
 nsresult UnsetExceptionHandler();
 nsresult AnnotateCrashReport(const nsACString &key, const nsACString &data);
 nsresult SetRestartArgs(int argc, char **argv);
 nsresult SetupExtraData(nsILocalFile* aAppDataDirectory,
                         const nsACString& aBuildID);
+#ifdef XP_WIN32
+  nsresult WriteMinidumpForException(EXCEPTION_POINTERS* aExceptionInfo);
+#endif
 }
 
 #endif /* nsExceptionHandler_h__ */
deleted file mode 100644
--- a/toolkit/crashreporter/nsICrashReporter.idl
+++ /dev/null
@@ -1,62 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Breakpad Integration.
- *
- * The Initial Developer of the Original Code is
- * Ted Mielczarek <ted.mielczarek@gmail.com>
- *
- * Portions created by the Initial Developer are Copyright (C) 2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsISupports.idl"
-
-/**
- * Provides access to crash reporting functionality.
- * @status UNSTABLE - This interface is not frozen and will probably change in
- *                    future releases.
- */
-
-[scriptable, uuid(da7020ad-fad4-443e-b02b-c5cc9d482e2f)]
-interface nsICrashReporter : nsISupports
-{
-  /**
-   * Add some extra data to be submitted with a crash report.
-   * @param key
-   *        Name of the data to be added.
-   * @param data
-   *        Data to be added.
-   *
-   * @throw NS_ERROR_NOT_INITIALIZED if crash reporting not initialized
-   * @throw NS_ERROR_INVALID_ARG if key or data contain invalid characters.
-   *                             Invalid characters for key are '=' and
-   *                             '\n'.  Invalid character for data is '\0'.
-   */
-  void annotateCrashReport(in ACString key, in ACString data);
-};
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -822,16 +822,26 @@ nsXULAppInfo::GetUserCanElevate(PRBool *
 
 #ifdef MOZ_CRASHREPORTER
 NS_IMETHODIMP
 nsXULAppInfo::AnnotateCrashReport(const nsACString& key,
                                   const nsACString& data)
 {
   return CrashReporter::AnnotateCrashReport(key, data);
 }
+
+NS_IMETHODIMP
+nsXULAppInfo::WriteMinidumpForException(void* aExceptionInfo)
+{
+#ifdef XP_WIN32
+  return CrashReporter::WriteMinidumpForException(static_cast<EXCEPTION_POINTERS*>(aExceptionInfo));
+#else
+  return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
 #endif
 
 static const nsXULAppInfo kAppInfo;
 static NS_METHOD AppInfoConstructor(nsISupports* aOuter,
                                     REFNSIID aIID, void **aResult)
 {
   NS_ENSURE_NO_AGGREGATION(aOuter);
 
--- a/xpcom/system/Makefile.in
+++ b/xpcom/system/Makefile.in
@@ -44,11 +44,12 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE          = xpcom
 XPIDL_MODULE    = xpcom_system
 
 XPIDLSRCS = \
         nsIXULAppInfo.idl \
         nsIGConfService.idl \
         nsIGnomeVFSService.idl \
+        nsICrashReporter.idl \
         $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/xpcom/system/nsICrashReporter.idl
@@ -0,0 +1,70 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Breakpad Integration.
+ *
+ * The Initial Developer of the Original Code is
+ * Ted Mielczarek <ted.mielczarek@gmail.com>
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+/**
+ * Provides access to crash reporting functionality.
+ * @status UNSTABLE - This interface is not frozen and will probably change in
+ *                    future releases.
+ */
+
+[scriptable, uuid(4d6449fe-d642-45e5-9773-41af5793c99a)]
+interface nsICrashReporter : nsISupports
+{
+  /**
+   * Add some extra data to be submitted with a crash report.
+   * @param key
+   *        Name of the data to be added.
+   * @param data
+   *        Data to be added.
+   *
+   * @throw NS_ERROR_NOT_INITIALIZED if crash reporting not initialized
+   * @throw NS_ERROR_INVALID_ARG if key or data contain invalid characters.
+   *                             Invalid characters for key are '=' and
+   *                             '\n'.  Invalid character for data is '\0'.
+   */
+  void annotateCrashReport(in ACString key, in ACString data);
+  
+  /**
+    * Write a minidump immediately, with the user-supplied exception
+    * information. This is implemented on Windows only, because
+    * SEH (structured exception handling) exists on Windows only.
+    * @param aExceptionInfo  EXCEPTION_INFO* provided by Window's SEH
+    */
+  [noscript] void WriteMinidumpForException(in voidPtr aExceptionInfo);
+};