Add threads stack dumping feature (through SIGUSR1) to test_runner.py.

BUG=320445
[email protected]

Review URL: https://codereview.chromium.org/59873011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235996 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index fa3e785..ea6ef09 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -11,7 +11,10 @@
 import optparse
 import os
 import shutil
+import signal
 import sys
+import threading
+import traceback
 
 from pylib import android_commands
 from pylib import constants
@@ -793,7 +796,23 @@
     }
 
 
+def DumpThreadStacks(signal, frame):
+  thread_names_map = dict(
+      [(thread.ident, thread.name) for thread in threading.enumerate()])
+  lines = []
+  for thread_id, stack in sys._current_frames().items():
+    lines.append(
+        '\n# Thread: %s (%d)' % (
+            thread_names_map.get(thread_id, ''), thread_id))
+    for filename, lineno, name, line in traceback.extract_stack(stack):
+      lines.append('File: "%s", line %d, in %s' % (filename, lineno, name))
+      if line:
+        lines.append('  %s' % (line.strip()))
+    print '\n'.join(lines)
+
+
 def main(argv):
+  signal.signal(signal.SIGUSR1, DumpThreadStacks)
   option_parser = command_option_parser.CommandOptionParser(
       commands_dict=VALID_COMMANDS)
   return command_option_parser.ParseAndExecute(option_parser)