From ebdc98cf6c19e8a4f2de02e28f51048d25cbf70f Mon Sep 17 00:00:00 2001 From: Vance Morrison Date: Fri, 16 Mar 2018 17:26:21 -0700 Subject: This change make DacTableGen work for VS2017 There was a issue (see https://github.com/dotnet/coreclr/issues/11305) where a tool used in the CoreCLR build called DacTableGen requires a old version of the msdia120.dll. The symptom is that this tool would fail with a class not registered errror. This tool comes from a very old nuget package microsoft.dotnet.buildtools.coreclr, which we no longer can build easly. Our guidance now is to move tools that are only used in one repository (like this one) out of nuget packages and simply build them as part of the build. This change makes a step in that direction. The DacTableGen code actually was already in the CoreCLR repo, so this change 1. Fixes the source of DacTableGen so that tool no longer needs a com object to be registered (but it DOES need msdia140.dll to be on the path. This is true for VS2017. 2. Turns on the build of DacTableGen 3. Change the build use the built DacTableGen (unless running on VS2017, in that case we use the the version in the tool package. 4.) Remove the hack that warns people to register msdia120 (since you don't need to anymore) There is also an unrelated addition to the docs. This change should still work for VS2015 (because it falls back to the old DacTableGen in that case) Finally we should move to using the Linux method of creating the DAC, and so all these tools and their nuget package can be removed. --- src/ToolBox/SOS/CMakeLists.txt | 1 + src/ToolBox/SOS/DacTableGen/CMakeLists.txt | 8 +++---- src/ToolBox/SOS/DacTableGen/DIALib.dll | Bin 0 -> 42496 bytes src/ToolBox/SOS/DacTableGen/diautil.cs | 36 +++++++++++++++++++++++++++-- src/dlls/mscoree/coreclr/CMakeLists.txt | 9 +++++++- 5 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 src/ToolBox/SOS/DacTableGen/DIALib.dll (limited to 'src') diff --git a/src/ToolBox/SOS/CMakeLists.txt b/src/ToolBox/SOS/CMakeLists.txt index 9380dc1de6..212f4eebd7 100644 --- a/src/ToolBox/SOS/CMakeLists.txt +++ b/src/ToolBox/SOS/CMakeLists.txt @@ -1,3 +1,4 @@ if(WIN32) + add_subdirectory(DacTableGen) add_subdirectory(Strike) endif(WIN32) diff --git a/src/ToolBox/SOS/DacTableGen/CMakeLists.txt b/src/ToolBox/SOS/DacTableGen/CMakeLists.txt index 01ee51f7a4..c980cc2ff8 100644 --- a/src/ToolBox/SOS/DacTableGen/CMakeLists.txt +++ b/src/ToolBox/SOS/DacTableGen/CMakeLists.txt @@ -7,13 +7,13 @@ set(DACTABLEGEN_SOURCES # Cmake does not support csharp sources so add custom command add_custom_target(dactablegen ALL - COMMAND csc.exe /t:exe /platform:anycpu /r:System.dll /r:$ /out:${CMAKE_CURRENT_BINARY_DIR}/dactablegen.exe ${DACTABLEGEN_SOURCES} - COMMAND ${CMAKE_COMMAND} -E copy $ $ - DEPENDS ${DACTABLEGEN_SOURCES} dialib + COMMAND csc.exe /t:exe /platform:anycpu32bitpreferred /r:System.dll /r:DiaLib.dll /out:${CMAKE_CURRENT_BINARY_DIR}/dactablegen.exe ${DACTABLEGEN_SOURCES} + COMMAND ${CMAKE_COMMAND} -E copy DIAlib.dll ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${DACTABLEGEN_SOURCES} DIAlib.dll WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) # In order to use dactablegen as an executable target it needs to be imported. # Target is used in dll/mscoree/coreclr/cmakelists.txt add_executable(dactablegen_exe IMPORTED GLOBAL) -set_property(TARGET dactablegen_exe PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/dactablegen.exe) \ No newline at end of file +set_property(TARGET dactablegen_exe PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/dactablegen.exe) diff --git a/src/ToolBox/SOS/DacTableGen/DIALib.dll b/src/ToolBox/SOS/DacTableGen/DIALib.dll new file mode 100644 index 0000000000..06665740dc Binary files /dev/null and b/src/ToolBox/SOS/DacTableGen/DIALib.dll differ diff --git a/src/ToolBox/SOS/DacTableGen/diautil.cs b/src/ToolBox/SOS/DacTableGen/diautil.cs index d0e9c811a7..f0937b190e 100644 --- a/src/ToolBox/SOS/DacTableGen/diautil.cs +++ b/src/ToolBox/SOS/DacTableGen/diautil.cs @@ -97,7 +97,7 @@ class Util public class DiaFile { - DiaSourceClass m_dsc; + IDiaDataSource m_dsc; IDiaSession m_session; DiaSymbol m_global; IDiaEnumSymbols m_publicsEnum; @@ -106,7 +106,7 @@ public class DiaFile public DiaFile(String pdbFile, String dllFile) { - m_dsc = new DiaSourceClass(); + m_dsc = GetDiaSourceClass(); string pdbPath = System.IO.Path.GetDirectoryName(pdbFile); // Open the PDB file, validating it matches the supplied DLL file @@ -414,6 +414,37 @@ public class DiaFile E_PDB_SYMSRV_CACHE_FULL , E_PDB_MAX } + + // Get the DiaSourceClass from the msdia140.dll in the app directory without using COM activation + static IDiaDataSource GetDiaSourceClass() { + // This is Class ID for the DiaSourceClass used by msdia140. + var diaSourceClassGuid = new Guid("{e6756135-1e65-4d17-8576-610761398c3c}"); + var comClassFactory = (IClassFactory)DllGetClassObject(diaSourceClassGuid, typeof(IClassFactory).GUID); + + // As the DLL to create a new instance of it + object comObject = null; + Guid iDiaDataSourceGuid = typeof(IDiaDataSource).GUID; + comClassFactory.CreateInstance(null, ref iDiaDataSourceGuid, out comObject); + + // And return it as the type we expect + return (comObject as IDiaDataSource); + } + + [return: MarshalAs(UnmanagedType.Interface)] + [DllImport("msdia140.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] + private static extern object DllGetClassObject( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid); + + [ComImport, ComVisible(false), Guid("00000001-0000-0000-C000-000000000046"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + private interface IClassFactory + { + void CreateInstance([MarshalAs(UnmanagedType.Interface)] object aggregator, + ref Guid refiid, + [MarshalAs(UnmanagedType.Interface)] out object createdObject); + void LockServer(bool incrementRefCount); + } } /*************************************************************************************** @@ -806,4 +837,5 @@ public class DiaDataSymbol : DiaSymbol } } + } // Namespace Dia.Util diff --git a/src/dlls/mscoree/coreclr/CMakeLists.txt b/src/dlls/mscoree/coreclr/CMakeLists.txt index fb5cc90291..cb08438c4d 100644 --- a/src/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/dlls/mscoree/coreclr/CMakeLists.txt @@ -162,11 +162,18 @@ if(WIN32) clr_unknown_arch() endif() + set(DACTABLEGEN_EXE ${CMAKE_CURRENT_BINARY_DIR}/../../../ToolBox/SOS/DacTableGen/dactablegen.exe) + # The DactTableGen executable that we build needs an msdia140.dll supplied by Visual Studio. + # however VS2015 may not have this, so fall back to the DactTableGen in the tools package (which is old) + if($ENV{__VSVersion} STREQUAL "vs2015") + set(DACTABLEGEN_EXE ${BuildToolsDir}/dactablegen.exe) + endif() + add_custom_command( DEPENDS coreclr mscordaccore mscordbi ${CLR_DIR}/src/debug/daccess/daccess.cpp OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/inject_debug_resources.timestamp COMMAND ${CMAKE_CXX_COMPILER} /P /EP /TP ${PREPROCESS_DEFINITIONS} ${INC_DIR} /Fi${CMAKE_CURRENT_BINARY_DIR}/daccess.i ${CLR_DIR}/src/debug/daccess/daccess.cpp - COMMAND ${BuildToolsDir}/dactablegen.exe /dac:${CMAKE_CURRENT_BINARY_DIR}/daccess.i /pdb:${CMAKE_CURRENT_BINARY_DIR}/$/coreclr.pdb /dll:$ /bin:${CMAKE_CURRENT_BINARY_DIR}/wks.bin + COMMAND ${DACTABLEGEN_EXE} /dac:${CMAKE_CURRENT_BINARY_DIR}/daccess.i /pdb:${CMAKE_CURRENT_BINARY_DIR}/$/coreclr.pdb /dll:$ /bin:${CMAKE_CURRENT_BINARY_DIR}/wks.bin COMMAND ${BuildToolsDir}/InjectResource.exe /bin:${CMAKE_CURRENT_BINARY_DIR}/wks.bin /dll:$ COMMAND ${BuildToolsDir}/GenClrDebugResource.exe /dac:$ /dbi:$ /sku:onecoreclr /out:${CMAKE_CURRENT_BINARY_DIR}/clrDebugResource.bin COMMAND ${BuildToolsDir}/InjectResource.exe /bin:${CMAKE_CURRENT_BINARY_DIR}/clrDebugResource.bin /dll:$ /name:CLRDEBUGINFO -- cgit v1.2.3