Bug 381049 - Pass swallowed crashes inside MSAA/IA2 methods to breakpad, patch=aaronlev, r=me, ted.mielczarek, sr=benjamin, a=dsicore

This commit is contained in:
surkov.alexander@gmail.com 2008-02-08 18:40:47 -08:00
Родитель 43bf4e8fbc
Коммит 03e2f49979
9 изменённых файлов: 156 добавлений и 12 удалений

Просмотреть файл

@ -569,3 +569,23 @@ void nsAccessNodeWrap::ShutdownAccessibility()
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;
}

Просмотреть файл

@ -58,6 +58,9 @@
#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);
@ -146,6 +149,8 @@ class nsAccessNodeWrap : public nsAccessNode,
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);

Просмотреть файл

@ -62,6 +62,13 @@
#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
*/
@ -103,6 +110,7 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsAccessibleWrap, nsAccessible);
// Microsoft COM QueryInterface
STDMETHODIMP nsAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
{
__try {
*ppv = NULL;
if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid)
@ -139,6 +147,7 @@ STDMETHODIMP nsAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
return nsAccessNodeWrap::QueryInterface(iid, ppv);
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -180,6 +189,7 @@ STDMETHODIMP nsAccessibleWrap::NotifyWinEvent(DWORD event,
STDMETHODIMP nsAccessibleWrap::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispParent)
{
__try {
*ppdispParent = NULL;
if (!mWeakShell)
return E_FAIL; // We've been shut down
@ -233,11 +243,13 @@ STDMETHODIMP nsAccessibleWrap::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *pp
}
*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;
@ -246,6 +258,7 @@ STDMETHODIMP nsAccessibleWrap::get_accChildCount( long __RPC_FAR *pcountChildren
PRInt32 numChildren;
GetChildCount(&numChildren);
*pcountChildren = numChildren;
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -254,8 +267,8 @@ 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;
@ -272,6 +285,7 @@ STDMETHODIMP nsAccessibleWrap::get_accChild(
*ppdispChild = NativeAccessible(childAccessible);
}
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return (*ppdispChild)? S_OK: E_FAIL;
}
@ -280,6 +294,7 @@ 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));
@ -294,6 +309,7 @@ STDMETHODIMP nsAccessibleWrap::get_accName(
NS_ASSERTION(mIsInitialized, "Access node was not initialized");
#endif
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -303,6 +319,7 @@ 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));
@ -313,7 +330,7 @@ STDMETHODIMP nsAccessibleWrap::get_accValue(
*pszValue = ::SysAllocString(value.get());
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -321,7 +338,9 @@ STDMETHODIMP
nsAccessibleWrap::get_accDescription(VARIANT varChild,
BSTR __RPC_FAR *pszDescription)
{
__try {
*pszDescription = NULL;
nsCOMPtr<nsIAccessible> xpAccessible;
GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
if (!xpAccessible)
@ -417,6 +436,7 @@ nsAccessibleWrap::get_accDescription(VARIANT varChild,
}
*pszDescription = ::SysAllocString(description.get());
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -424,6 +444,7 @@ STDMETHODIMP nsAccessibleWrap::get_accRole(
/* [optional][in] */ VARIANT varChild,
/* [retval][out] */ VARIANT __RPC_FAR *pvarRole)
{
__try {
VariantInit(pvarRole);
nsCOMPtr<nsIAccessible> xpAccessible;
@ -493,6 +514,7 @@ STDMETHODIMP nsAccessibleWrap::get_accRole(
return S_OK;
}
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return E_FAIL;
}
@ -500,6 +522,7 @@ STDMETHODIMP nsAccessibleWrap::get_accState(
/* [optional][in] */ VARIANT varChild,
/* [retval][out] */ VARIANT __RPC_FAR *pvarState)
{
__try {
VariantInit(pvarState);
pvarState->vt = VT_I4;
pvarState->lVal = 0;
@ -514,7 +537,7 @@ STDMETHODIMP nsAccessibleWrap::get_accState(
return E_FAIL;
pvarState->lVal = state;
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -541,6 +564,7 @@ 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));
@ -553,6 +577,7 @@ STDMETHODIMP nsAccessibleWrap::get_accKeyboardShortcut(
*pszKeyboardShortcut = ::SysAllocString(shortcut.get());
return S_OK;
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_FALSE;
}
@ -565,7 +590,7 @@ STDMETHODIMP nsAccessibleWrap::get_accFocus(
// 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
}
@ -587,6 +612,7 @@ STDMETHODIMP nsAccessibleWrap::get_accFocus(
pvarChild->vt = VT_EMPTY; // No focus or focus is not a child
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -624,6 +650,7 @@ private:
HRESULT
AccessibleEnumerator::QueryInterface(REFIID iid, void ** ppvObject)
{
__try {
if (iid == IID_IEnumVARIANT) {
*ppvObject = static_cast<IEnumVARIANT*>(this);
AddRef();
@ -636,6 +663,7 @@ AccessibleEnumerator::QueryInterface(REFIID iid, void ** ppvObject)
}
*ppvObject = NULL;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return E_NOINTERFACE;
}
@ -657,6 +685,7 @@ AccessibleEnumerator::Release(void)
STDMETHODIMP
AccessibleEnumerator::Next(unsigned long celt, VARIANT FAR* rgvar, unsigned long FAR* pceltFetched)
{
__try {
PRUint32 length = 0;
mArray->GetLength(&length);
@ -683,21 +712,27 @@ AccessibleEnumerator::Next(unsigned long celt, VARIANT FAR* rgvar, unsigned long
*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
@ -706,6 +741,7 @@ AccessibleEnumerator::Skip(unsigned long celt)
return S_FALSE;
}
mCurIndex += celt;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -728,6 +764,7 @@ AccessibleEnumerator::Skip(unsigned long celt)
*/
STDMETHODIMP nsAccessibleWrap::get_accSelection(VARIANT __RPC_FAR *pvarChildren)
{
__try {
VariantInit(pvarChildren);
pvarChildren->vt = VT_EMPTY;
@ -750,6 +787,7 @@ STDMETHODIMP nsAccessibleWrap::get_accSelection(VARIANT __RPC_FAR *pvarChildren)
NS_ADDREF(pvarChildren->punkVal = pEnum);
}
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -757,6 +795,7 @@ 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));
@ -768,6 +807,7 @@ STDMETHODIMP nsAccessibleWrap::get_accDefaultAction(
*pszDefaultAction = ::SysAllocString(defaultAction.get());
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -775,6 +815,7 @@ 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));
@ -800,6 +841,7 @@ STDMETHODIMP nsAccessibleWrap::accSelect(
return S_OK;
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return E_FAIL;
}
@ -810,6 +852,7 @@ STDMETHODIMP nsAccessibleWrap::accLocation(
/* [out] */ long __RPC_FAR *pcyHeight,
/* [optional][in] */ VARIANT varChild)
{
__try {
nsCOMPtr<nsIAccessible> xpAccessible;
GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
@ -824,6 +867,7 @@ STDMETHODIMP nsAccessibleWrap::accLocation(
*pcyHeight = height;
return S_OK;
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return E_FAIL;
}
@ -833,6 +877,7 @@ STDMETHODIMP nsAccessibleWrap::accNavigate(
/* [optional][in] */ VARIANT varStart,
/* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt)
{
__try {
nsCOMPtr<nsIAccessible> xpAccessibleStart, xpAccessibleResult;
GetXPAccessibleFor(varStart, getter_AddRefs(xpAccessibleStart));
if (!xpAccessibleStart)
@ -937,6 +982,7 @@ STDMETHODIMP nsAccessibleWrap::accNavigate(
pvarEndUpAt->vt = VT_DISPATCH;
return NS_OK;
}
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return E_FAIL;
}
@ -945,6 +991,7 @@ STDMETHODIMP nsAccessibleWrap::accHitTest(
/* [in] */ long yTop,
/* [retval][out] */ VARIANT __RPC_FAR *pvarChild)
{
__try {
VariantInit(pvarChild);
// convert to window coords
@ -984,6 +1031,7 @@ STDMETHODIMP nsAccessibleWrap::accHitTest(
pvarChild->vt = VT_EMPTY;
return S_FALSE;
}
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -991,12 +1039,14 @@ STDMETHODIMP nsAccessibleWrap::accHitTest(
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;
}
@ -1024,6 +1074,7 @@ nsAccessibleWrap::Next(ULONG aNumElementsRequested, VARIANT FAR* pvar, ULONG FAR
// 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;
@ -1058,12 +1109,14 @@ nsAccessibleWrap::Next(ULONG aNumElementsRequested, VARIANT FAR* pvar, ULONG FAR
}
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;
@ -1074,6 +1127,7 @@ nsAccessibleWrap::Skip(ULONG aNumElements)
mEnumVARIANTPosition = numChildren;
return S_FALSE;
}
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return NOERROR;
}
@ -1090,17 +1144,22 @@ nsAccessibleWrap::Reset(void)
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))
@ -1117,6 +1176,7 @@ nsAccessibleWrap::get_relation(long aRelationIndex,
return E_FAIL;
*aRelation = static_cast<IAccessibleRelation*>(instancePtr);
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -1125,6 +1185,7 @@ nsAccessibleWrap::get_relations(long aMaxRelations,
IAccessibleRelation **aRelation,
long *aNRelations)
{
__try {
*aNRelations = 0;
nsCOMPtr<nsIArray> relations;
@ -1163,12 +1224,14 @@ nsAccessibleWrap::get_relations(long aMaxRelations,
}
*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;
@ -1177,15 +1240,17 @@ nsAccessibleWrap::role(long *role)
"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;
}
@ -1193,12 +1258,15 @@ 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
@ -1206,6 +1274,7 @@ nsAccessibleWrap::get_groupPosition(long *aGroupLevel,
long *aSimilarItemsInGroup,
long *aPositionInGroup)
{
__try {
PRInt32 groupLevel = 0;
PRInt32 similarItemsInGroup = 0;
PRInt32 positionInGroup = 0;
@ -1219,12 +1288,14 @@ nsAccessibleWrap::get_groupPosition(long *aGroupLevel,
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.
@ -1272,6 +1343,7 @@ nsAccessibleWrap::get_states(AccessibleStates *aStates)
if (extraStates & nsIAccessibleStates::EXT_STATE_VERTICAL)
*aStates |= IA2_STATE_VERTICAL;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
@ -1315,40 +1387,47 @@ nsAccessibleWrap::get_localizedExtendedStates(long maxLocalizedExtendedStates,
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.
@ -1385,6 +1464,7 @@ nsAccessibleWrap::get_locale(IA2Locale *aLocale)
// 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;
}
@ -1393,7 +1473,7 @@ nsAccessibleWrap::get_attributes(BSTR *aAttributes)
{
// The format is name:value;name:value; with \ for escaping these
// characters ":;=,\".
__try {
*aAttributes = NULL;
nsCOMPtr<nsIPersistentProperties> attributes;
@ -1448,12 +1528,14 @@ nsAccessibleWrap::get_attributes(BSTR *aAttributes)
}
*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;
@ -1469,6 +1551,7 @@ nsAccessibleWrap::Clone(IEnumVARIANT FAR* FAR* ppenum)
(*ppenum)->Skip(mEnumVARIANTPosition); // QI addrefed
msaaAccessible->Release();
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return NOERROR;
}

Просмотреть файл

@ -89,10 +89,6 @@ DIRS += client
LOCAL_INCLUDES = -I$(srcdir)/google-breakpad/src
DEFINES += -DUNICODE -D_UNICODE
XPIDLSRCS = \
nsICrashReporter.idl \
$(NULL)
EXPORTS = \
nsExceptionHandler.h \
$(NULL)

Просмотреть файл

@ -834,4 +834,15 @@ SetRestartArgs(int argc, char **argv)
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

Просмотреть файл

@ -42,6 +42,13 @@
#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);
@ -51,6 +58,9 @@ 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__ */

Просмотреть файл

@ -827,6 +827,16 @@ nsXULAppInfo::AnnotateCrashReport(const nsACString& key,
{
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;

Просмотреть файл

@ -49,6 +49,7 @@ XPIDLSRCS = \
nsIXULAppInfo.idl \
nsIGConfService.idl \
nsIGnomeVFSService.idl \
nsICrashReporter.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -43,7 +43,7 @@
* future releases.
*/
[scriptable, uuid(da7020ad-fad4-443e-b02b-c5cc9d482e2f)]
[scriptable, uuid(4d6449fe-d642-45e5-9773-41af5793c99a)]
interface nsICrashReporter : nsISupports
{
/**
@ -59,4 +59,12 @@ interface nsICrashReporter : nsISupports
* '\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);
};