[autotest] Add faulthandler to autoserv

This change adds the faulthandler package as a new external_package.
It then imports it to autoserv and then registers SIGTERM. This will
dump the thread's current traceback on SIGTERM then execute the
previous signal handler.

BUG=chromium:302815
DEPLOY=build_externals
TEST=Executed build_externals and ensured faulthandler was downloaded
and installed and that re-executing build_externals did not reinstall
it. Then ran sleeptest with a 1 minute timeout and ensured the
faulthandler output showed up in autoserv.DEBUG when the scheduler
aborted it.

Change-Id: Id59f897bb766a821ef463c8166531db480c68041
Reviewed-on: https://chromium-review.googlesource.com/181688
Reviewed-by: Alex Miller <milleral@chromium.org>
Commit-Queue: Simran Basi <sbasi@chromium.org>
Tested-by: Simran Basi <sbasi@chromium.org>
diff --git a/server/autoserv b/server/autoserv
index 0883111..bf3b6ce 100755
--- a/server/autoserv
+++ b/server/autoserv
@@ -60,11 +60,24 @@
         if pid_file_manager:
             pid_file_manager.close_file(1, signal.SIGTERM)
         logging.debug('Finished writing to pid_file. Killing process.')
+        # TODO (sbasi) - remove the time.sleep when crbug.com/302815 is solved.
+        # This sleep allows the pending output to be logged before the kill
+        # signal is sent.
+        time.sleep(.1)
         os.killpg(os.getpgrp(), signal.SIGKILL)
 
     # Set signal handler
     signal.signal(signal.SIGTERM, handle_sigterm)
 
+    # faulthandler is only needed to debug in the Lab and is not avaliable to
+    # be imported in the chroot as part of VMTest, so Try-Except it.
+    try:
+        import faulthandler
+        faulthandler.register(signal.SIGTERM, all_threads=True, chain=True)
+        logging.debug('faulthandler registered on SIGTERM.')
+    except ImportError:
+        pass
+
     # Ignore SIGTTOU's generated by output from forked children.
     signal.signal(signal.SIGTTOU, signal.SIG_IGN)