changeset 85:c8db7ce22241 8.1.x

Merge with fb/windbg
author Evgeniy.Koshkin
date Mon, 12 Jan 2015 15:50:18 +0400
parents 1147ad4b741a (current diff) 2e0b92a9ff26 (diff)
children fc50962148fa
files agent/src/jetbrains/buildServer/symbols/tools/WinDbgToolsDetector.java
diffstat 4 files changed, 152 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/META-INF/build-agent-plugin-symbol-server.xml	Mon Jan 12 14:48:45 2015 +0300
+++ b/agent/src/META-INF/build-agent-plugin-symbol-server.xml	Mon Jan 12 15:50:18 2015 +0400
@@ -7,5 +7,6 @@
         >
 
   <bean class="jetbrains.buildServer.symbols.SymbolsIndexer"/>
+  <bean class="jetbrains.buildServer.symbols.WinDbgToolsDetector"/>
 
 </beans>
\ No newline at end of file
--- a/agent/src/jetbrains/buildServer/symbols/SymbolsIndexer.java	Mon Jan 12 14:48:45 2015 +0300
+++ b/agent/src/jetbrains/buildServer/symbols/SymbolsIndexer.java	Mon Jan 12 15:50:18 2015 +0400
@@ -6,7 +6,6 @@
 import jetbrains.buildServer.agent.impl.artifacts.ArtifactsCollection;
 import jetbrains.buildServer.agent.plugins.beans.PluginDescriptor;
 import jetbrains.buildServer.symbols.tools.JetSymbolsExe;
-import jetbrains.buildServer.symbols.tools.WinDbgToolsDetector;
 import jetbrains.buildServer.util.EventDispatcher;
 import jetbrains.buildServer.util.FileUtil;
 import org.apache.log4j.Logger;
@@ -18,6 +17,7 @@
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
@@ -28,6 +28,8 @@
   private static final Logger LOG = Logger.getLogger(SymbolsIndexer.class);
 
   public static final String PDB_FILE_EXTENSION = "pdb";
+  private static final String X64_SRCSRV = "\\x64\\srcsrv";
+  private static final String X86_SRCSRV = "\\x86\\srcsrv";
 
   @NotNull private final ArtifactsWatcher myArtifactsWatcher;
   @NotNull private final JetSymbolsExe myJetSymbolsExe;
@@ -54,7 +56,7 @@
         myProgressLogger = runningBuild.getBuildLogger();
         myBuildTempDirectory = runningBuild.getBuildTempDirectory();
 
-        mySrcSrvHomeDir = WinDbgToolsDetector.getSrcSrvHomeDir(runningBuild);
+        mySrcSrvHomeDir = getSrcSrvHomeDir(runningBuild);
         if (mySrcSrvHomeDir == null) {
           LOG.error("Failed to find Source Server tools home directory. No symbol and source indexing will be performed.");
           myProgressLogger.error("Failed to find Source Server tools home directory. No symbol and source indexing will be performed.");
@@ -124,6 +126,22 @@
     }
   }
 
+  @Nullable
+  private File getSrcSrvHomeDir(@NotNull AgentRunningBuild build) {
+    final Map<String,String> agentConfigParameters = build.getAgentConfiguration().getConfigurationParameters();
+    String winDbgHomeDir = agentConfigParameters.get(WinDbgToolsDetector.WIN_DBG_PATH);
+    if(winDbgHomeDir == null){
+      LOG.debug("WinDbg tools are not mentioned in agent configuration.");
+      return null;
+    }
+    File srcSrvHomeDir = new File(winDbgHomeDir, X64_SRCSRV);
+    if (srcSrvHomeDir.isDirectory()) return srcSrvHomeDir;
+    srcSrvHomeDir = new File(winDbgHomeDir, X86_SRCSRV);
+    if (srcSrvHomeDir.isDirectory()) return srcSrvHomeDir;
+    LOG.debug("Failed to find Source Server tools home directory under WinDbg tools home directory detected on path " + winDbgHomeDir);
+    return null;
+  }
+
   private Collection<File> getArtifactPathsByFileExtension(List<ArtifactsCollection> artifactsCollections, String fileExtension){
     final Collection<File> result = new HashSet<File>();
     for(ArtifactsCollection artifactsCollection : artifactsCollections){
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/jetbrains/buildServer/symbols/WinDbgToolsDetector.java	Mon Jan 12 15:50:18 2015 +0400
@@ -0,0 +1,131 @@
+package jetbrains.buildServer.symbols;
+
+import jetbrains.buildServer.agent.AgentLifeCycleAdapter;
+import jetbrains.buildServer.agent.AgentLifeCycleListener;
+import jetbrains.buildServer.agent.BuildAgent;
+import jetbrains.buildServer.agent.BuildAgentConfiguration;
+import jetbrains.buildServer.dotNet.DotNetConstants;
+import jetbrains.buildServer.util.EventDispatcher;
+import jetbrains.buildServer.util.Win32RegistryAccessor;
+import org.apache.log4j.Logger;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.FileFilter;
+
+import static jetbrains.buildServer.util.Bitness.BIT32;
+import static jetbrains.buildServer.util.Win32RegistryAccessor.Hive.LOCAL_MACHINE;
+
+/**
+ * @author Evgeniy.Koshkin
+ */
+public class WinDbgToolsDetector extends AgentLifeCycleAdapter {
+
+  private static final Logger LOG = Logger.getLogger(WinDbgToolsDetector.class);
+
+  private static final String WINDOWS_KITS_INSTALLED_ROOTS_KEY_PATH = "Software/Microsoft/Windows Kits/Installed Roots";
+  private static final String WIN_DBG_81_ROOT_ENTRY_NAME = "WindowsDebuggersRoot81";
+  private static final String WIN_SDK_81_ROOT_ENTRY_NAME = "KitsRoot81";
+  private static final String WIN_DBG_8_ROOT_ENTRY_NAME = "WindowsDebuggersRoot8";
+  private static final String WIN_SDK_8_ROOT_ENTRY_NAME = "KitsRoot8";
+  private static final String WIN_DBG_HOME_DIR_RELATIVE_SDK8 = "\\Debuggers";
+
+  public static final String WIN_DBG_PATH = "WinDbg" + DotNetConstants.PATH;
+  private static final String DEBUGGING_TOOLS_FOR_WINDOWS = "Debugging Tools for Windows";
+
+  @NotNull private final Win32RegistryAccessor myRegistryAccessor;
+
+  public WinDbgToolsDetector(@NotNull final EventDispatcher<AgentLifeCycleListener> events,
+                             @NotNull final Win32RegistryAccessor registryAccessor) {
+    myRegistryAccessor = registryAccessor;
+    events.addListener(this);
+  }
+
+  @Override
+  public void agentInitialized(@NotNull BuildAgent agent) {
+    final BuildAgentConfiguration config = agent.getConfiguration();
+    if (!config.getSystemInfo().isWindows()) return;
+    LOG.info("Searching WinDbg installation...");
+
+    LOG.info("Searching the WinDbg as part of Windows 8.1 SDK");
+    File winDbgHomeDir = searchSDK8x(WIN_DBG_81_ROOT_ENTRY_NAME, WIN_SDK_81_ROOT_ENTRY_NAME, "8.1");
+    if(winDbgHomeDir == null) {
+      LOG.info("Searching the WinDbg as part of Windows 8 SDK");
+      winDbgHomeDir = searchSDK8x(WIN_DBG_8_ROOT_ENTRY_NAME, WIN_SDK_8_ROOT_ENTRY_NAME, "8");
+    } if(winDbgHomeDir == null) {
+      LOG.info("Searching the WinDbg as part of Windows 7 SDK");
+      winDbgHomeDir = searchSDK7x();
+    }
+
+    if(winDbgHomeDir == null) LOG.info("WinDbg tools were not found on this machine.");
+    else{
+      final String winDbgHomeDirAbsolutePath = winDbgHomeDir.getAbsolutePath();
+      LOG.info("WinDbg tools were found on path " + winDbgHomeDirAbsolutePath);
+      config.addConfigurationParameter(WIN_DBG_PATH, winDbgHomeDirAbsolutePath);
+    }
+  }
+
+  @Nullable
+  private File searchSDK8x(String winDbgRootEntryName, String winSdkRootEntryName, String sdkVersion) {
+    File winDbgHomeDir = myRegistryAccessor.readRegistryFile(LOCAL_MACHINE, BIT32, WINDOWS_KITS_INSTALLED_ROOTS_KEY_PATH, winDbgRootEntryName);
+    if (winDbgHomeDir != null) return winDbgHomeDir;
+    final File sdkHomeDir = myRegistryAccessor.readRegistryFile(LOCAL_MACHINE, BIT32, WINDOWS_KITS_INSTALLED_ROOTS_KEY_PATH, winSdkRootEntryName);
+    if(sdkHomeDir == null){
+      LOG.debug(String.format("Failed to locate Windows SDK %s home directory.", sdkVersion));
+      return null;
+    }
+    LOG.debug(String.format("Windows SDK %s found, searching WinDbg under its home directory.", sdkHomeDir));
+    winDbgHomeDir = new File(sdkHomeDir, WIN_DBG_HOME_DIR_RELATIVE_SDK8);
+    if(winDbgHomeDir.isDirectory()) return winDbgHomeDir;
+    LOG.debug("Failed to find WinDbg home directory under Windows SDK home directory detected on path " + sdkHomeDir.getAbsolutePath());
+    return null;
+  }
+
+  @Nullable
+  private File searchSDK7x() {
+    final String systemDrive = ensureSuffix(getEnv("SYSTEMDRIVE", "C:"), ":").toUpperCase();
+    final File programFilesDir = new File(systemDrive, "Program Files");
+    final File programFilesX86Dir = new File(systemDrive, "Program Files (x86)");
+    if(!programFilesDir.isDirectory() && !programFilesX86Dir.isDirectory()){
+      LOG.debug(String.format("Failed to locate 'Program Files' directory on the machine. Checked paths: %s, %s", programFilesDir, programFilesX86Dir));
+      return null;
+    }
+    File winDbgHome = findWinDbgHomeInDirectory(programFilesDir);
+    if(winDbgHome == null){
+      winDbgHome = findWinDbgHomeInDirectory(programFilesX86Dir);
+    }
+    return winDbgHome;
+  }
+
+  @Nullable
+  private File findWinDbgHomeInDirectory(File directory) {
+    if (!directory.isDirectory()) return null;
+
+    final String directoryAbsolutePath = directory.getAbsolutePath();
+    LOG.info("Searching for WinDbg home under " + directoryAbsolutePath);
+
+    final File[] matches = directory.listFiles(new FileFilter() {
+      public boolean accept(File pathname) {
+        return pathname.isDirectory() && pathname.getName().startsWith(DEBUGGING_TOOLS_FOR_WINDOWS);
+      }
+    });
+
+    if (matches == null || matches.length == 0) LOG.info("WinDbg home was NOT found under " + directoryAbsolutePath);
+    else return matches[0];
+    return null;
+  }
+
+  @NotNull
+  private static String ensureSuffix(final @NotNull String string, final @NotNull String suffix) {
+    int n = string.length(),
+            m = suffix.length();
+    return n >= m && string.endsWith(suffix) ? string : string + suffix;
+  }
+
+  @NotNull
+  private static String getEnv(final @NotNull String variableName, final @NotNull String defaultValue) {
+    String value = System.getenv(variableName);
+    return value != null ? value : defaultValue;
+  }
+}
--- a/agent/src/jetbrains/buildServer/symbols/tools/WinDbgToolsDetector.java	Mon Jan 12 14:48:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-package jetbrains.buildServer.symbols.tools;
-
-import jetbrains.buildServer.agent.AgentRunningBuild;
-import jetbrains.buildServer.dotNet.DotNetConstants;
-import jetbrains.buildServer.util.CollectionsUtil;
-import jetbrains.buildServer.util.filters.Filter;
-import org.apache.log4j.Logger;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Evgeniy.Koshkin
- */
-public class WinDbgToolsDetector {
-
-  private static final Logger LOG = Logger.getLogger(WinDbgToolsDetector.class);
-
-  private static final String SRCSRV_HOME_DIR_RELATIVE_X64 = "\\Debuggers\\x64\\srcsrv\\";
-  private static final String SRCSRV_HOME_DIR_RELATIVE_X86 = "\\Debuggers\\x86\\srcsrv\\";
-
-  @Nullable
-  public static File getSrcSrvHomeDir(@NotNull AgentRunningBuild build) {
-    final Map<String,String> agentConfigParameters = build.getAgentConfiguration().getConfigurationParameters();
-    final List<String> winSdkPathParams = CollectionsUtil.filterCollection(agentConfigParameters.keySet(), new Filter<String>() {
-      public boolean accept(@NotNull String paramName) {
-        return paramName.startsWith(DotNetConstants.WINDOWS_SDK) && paramName.endsWith(DotNetConstants.PATH);
-      }
-    });
-    if(winSdkPathParams.isEmpty()){
-      LOG.debug("None of Windows SDK versions are mentioned in agent configuration.");
-      return null;
-    }
-
-    for (String paramName : winSdkPathParams){
-      final File winSdkHomeDir = new File(agentConfigParameters.get(paramName));
-      if(!winSdkHomeDir.exists()) {
-        LOG.debug(String.format("Windows SDK home directory mentioned in parameter %s is not exist. Checked path %s.", paramName, winSdkHomeDir.getAbsolutePath()));
-        continue;
-      }
-      File dir = new File(winSdkHomeDir, SRCSRV_HOME_DIR_RELATIVE_X64);
-      if(dir.exists() && dir.isDirectory()) return dir;
-      dir = new File(winSdkHomeDir, SRCSRV_HOME_DIR_RELATIVE_X86);
-      if(dir.exists() && dir.isDirectory()) return dir;
-      LOG.debug("Failed to find Source Server tools home directory under Windows SDK home directory detected on path " + winSdkHomeDir.getAbsolutePath());
-    }
-    LOG.debug("None of detected Windows SDK installations contain Source Server tools.");
-    return null;
-  }
-}