diagnose-me.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!/usr/bin/env python
  2. # Copyright (c) 2012 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """Diagnose some common system configuration problems on Linux, and
  6. suggest fixes."""
  7. from __future__ import print_function
  8. import os
  9. import subprocess
  10. import sys
  11. all_checks = []
  12. def Check(name):
  13. """Decorator that defines a diagnostic check."""
  14. def wrap(func):
  15. all_checks.append((name, func))
  16. return func
  17. return wrap
  18. @Check("/usr/bin/ld is not gold")
  19. def CheckSystemLd():
  20. proc = subprocess.Popen(['/usr/bin/ld', '-v'], stdout=subprocess.PIPE)
  21. stdout = proc.communicate()[0]
  22. if 'GNU gold' in stdout:
  23. return ("When /usr/bin/ld is gold, system updates can silently\n"
  24. "corrupt your graphics drivers.\n"
  25. "Try 'sudo apt-get remove binutils-gold'.\n")
  26. return None
  27. @Check("random lds are not in the $PATH")
  28. def CheckPathLd():
  29. proc = subprocess.Popen(['which', '-a', 'ld'], stdout=subprocess.PIPE)
  30. stdout = proc.communicate()[0]
  31. instances = stdout.split()
  32. if len(instances) > 1:
  33. return ("You have multiple 'ld' binaries in your $PATH:\n"
  34. + '\n'.join(' - ' + i for i in instances) + "\n"
  35. "You should delete all of them but your system one.\n"
  36. "gold is hooked into your build via gyp.\n")
  37. return None
  38. @Check("/usr/bin/ld doesn't point to gold")
  39. def CheckLocalGold():
  40. # Check /usr/bin/ld* symlinks.
  41. for path in ('ld.bfd', 'ld'):
  42. path = '/usr/bin/' + path
  43. try:
  44. target = os.readlink(path)
  45. except OSError, e:
  46. if e.errno == 2:
  47. continue # No such file
  48. if e.errno == 22:
  49. continue # Not a symlink
  50. raise
  51. if '/usr/local/gold' in target:
  52. return ("%s is a symlink into /usr/local/gold.\n"
  53. "It's difficult to make a recommendation, because you\n"
  54. "probably set this up yourself. But you should make\n"
  55. "/usr/bin/ld be the standard linker, which you likely\n"
  56. "renamed /usr/bin/ld.bfd or something like that.\n" % path)
  57. return None
  58. @Check("random ninja binaries are not in the $PATH")
  59. def CheckPathNinja():
  60. proc = subprocess.Popen(['which', 'ninja'], stdout=subprocess.PIPE)
  61. stdout = proc.communicate()[0]
  62. if not 'depot_tools' in stdout:
  63. return ("The ninja binary in your path isn't from depot_tools:\n"
  64. + " " + stdout +
  65. "Remove custom ninjas from your path so that the one\n"
  66. "in depot_tools is used.\n")
  67. return None
  68. @Check("build dependencies are satisfied")
  69. def CheckBuildDeps():
  70. script_path = os.path.join(
  71. os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'build',
  72. 'install-build-deps.sh')
  73. proc = subprocess.Popen([script_path, '--quick-check'],
  74. stdout=subprocess.PIPE)
  75. stdout = proc.communicate()[0]
  76. if 'WARNING' in stdout:
  77. return ("Your build dependencies are out-of-date.\n"
  78. "Run '" + script_path + "' to update.")
  79. return None
  80. def RunChecks():
  81. for name, check in all_checks:
  82. sys.stdout.write("* Checking %s: " % name)
  83. sys.stdout.flush()
  84. error = check()
  85. if not error:
  86. print("ok")
  87. else:
  88. print("FAIL")
  89. print(error)
  90. if __name__ == '__main__':
  91. RunChecks()