Kill the watchdog cleanly before cgroups starts getting involved.

Right now, the watchdog prints an AssertionError traceback if it is killed
with SIGTERM. This actually currently happens every time cbuildbot
exits, because the cgroups logic kills the watchdog with SIGTERM.

To fix the AssertionError, update cleanup.py to catch BaseException
instead of Exception so that it catches the case where a SIGTERM
is thrown as a SystemExit exception. This still prints an error,
but it doesn't print a confusing traceback.

To ensure the watchdog exits before cgroups kills it, add a
contextmanager for ForkWatchdog, so that we can guarantee that
the watchdog exits before cgroups starts messing with it.

BUG=chromium:306904
TEST=Run example build and notice error is missing.
TEST=Verify children are still cleaned up if parent is kill -9'd
TEST=Verify children are cleaned up if parent has an exception

Change-Id: I8b86b58feac6aa284a026164bdd9381c75769f07
Reviewed-on: https://chromium-review.googlesource.com/173246
Reviewed-by: Aviv Keshet <akeshet@chromium.org>
Commit-Queue: David James <davidjames@chromium.org>
Tested-by: David James <davidjames@chromium.org>
diff --git a/scripts/cbuildbot.py b/scripts/cbuildbot.py
index 13d5299..9115bf5 100644
--- a/scripts/cbuildbot.py
+++ b/scripts/cbuildbot.py
@@ -1491,7 +1491,7 @@
     # be rolled back via the contextmanager cleanup handlers.  This
     # ensures that sudo bits cannot outlive cbuildbot, that anything
     # cgroups would kill gets killed, etc.
-    critical_section.ForkWatchdog()
+    stack.Add(critical_section.ForkWatchdog)
 
     if options.timeout > 0:
       stack.Add(cros_build_lib.Timeout, options.timeout)