/// <summary> /// This is the main managed entry point that the native hosting code calls. It needs to be a single function /// and is restricted to just a string parameter because host APIs (i.e. desktop clr) have this narrow interface. /// </summary> /// <param name="extensionPath">Path and filename of native extensions to callback</param> /// <returns>hresult</returns> public static int Initialize( [MarshalAs(UnmanagedType.LPStr)] string extensionPath) { IntPtr extensionLibrary = default; try { extensionLibrary = DataTarget.PlatformFunctions.LoadLibrary(extensionPath); } catch (Exception ex) when(ex is DllNotFoundException || ex is BadImageFormatException) { } if (extensionLibrary == default) { return(HResult.E_FAIL); } var initialializeCallback = SOSHost.GetDelegateFunction <InitializeCallbackDelegate>(extensionLibrary, "InitializeHostServices"); if (initialializeCallback == null) { return(HResult.E_FAIL); } Instance = new HostServices(); return(initialializeCallback(Instance.IHostServices)); }
/// <summary> /// Add all the services needed by commands /// </summary> private void AddServices(DataTarget target) { _serviceProvider.AddService(target); _serviceProvider.AddService <IConsoleService>(_consoleProvider); _serviceProvider.AddService(_commandProcessor); _serviceProvider.AddServiceFactory(typeof(IHelpBuilder), _commandProcessor.CreateHelpBuilder); // Create common analyze context for commands var analyzeContext = new AnalyzeContext() { CurrentThreadId = unchecked ((int)target.DataReader.EnumerateAllThreads().FirstOrDefault()) }; _serviceProvider.AddService(analyzeContext); // Add the register, memory, SOSHost and ClrRuntime services var registerService = new RegisterService(target); _serviceProvider.AddService(registerService); var memoryService = new MemoryService(target.DataReader); _serviceProvider.AddService(memoryService); _serviceProvider.AddServiceFactory(typeof(ClrRuntime), () => CreateRuntime(target)); _serviceProvider.AddServiceFactory(typeof(SOSHost), () => { var sosHost = new SOSHost(_serviceProvider); sosHost.InitializeSOSHost(SymbolReader.TempDirectory, _isDesktop, _dacFilePath, dbiFilePath: null); return(sosHost); }); }
/// <summary> /// Add all the services needed by commands /// </summary> private void AddServices(DataTarget target) { _serviceProvider.AddService(target); _serviceProvider.AddService(target.DataReader); _serviceProvider.AddService <IConsoleService>(_consoleProvider); _serviceProvider.AddService(_commandProcessor); _serviceProvider.AddServiceFactory(typeof(IHelpBuilder), _commandProcessor.CreateHelpBuilder); if (!(target.DataReader is IThreadReader threadReader)) { throw new InvalidOperationException("IThreadReader not implemented"); } // Create common analyze context for commands var analyzeContext = new AnalyzeContext() { CurrentThreadId = threadReader.EnumerateOSThreadIds().FirstOrDefault() }; _serviceProvider.AddService(analyzeContext); // Add the thread, memory, SOSHost and ClrRuntime services var threadService = new ThreadService(target.DataReader); _serviceProvider.AddService <IThreadService>(threadService); var memoryService = new MemoryService(target.DataReader); _serviceProvider.AddService(memoryService); _serviceProvider.AddServiceFactory(typeof(ClrRuntime), () => CreateRuntime(target)); _serviceProvider.AddServiceFactory(typeof(SOSHost), () => { var sosHost = new SOSHost(_serviceProvider); sosHost.InitializeSOSHost(SymbolReader.TempDirectory, _isDesktop, _dacFilePath, dbiFilePath: null); return(sosHost); }); // ClrMD helper for extended commands _serviceProvider.AddServiceFactory(typeof(ClrMDHelper), () => new ClrMDHelper(_serviceProvider) ); }
public override Task InvokeAsync() { try { if (_sosHost == null) { _sosHost = new SOSHost(AnalyzeContext.Target.DataReader, AnalyzeContext); } string arguments = null; if (Arguments.Length > 0) { arguments = string.Concat(Arguments.Select((arg) => arg + " ")); } _sosHost.ExecuteCommand(AliasExpansion, arguments); } catch (Exception ex) when(ex is FileNotFoundException || ex is EntryPointNotFoundException || ex is InvalidOperationException) { Console.Error.WriteLine(ex.Message); } return(Task.CompletedTask); }
public Task <int> Analyze(FileInfo dump_path, string[] command) { _consoleProvider.WriteLine($"Loading core dump: {dump_path} ..."); try { using DataTarget dataTarget = DataTarget.LoadDump(dump_path.FullName); OSPlatform targetPlatform = dataTarget.DataReader.TargetPlatform; if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { targetPlatform = OSPlatform.OSX; } _target = new TargetFromDataReader(dataTarget.DataReader, targetPlatform, this, dump_path.FullName); _target.ServiceProvider.AddServiceFactory <SOSHost>(() => { var sosHost = new SOSHost(_target); sosHost.InitializeSOSHost(); return(sosHost); }); // Set the default symbol cache to match Visual Studio's when running on Windows if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { _symbolService.DefaultSymbolCache = Path.Combine(Path.GetTempPath(), "SymbolCache"); } // Automatically enable symbol server support _symbolService.AddSymbolServer(msdl: true, symweb: false, symbolServerPath: null, authToken: null, timeoutInMinutes: 0); _symbolService.AddCachePath(_symbolService.DefaultSymbolCache); // Run the commands from the dotnet-dump command line if (command != null) { foreach (string cmd in command) { Parse(cmd); if (_consoleProvider.Shutdown) { break; } } } if (!_consoleProvider.Shutdown) { // Start interactive command line processing _consoleProvider.WriteLine("Ready to process analysis commands. Type 'help' to list available commands or 'help [command]' to get detailed help on a command."); _consoleProvider.WriteLine("Type 'quit' or 'exit' to exit the session."); _consoleProvider.Start((string commandLine, CancellationToken cancellation) => { Parse(commandLine); }); } } catch (Exception ex) when (ex is ClrDiagnosticsException || ex is FileNotFoundException || ex is DirectoryNotFoundException || ex is UnauthorizedAccessException || ex is PlatformNotSupportedException || ex is InvalidDataException || ex is InvalidOperationException || ex is NotSupportedException) { _consoleProvider.WriteLine(OutputType.Error, $"{ex.Message}"); return(Task.FromResult(1)); } finally { if (_target != null) { _target.Close(); _target = null; } // Send shutdown event on exit OnShutdownEvent?.Invoke(this, new EventArgs()); } return(Task.FromResult(0)); }
public Task <int> Analyze(FileInfo dump_path, string[] command) { _consoleProvider.WriteLine($"Loading core dump: {dump_path} ..."); // Attempt to load the persisted command history string dotnetHome; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { dotnetHome = Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), ".dotnet"); } else { dotnetHome = Path.Combine(Environment.GetEnvironmentVariable("HOME"), ".dotnet"); } string historyFileName = Path.Combine(dotnetHome, "dotnet-dump.history"); try { string[] history = File.ReadAllLines(historyFileName); _consoleProvider.AddCommandHistory(history); } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException || ex is NotSupportedException || ex is SecurityException) { } try { using DataTarget dataTarget = DataTarget.LoadDump(dump_path.FullName); OSPlatform targetPlatform = dataTarget.DataReader.TargetPlatform; if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || dataTarget.DataReader.EnumerateModules().Any((module) => Path.GetExtension(module.FileName) == ".dylib")) { targetPlatform = OSPlatform.OSX; } _target = new TargetFromDataReader(dataTarget.DataReader, targetPlatform, this, dump_path.FullName); _target.ServiceProvider.AddServiceFactory <SOSHost>(() => { var sosHost = new SOSHost(_target); sosHost.InitializeSOSHost(); return(sosHost); }); // Automatically enable symbol server support _symbolService.AddSymbolServer(msdl: true, symweb: false, symbolServerPath: null, authToken: null, timeoutInMinutes: 0); _symbolService.AddCachePath(_symbolService.DefaultSymbolCache); // Run the commands from the dotnet-dump command line if (command != null) { foreach (string cmd in command) { Parse(cmd); if (_consoleProvider.Shutdown) { break; } } } if (!_consoleProvider.Shutdown && (!Console.IsOutputRedirected || Console.IsInputRedirected)) { // Start interactive command line processing _consoleProvider.WriteLine("Ready to process analysis commands. Type 'help' to list available commands or 'help [command]' to get detailed help on a command."); _consoleProvider.WriteLine("Type 'quit' or 'exit' to exit the session."); _consoleProvider.Start((string commandLine, CancellationToken cancellation) => { Parse(commandLine); }); } } catch (Exception ex) when (ex is ClrDiagnosticsException || ex is FileNotFoundException || ex is DirectoryNotFoundException || ex is UnauthorizedAccessException || ex is PlatformNotSupportedException || ex is InvalidDataException || ex is InvalidOperationException || ex is NotSupportedException) { _consoleProvider.WriteLine(OutputType.Error, $"{ex.Message}"); return(Task.FromResult(1)); } finally { if (_target != null) { _target.Close(); _target = null; } // Persist the current command history try { File.WriteAllLines(historyFileName, _consoleProvider.GetCommandHistory()); } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException || ex is NotSupportedException || ex is SecurityException) { } // Send shutdown event on exit OnShutdownEvent.Fire(); } return(Task.FromResult(0)); }
internal DbgEngController(string dbgengPath, string dumpPath, string sosPath) { Trace.TraceInformation($"DbgEngController: {dbgengPath} {dumpPath} {sosPath}"); _converter = new CharToLineConverter((text) => { Trace.TraceInformation(text); }); IntPtr dbgengLibrary = DataTarget.PlatformFunctions.LoadLibrary(dbgengPath); var debugCreate = SOSHost.GetDelegateFunction <DebugCreateDelegate>(dbgengLibrary, "DebugCreate"); if (debugCreate == null) { throw new DiagnosticsException($"DebugCreate export not found"); } Guid iid = _iidClient; HResult hr = debugCreate(ref iid, out object client); if (hr != HResult.S_OK) { throw new DiagnosticsException($"DebugCreate FAILED {hr:X8}"); } Client = (IDebugClient)client; Control = (IDebugControl)client; Symbols = (IDebugSymbols2)client; hr = Client.SetOutputCallbacks(this); if (hr != HResult.S_OK) { throw new DiagnosticsException($"SetOutputCallbacks FAILED {hr:X8}"); } // Automatically enable/adjust symbol server support. Override the default cache path so // the cache isn't created in the debugger binaries .nuget package cache directory. string cachePath = Path.Combine(Environment.GetEnvironmentVariable("PROGRAMDATA"), "dbg", "sym"); string sympath = $"{Path.GetDirectoryName(dumpPath)};cache*{cachePath};SRV*https://msdl.microsoft.com/download/symbols"; hr = Symbols.SetSymbolPath(sympath); if (hr != HResult.S_OK) { Trace.TraceError($"SetSymbolPath({sympath}) FAILED {hr:X8}"); } // Load dump file hr = Client.OpenDumpFile(dumpPath); if (hr != HResult.S_OK) { throw new DiagnosticsException($"OpenDumpFile({dumpPath} FAILED {hr:X8}"); } ProcessEvents(); // Load the sos extensions hr = Control.Execute(DEBUG_OUTCTL.ALL_CLIENTS, $".load {sosPath}", DEBUG_EXECUTE.DEFAULT); if (hr != HResult.S_OK) { throw new DiagnosticsException($"Loading {sosPath} FAILED {hr:X8}"); } // Initialize the extension host hr = HostServices.Initialize(sosPath); if (hr != HResult.S_OK) { throw new DiagnosticsException($"HostServices.Initialize({sosPath}) FAILED {hr:X8}"); } var symbolService = Host.Services.GetService <ISymbolService>(); Trace.TraceInformation($"SymbolService: {symbolService}"); }