Add valgrind pass to test script.  Fix valgrind errors.
diff --git a/c++/src/kj/array.c++ b/c++/src/kj/array.c++
index 53f8ed6..36d7055 100644
--- a/c++/src/kj/array.c++
+++ b/c++/src/kj/array.c++
@@ -22,6 +22,7 @@
 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "array.h"
+#include "exception.h"
 
 namespace kj {
 
@@ -62,38 +63,43 @@
 
 namespace _ {  // private
 
+struct AutoDeleter {
+  void* ptr;
+  inline void* release() { void* result = ptr; ptr = nullptr; return result; }
+  inline AutoDeleter(void* ptr): ptr(ptr) {}
+  inline ~AutoDeleter() { operator delete(ptr); }
+};
+
 void* HeapArrayDisposer::allocateImpl(size_t elementSize, size_t elementCount, size_t capacity,
                                       void (*constructElement)(void*),
                                       void (*destroyElement)(void*)) {
-  void* result = operator new(elementSize * capacity);
+  AutoDeleter result(operator new(elementSize * capacity));
 
   if (constructElement == nullptr) {
     // Nothing to do.
   } else if (destroyElement == nullptr) {
-    byte* pos = reinterpret_cast<byte*>(result);
+    byte* pos = reinterpret_cast<byte*>(result.ptr);
     while (elementCount > 0) {
       constructElement(pos);
       pos += elementSize;
       --elementCount;
     }
   } else {
-    ExceptionSafeArrayUtil guard(result, elementSize, 0, destroyElement);
+    ExceptionSafeArrayUtil guard(result.ptr, elementSize, 0, destroyElement);
     guard.construct(elementCount, constructElement);
     guard.release();
   }
 
-  return result;
+  return result.release();
 }
 
 void HeapArrayDisposer::disposeImpl(
     void* firstElement, size_t elementSize, size_t elementCount, size_t capacity,
     void (*destroyElement)(void*)) const {
   // Note that capacity is ignored since operator delete() doesn't care about it.
+  AutoDeleter deleter(firstElement);
 
-  if (destroyElement == nullptr) {
-    operator delete(firstElement);
-  } else {
-    KJ_DEFER(operator delete(firstElement));
+  if (destroyElement != nullptr) {
     ExceptionSafeArrayUtil guard(firstElement, elementSize, elementCount, destroyElement);
     guard.destroyAll();
   }
diff --git a/c++/src/kj/exception-test.c++ b/c++/src/kj/exception-test.c++
index 3e2df30..5d18248 100644
--- a/c++/src/kj/exception-test.c++
+++ b/c++/src/kj/exception-test.c++
@@ -95,6 +95,40 @@
 #endif
 }
 
+#if !KJ_NO_EXCEPTIONS
+TEST(Exception, ScopeSuccessFail) {
+  bool success = false;
+  bool failure = false;
+
+  {
+    KJ_ON_SCOPE_SUCCESS(success = true);
+    KJ_ON_SCOPE_FAILURE(failure = true);
+
+    EXPECT_FALSE(success);
+    EXPECT_FALSE(failure);
+  }
+
+  EXPECT_TRUE(success);
+  EXPECT_FALSE(failure);
+
+  success = false;
+  failure = false;
+
+  try {
+    KJ_ON_SCOPE_SUCCESS(success = true);
+    KJ_ON_SCOPE_FAILURE(failure = true);
+
+    EXPECT_FALSE(success);
+    EXPECT_FALSE(failure);
+
+    throw 1;
+  } catch (int) {}
+
+  EXPECT_FALSE(success);
+  EXPECT_TRUE(failure);
+}
+#endif
+
 }  // namespace
 }  // namespace _ (private)
 }  // namespace kj
diff --git a/c++/src/kj/exception.h b/c++/src/kj/exception.h
index b701e3d..c0c21f0 100644
--- a/c++/src/kj/exception.h
+++ b/c++/src/kj/exception.h
@@ -262,6 +262,16 @@
   }
 }
 
+#define KJ_ON_SCOPE_SUCCESS(code) \
+  ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \
+  KJ_DEFER(if (!KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; })
+// Runs `code` if the current scope is exited normally (not due to an exception).
+
+#define KJ_ON_SCOPE_FAILURE(code) \
+  ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \
+  KJ_DEFER(if (KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; })
+// Runs `code` if the current scope is exited due to an exception.
+
 }  // namespace kj
 
 #endif  // KJ_EXCEPTION_H_
diff --git a/c++/src/kj/io.c++ b/c++/src/kj/io.c++
index 0493fe7..3dfe4cb 100644
--- a/c++/src/kj/io.c++
+++ b/c++/src/kj/io.c++
@@ -295,11 +295,11 @@
   }
 
   while (current < iov.end()) {
-    ssize_t n;
+    ssize_t n = 0;
     KJ_SYSCALL(n = ::writev(fd, current, iov.end() - current), fd);
     KJ_ASSERT(n > 0, "writev() returned zero.");
 
-    while (static_cast<size_t>(n) >= current->iov_len) {
+    while (n > 0 && static_cast<size_t>(n) >= current->iov_len) {
       n -= current->iov_len;
       ++current;
     }