ios: Fix leak in iOS NSException preprocessor.

Call __cxa_free_exception after __cxa_allocate_exception usage.

Change-Id: I0cd5043b945652e6ac28c3bf79486c071d3aa09e
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/4990028
Commit-Queue: Justin Cohen <justincohen@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
diff --git a/client/ios_handler/exception_processor.mm b/client/ios_handler/exception_processor.mm
index b61d56c..470b0e7 100644
--- a/client/ios_handler/exception_processor.mm
+++ b/client/ios_handler/exception_processor.mm
@@ -324,6 +324,20 @@
 #endif
 }
 
+//! \brief Helper to release memory from calls to __cxa_allocate_exception.
+class ScopedException {
+ public:
+  explicit ScopedException(objc_exception* exception) : exception_(exception) {}
+
+  ScopedException(const ScopedException&) = delete;
+  ScopedException& operator=(const ScopedException&) = delete;
+
+  ~ScopedException() { __cxxabiv1::__cxa_free_exception(exception_); }
+
+ private:
+  objc_exception* exception_;  // weak
+};
+
 id ObjcExceptionPreprocessor(id exception) {
   // Some sinkholes don't use objc_exception_rethrow when they should, which
   // would otherwise prevent the exception_preprocessor from getting called
@@ -384,6 +398,7 @@
   // From 10.15.0 objc4-779.1/runtime/objc-exception.mm objc_exception_throw.
   objc_exception* exception_objc = reinterpret_cast<objc_exception*>(
       __cxxabiv1::__cxa_allocate_exception(sizeof(objc_exception)));
+  ScopedException exception_objc_owner(exception_objc);
   exception_objc->obj = exception;
   exception_objc->tinfo.vtable = objc_ehtype_vtable + 2;
   exception_objc->tinfo.name = object_getClassName(exception);