Add system-gdbinit/fuchia.py.

Change-Id: Ibf377c5453000dd8b70fecb97b71c02add1af480
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 32acb09..bfbdcb8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2016-12-15  Doug Evans  <dje@google.com>
+
+	* system-gdbinit/fuchsia.py: New file.
+	* data-directory/Makefile.in (SYSTEM_GDBINIT_FILES): Add fuchsia.py.
+
 2016-12-14  Doug Evans  <dje@google.com>
 
 	Beginnings of Fuchsia amd64 port.
diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
index 51b5c2a..bf74c72 100644
--- a/gdb/data-directory/Makefile.in
+++ b/gdb/data-directory/Makefile.in
@@ -137,6 +137,7 @@
 SYSTEM_GDBINIT_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(SYSTEM_GDBINIT_DIR)
 SYSTEM_GDBINIT_FILES = \
 	elinos.py \
+	fuchsia.py \
 	wrs-linux.py
 
 FLAGS_TO_PASS = \
diff --git a/gdb/system-gdbinit/fuchsia.py b/gdb/system-gdbinit/fuchsia.py
new file mode 100644
index 0000000..b5d18cf
--- /dev/null
+++ b/gdb/system-gdbinit/fuchsia.py
@@ -0,0 +1,82 @@
+# Copyright 2016 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Initialize gdb for debugging fuchsia code."""
+
+import gdb
+import os
+import sys
+
+
+_FUCHSIA_SYS_PATH = "scripts/gdb"
+_FUCHSIA_GDB_FILE = _FUCHSIA_SYS_PATH + "/fuchsia/gdb/__init__.py"
+
+
+def _get_sys_path(fuchsia_gdb_file):
+  """Return sys.path entry for gdb support.
+
+  Arguments:
+    fuchsia_gdb_file: The absolute path to _FUCHSIA_GDB_FILE.
+
+  Returns:
+    Path to add to sys.path.
+  """
+
+  # /foo/bar/fuchsia/gdb/__init__.py -> /foo/bar
+  return os.path.dirname(os.path.dirname(os.path.dirname(fuchsia_gdb_file)))
+
+
+def _find_file(file):
+  """Look for file in current directory and every parent.
+
+  Returns:
+    Absolute path of found file or None if not found.
+  """
+
+  cwd = os.getcwd()
+
+  while cwd != "/":
+    trial = os.path.join(cwd, file)
+    if os.path.exists(trial):
+      return trial
+    # Protect against unknown failure modes.
+    new_cwd = os.path.dirname(cwd)
+    if new_cwd == cwd:
+      print "Trouble with file system trying to find: %s" % (file)
+      sys.exit(1)
+    cwd = new_cwd
+  return None
+
+
+def _append_sys_path(path):
+  """Append path to sys.path if not already present."""
+  # Python2 canonicalizes directories in sys.path, so we do too.
+  path = os.path.abspath(path)
+  if os.path.exists(path) and \
+      path not in sys.path:
+    sys.path.append(path)
+
+
+def _try_bootstrap():
+  """Try to find Fuchsia support and load it.
+
+  Most of Fuchsia support comes with the Fuchsia tree in the scripts repo.
+  We just need to find it.
+  """
+
+  fuchsia_gdb_file = _find_file(_FUCHSIA_GDB_FILE)
+  if fuchsia_gdb_file != None:
+    _append_sys_path(_get_sys_path(fuchsia_gdb_file))
+    # TODO(dje): Catch certain exceptions?
+    import fuchsia.gdb
+    fuchsia.gdb.Initialize()
+  else:
+    print "Unable to find Fuchsia support. In Fuchsia tree?"
+    print "Looking for file: %s" % (_FUCHSIA_GDB_FILE)
+
+
+# This message is quite helpful for debugging issues with the python support.
+print "Hi, this is fuchsia.py. Adding Fuchsia support."
+
+_try_bootstrap()