Browse Source

Profiler:

- fixed memory leak
- removed ICSharpCode.SharpDevelop.Profiling namespace
- added filter for unit tests when selecting "Run with profiler"

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4863 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Siegfried Pammer 16 years ago
parent
commit
28804bf2ea
  1. 10
      src/AddIns/Misc/Profiler/AutomatedBuild.proj
  2. 2
      src/AddIns/Misc/Profiler/Controller/Controller.csproj
  3. 61
      src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteWriter.cs
  4. 95
      src/AddIns/Misc/Profiler/Controller/Data/UnitTestRootCallTreeNode.cs
  5. 6
      src/AddIns/Misc/Profiler/Frontend/AddIn/AddIn.csproj
  6. 19
      src/AddIns/Misc/Profiler/Frontend/AddIn/ICSharpCode.Profiler.AddIn.addin
  7. 9
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Commands/ProfileProject.cs
  8. 93
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Commands/RunTestWithProfilerCommand.cs
  9. 2
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Dialogs/ProfileExecutableForm.xaml.cs
  10. 51
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Extensions.cs
  11. 33
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/ProfilerRunner.cs
  12. 94
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/WindowsProfiler.cs
  13. 2
      src/AddIns/Misc/Profiler/Frontend/BenchmarkRunner/BenchmarkRunner.cs
  14. 2
      src/AddIns/Misc/Profiler/Frontend/Gui/Window1.xaml.cs
  15. 40
      src/AddIns/Misc/Profiler/Profiler.sln
  16. 42
      src/AddIns/Misc/UnitTesting/Src/RunTestCommands.cs
  17. 3
      src/AddIns/Misc/UnitTesting/UnitTesting.addin
  18. 4
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  19. 44
      src/Main/Base/Project/Src/Services/Profiler/DefaultProfiler.cs
  20. 21
      src/Main/Base/Project/Src/Services/Profiler/IProfiler.cs
  21. 87
      src/Main/Base/Project/Src/Services/Profiler/ProfilerService.cs

10
src/AddIns/Misc/Profiler/AutomatedBuild.proj

@ -1,13 +1,17 @@ @@ -1,13 +1,17 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<!-- workaround for Windows 7 x64 -->
<PropertyGroup>
<ProgramFiles32>$(MSBuildExtensionsPath32)\..</ProgramFiles32>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition="'$(Configuration)'==''">Release</Configuration>
<ProfilerProjectDir>$(MSBuildProjectDirectory)</ProfilerProjectDir>
<ProfilerHookDir>$(ProfilerProjectDir)\Hook</ProfilerHookDir>
<CppBatch32>$(PROGRAMFILES)\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat</CppBatch32>
<CppBatch64Native>$(PROGRAMFILES)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat</CppBatch64Native>
<CppBatch64Cross>$(PROGRAMFILES)\Microsoft Visual Studio 9.0\VC\bin\vcvarsx86_amd64.bat</CppBatch64Cross>
<CppBatch32>$(ProgramFiles32)\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat</CppBatch32>
<CppBatch64Native>$(ProgramFiles32)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat</CppBatch64Native>
<CppBatch64Cross>$(ProgramFiles32)\Microsoft Visual Studio 9.0\VC\bin\vcvarsx86_amd64.bat</CppBatch64Cross>
<CppBatch64 Condition="Exists('$(CppBatch64Native)')">$(CppBatch64Native)</CppBatch64>
<CppBatch64 Condition="'$(CppBatch64)'==''">$(CppBatch64Cross)</CppBatch64>
<VcBuildArguments>/showenv "$(ProfilerHookDir)\Hook.vcproj" $(Configuration)</VcBuildArguments>

2
src/AddIns/Misc/Profiler/Controller/Controller.csproj

@ -77,12 +77,12 @@ @@ -77,12 +77,12 @@
</Compile>
<Compile Include="Data\SQLiteCallTreeNode.cs" />
<Compile Include="Data\TempFileDatabase.cs" />
<Compile Include="Data\UnitTestRootCallTreeNode.cs" />
<Compile Include="Data\UnmanagedCallTreeNode.cs" />
<Compile Include="Data\UnmanagedCallTreeNode64.cs">
<DependentUpon>UnmanagedCallTreeNode.cs</DependentUpon>
</Compile>
<Compile Include="Data\UnmanagedProfilingDataSet.cs">
<DependentUpon>ProfilingDataSQLiteWriter.cs</DependentUpon>
</Compile>
<Compile Include="ExtendedRegistry.cs" />
<Compile Include="ExtensionMethods.cs" />

61
src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteWriter.cs

@ -30,11 +30,13 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -30,11 +30,13 @@ namespace ICSharpCode.Profiler.Controller.Data
int functionInfoCount;
bool isDisposed;
int processorFrequency;
bool profileUnitTests;
string[] unitTestNames;
/// <summary>
/// Creates a new SQLite profiling data provider and opens or creates a new database stored in a file.
/// </summary>
public ProfilingDataSQLiteWriter(string fileName)
public ProfilingDataSQLiteWriter(string fileName, bool profileUnitTests, string[] unitTestNames)
{
if (File.Exists(fileName))
throw new IOException("File already exists!");
@ -54,6 +56,12 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -54,6 +56,12 @@ namespace ICSharpCode.Profiler.Controller.Data
InitializeTables();
File.SetAttributes(fileName, FileAttributes.Compressed);
this.profileUnitTests = profileUnitTests;
this.unitTestNames = unitTestNames;
if (profileUnitTests && unitTestNames == null)
throw new InvalidOperationException("Please add unit tests to filter!");
}
/// <summary>
@ -103,8 +111,6 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -103,8 +111,6 @@ namespace ICSharpCode.Profiler.Controller.Data
cmd.CommandText = "INSERT INTO DataSets(id, cpuusage, rootid)" +
"VALUES(?,?,?);";
cmd.ExecuteNonQuery();
using (SQLiteCommand loopCommand = this.connection.CreateCommand()) {
CallTreeNode node = dataSet.RootNode;
@ -121,14 +127,54 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -121,14 +127,54 @@ namespace ICSharpCode.Profiler.Controller.Data
loopCommand.Parameters.Add(dataParams.isActiveAtStart = new SQLiteParameter());
loopCommand.Parameters.Add(dataParams.callCount = new SQLiteParameter());
InsertTree(loopCommand, node, -1, dataSet, dataParams);
dataSetCount++;
bool addedData = true;
if (profileUnitTests)
addedData = FindUnitTestsAndInsert(loopCommand, node, dataSet, dataParams);
else
InsertTree(loopCommand, node, -1, dataSet, dataParams);
if (addedData) {
cmd.ExecuteNonQuery();
dataSetCount++;
}
}
transaction.Commit();
}
}
bool IsUnitTest(NameMapping name)
{
return unitTestNames.Contains(name.Name);
}
bool FindUnitTestsAndInsert(SQLiteCommand cmd, CallTreeNode node, IProfilingDataSet dataSet, FunctionDataParams dataParams)
{
List<CallTreeNode> list = new List<CallTreeNode>();
FindUnitTests(node, list);
if (list.Count > 0) {
InsertTree(cmd, new UnitTestRootCallTreeNode(list), -1, dataSet, dataParams);
return true;
}
return false;
}
void FindUnitTests(CallTreeNode parentNode, IList<CallTreeNode> list)
{
if (IsUnitTest(parentNode.NameMapping)) {
list.Add(parentNode);
return;
}
foreach (var node in parentNode.Children) {
FindUnitTests(node, list);
}
}
void InitializeTables()
{
//NameMapping { Id, ReturnType, Name, Parameters }
@ -194,9 +240,10 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -194,9 +240,10 @@ namespace ICSharpCode.Profiler.Controller.Data
parentId, nameId, cpuCyclesSpent, isActiveAtStart, callCount, endId;
}
unsafe void InsertTree(SQLiteCommand cmd, CallTreeNode node, int parentId, IProfilingDataSet dataSet, FunctionDataParams dataParams)
void InsertTree(SQLiteCommand cmd, CallTreeNode node, int parentId, IProfilingDataSet dataSet, FunctionDataParams dataParams)
{
int thisID = functionInfoCount++;
foreach (CallTreeNode child in node.Children) {
InsertTree(cmd, child, thisID, dataSet, dataParams);
}
@ -259,4 +306,4 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -259,4 +306,4 @@ namespace ICSharpCode.Profiler.Controller.Data
isDisposed = true;
}
}
}
}

95
src/AddIns/Misc/Profiler/Controller/Data/UnitTestRootCallTreeNode.cs

@ -0,0 +1,95 @@ @@ -0,0 +1,95 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Linq;
namespace ICSharpCode.Profiler.Controller.Data
{
/// <summary>
/// Wraps multiple CallTreeNodes that represent unit test methods for proper display in the listview.
/// </summary>
public class UnitTestRootCallTreeNode : CallTreeNode
{
List<CallTreeNode> unitTests;
/// <summary>
/// Creates a new UnitTestRootCallTreeNode.
/// </summary>
public UnitTestRootCallTreeNode(IEnumerable<CallTreeNode> unitTests)
{
this.unitTests = new List<CallTreeNode>(unitTests);
}
/// <summary>
/// Gets a reference to the name, return type and parameter list of the method.
/// </summary>
public override NameMapping NameMapping {
get {
return new NameMapping(0, null, "Merged node", null);
}
}
public override long CpuCyclesSpent {
get {
return 0;
}
}
public override bool IsActiveAtStart {
get {
return this.unitTests.Any(test => test.IsActiveAtStart);
}
}
public override double TimeSpent {
get {
return 0;
}
}
public override int RawCallCount {
get {
return 0;
}
}
public override CallTreeNode Parent {
get {
return null;
}
}
public override CallTreeNode Merge(System.Collections.Generic.IEnumerable<CallTreeNode> nodes)
{
// throw new ShouldNeverHappenException();
throw new NotSupportedException("Cannot merge a UnitTestRootCallTreeNode (should never be possible)");
}
public override int GetHashCode()
{
return this.unitTests.Aggregate(0, (sum, item) => sum ^= item.GetHashCode());
}
public override bool Equals(CallTreeNode other)
{
return (other is UnitTestRootCallTreeNode) && (other as UnitTestRootCallTreeNode).unitTests.SequenceEqual(unitTests);
}
public override IQueryable<CallTreeNode> Callers {
get {
return Enumerable.Empty<CallTreeNode>().AsQueryable();
}
}
public override IQueryable<CallTreeNode> Children {
get {
return unitTests.AsQueryable();
}
}
}
}

6
src/AddIns/Misc/Profiler/Frontend/AddIn/AddIn.csproj

@ -78,6 +78,9 @@ @@ -78,6 +78,9 @@
<Reference Include="UIAutomationProvider">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="UnitTesting">
<HintPath>..\..\..\..\..\..\AddIns\AddIns\Misc\UnitTesting\UnitTesting.dll</HintPath>
</Reference>
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
@ -95,11 +98,13 @@ @@ -95,11 +98,13 @@
<Compile Include="Src\Commands\ProfileExecutable.cs" />
<Compile Include="Src\Commands\ProfileProject.cs" />
<Compile Include="Src\Commands\ProfilerMenuCommand.cs" />
<Compile Include="Src\Commands\RunTestWithProfilerCommand.cs" />
<Compile Include="Src\Commands\SetAsRoot.cs" />
<Compile Include="Src\Commands\ShowFunctions.cs" />
<Compile Include="Src\Dialogs\ProfileExecutableForm.xaml.cs">
<DependentUpon>ProfileExecutableForm.xaml</DependentUpon>
</Compile>
<Compile Include="Src\Extensions.cs" />
<Compile Include="Src\OptionsPanels\General.cs">
<SubType>UserControl</SubType>
</Compile>
@ -115,7 +120,6 @@ @@ -115,7 +120,6 @@
</Compile>
<Compile Include="Src\Views\SharpDevelopElementHost.cs" />
<Compile Include="Src\Views\WpfViewer.cs" />
<Compile Include="Src\WindowsProfiler.cs" />
</ItemGroup>
<ItemGroup>
<Page Include="Src\Dialogs\ProfileExecutableForm.xaml">

19
src/AddIns/Misc/Profiler/Frontend/AddIn/ICSharpCode.Profiler.AddIn.addin

@ -8,6 +8,11 @@ @@ -8,6 +8,11 @@
<Import assembly="ICSharpCode.Profiler.AddIn.dll" />
</Runtime>
<Manifest>
<Identity name="Profiler.AddIn" />
<Dependency addin="ICSharpCode.UnitTesting" requirePreload="true" />
</Manifest>
<Path name="/SharpDevelop/Workbench/MainMenu/Analysis">
<MenuItem id="Profiler" label="Profiler" type="Menu" insertbefore="Separator1">
<ComplexCondition action="Disable">
@ -81,7 +86,17 @@ @@ -81,7 +86,17 @@
</DialogPanel>
</Path>
<Path name="/SharpDevelop/Services/ProfilerService/Profiler">
<Class id = "WindowsProfiler" class="ICSharpCode.Profiler.AddIn.WindowsProfiler" />
<Path name = "/SharpDevelop/Pads/UnitTestsPad/CommonTestCommands">
<ComplexCondition action="Disable">
<And>
<Condition name="SolutionOpen"/>
<Not>
<Condition name="RunningTests"/>
</Not>
</And>
<MenuItem id = "RunWithProfiler"
label = "Run with profiler"
class = "ICSharpCode.Profiler.AddIn.Commands.RunTestWithProfilerCommand"/>
</ComplexCondition>
</Path>
</AddIn>

9
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Commands/ProfileProject.cs

@ -8,7 +8,6 @@ @@ -8,7 +8,6 @@
using System;
using System.IO;
using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop.Profiling;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.Profiler.AddIn.Commands
@ -26,14 +25,14 @@ namespace ICSharpCode.Profiler.AddIn.Commands @@ -26,14 +25,14 @@ namespace ICSharpCode.Profiler.AddIn.Commands
public override void Run()
{
IProject currentProj = ProjectService.CurrentProject;
string path = ProfilerService.GetSessionFileName(currentProj);
string path = currentProj.GetSessionFileName();
Directory.CreateDirectory(Path.GetDirectoryName(path));
IProfilingDataWriter writer = new ProfilingDataSQLiteWriter(path);
ProfilerRunner runner = WindowsProfiler.CreateRunner(writer);
IProfilingDataWriter writer = new ProfilingDataSQLiteWriter(path, false, null);
ProfilerRunner runner = ProfilerRunner.CreateRunner(writer);
if (runner != null) {
runner.RunFinished += delegate { ProfilerService.AddSessionToProject(currentProj, path); };
runner.RunFinished += delegate { currentProj.AddSessionToProject(path); };
runner.Run();
}
}

93
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Commands/RunTestWithProfilerCommand.cs

@ -0,0 +1,93 @@ @@ -0,0 +1,93 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.SharpDevelop.Gui;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.Profiler.AddIn;
using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.UnitTesting;
namespace ICSharpCode.Profiler.AddIn.Commands
{
public class RunTestWithProfilerCommand : AbstractRunTestCommand
{
protected override void RunTests(UnitTestApplicationStartHelper helper)
{
TestRunnerCategory.AppendLine(helper.GetCommandLine());
ProcessStartInfo startInfo = new ProcessStartInfo(helper.UnitTestApplication);
string path = helper.Project.GetSessionFileName();
startInfo.Arguments = helper.GetArguments();
startInfo.WorkingDirectory = UnitTestApplicationStartHelper.UnitTestApplicationDirectory;
LoggingService.Info("starting profiler...");
ProfilerRunner runner = new ProfilerRunner(startInfo, true, new ProfilingDataSQLiteWriter(path, true, GetUnitTestNames(helper).ToArray()));
runner.RunFinished += delegate {
WorkbenchSingleton.SafeThreadCall(() => FileService.OpenFile(path));
AfterFinish(helper, path);
};
runner.Run();
}
IEnumerable<string> GetUnitTestNames(UnitTestApplicationStartHelper helper)
{
IProjectContent content = ParserService.GetProjectContent(helper.Project);
if (helper.Fixture == null) {
var testClasses = content.Classes
.Where(c => c.Attributes.Any(a => a.AttributeType.FullyQualifiedName == "NUnit.Framework.TestFixtureAttribute"));
return testClasses
.SelectMany(c2 => c2.Methods)
.Where(m => m.Attributes.Any(a2 => a2.AttributeType.FullyQualifiedName == "NUnit.Framework.TestAttribute"))
.Select(m2 => m2.FullyQualifiedName);
}
if (helper.Test == null) {
return content.Classes
.Where(c => c.FullyQualifiedName == helper.Fixture).First().Methods
.Where(m => m.Attributes.Any(a2 => a2.AttributeType.FullyQualifiedName == "NUnit.Framework.TestAttribute"))
.Select(m2 => m2.FullyQualifiedName);
}
return new[] { helper.Fixture + "." + helper.Test };
}
void AfterFinish(UnitTestApplicationStartHelper helper, string path)
{
helper.Project.AddSessionToProject(path);
WorkbenchSingleton.SafeThreadAsyncCall(TestsFinished);
LoggingService.Info("shutting profiler down...");
}
public override void Run()
{
// if (ProfilerService.IsProfilerLoaded && ProfilerService.CurrentProfiler.IsRunning) {
// MessageService.ShowError("Currently there is a profiling session in progress. " +
// "Please finish the current session before starting a new one.");
// } else {
base.Run();
// }
}
protected override void OnStop()
{
// if (ProfilerService.CurrentProfiler.IsRunning) {
// LoggingService.Info("stopping profiler...");
// ProfilerService.CurrentProfiler.Stop();
// }
}
}
}

2
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Dialogs/ProfileExecutableForm.xaml.cs

@ -45,7 +45,7 @@ namespace ICSharpCode.Profiler.AddIn.Dialogs @@ -45,7 +45,7 @@ namespace ICSharpCode.Profiler.AddIn.Dialogs
try {
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
var runner = CreateRunner(txtExePath.Text, txtWorkingDir.Text, txtArgs.Text, new ProfilingDataSQLiteWriter(outputPath));
var runner = CreateRunner(txtExePath.Text, txtWorkingDir.Text, txtArgs.Text, new ProfilingDataSQLiteWriter(outputPath, false, null));
if (runner != null) {
runner.RunFinished += delegate {

51
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Extensions.cs

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.SharpDevelop.Gui;
using System;
using System.Globalization;
using System.IO;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.Profiler.AddIn
{
/// <summary>
/// Description of Extensions.
/// </summary>
public static class Extensions
{
public static string GetSessionFileName(this IProject project)
{
string filename = @"ProfilingSessions\Session" +
DateTime.Now.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture) +
".sdps";
string path = Path.Combine(project.Directory, filename);
Directory.CreateDirectory(Path.GetDirectoryName(path));
return path;
}
public static void AddSessionToProject(this IProject project, string path)
{
Action updater = () => {
if (!File.Exists(path))
return;
FileService.OpenFile(path);
if (!project.ReadOnly) {
FileProjectItem file = new FileProjectItem(project, ItemType.Content, "ProfilingSessions\\" + Path.GetFileName(path));
ProjectService.AddProjectItem(project, file);
ProjectBrowserPad.Instance.ProjectBrowserControl.RefreshView();
project.Save();
}
};
WorkbenchSingleton.SafeThreadCall(updater);
}
}
}

33
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/ProfilerRunner.cs

@ -11,7 +11,8 @@ using ICSharpCode.Core; @@ -11,7 +11,8 @@ using ICSharpCode.Core;
using ICSharpCode.Profiler.AddIn.OptionsPanels;
using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Profiling;
using ICSharpCode.SharpDevelop.Project;
using System.IO;
namespace ICSharpCode.Profiler.AddIn
{
@ -76,8 +77,9 @@ namespace ICSharpCode.Profiler.AddIn @@ -76,8 +77,9 @@ namespace ICSharpCode.Profiler.AddIn
}
void FinishSession()
{
{
using (AsynchronousWaitDialog dlg = AsynchronousWaitDialog.ShowWaitDialog("Preparing for analysis", true)) {
profiler.Dispose();
if (database != null) {
database.WriteTo(writer, progress => !dlg.IsCancelled);
writer.Close();
@ -102,6 +104,33 @@ namespace ICSharpCode.Profiler.AddIn @@ -102,6 +104,33 @@ namespace ICSharpCode.Profiler.AddIn
profiler.Stop();
}
public static ProfilerRunner CreateRunner(IProfilingDataWriter writer)
{
AbstractProject currentProj = ProjectService.CurrentProject as AbstractProject;
if (currentProj == null)
return null;
if (!currentProj.IsStartable) {
if (MessageService.AskQuestion("This project cannot be started. Do you want to profile the solution's StartUp project instead?")) {
currentProj = ProjectService.OpenSolution.StartupProject as AbstractProject;
if (currentProj == null) {
MessageService.ShowError("No startable project was found. Aborting ...");
return null;
}
} else
return null;
}
if (!File.Exists(currentProj.OutputAssemblyFullPath)) {
MessageService.ShowError("This project cannot be started because the executable file was not found, " +
"please ensure that the project and all its depencies are built correctly!");
return null;
}
ProfilerRunner runner = new ProfilerRunner(currentProj.CreateStartInfo(), true, writer);
return runner;
}
#region MessageView Management
static MessageViewCategory profileCategory = null;

94
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/WindowsProfiler.cs

@ -1,94 +0,0 @@ @@ -1,94 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Diagnostics;
using ICSharpCode.Core;
using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop.Profiling;
using ICSharpCode.SharpDevelop.Project;
using System.IO;
namespace ICSharpCode.Profiler.AddIn
{
/// <summary>
/// Description of WindowsProfiler.
/// </summary>
public class WindowsProfiler : IProfiler
{
ProfilerRunner runner;
bool isRunning = false;
public WindowsProfiler()
{
}
public bool CanProfile(IProject project)
{
return project != null && project.IsStartable;
}
public void Start(ProcessStartInfo info, string outputPath, Action afterFinishAction)
{
this.runner = new ProfilerRunner(info, true, new ProfilingDataSQLiteWriter(outputPath));
if (runner != null) {
runner.RunFinished += delegate {
try {
afterFinishAction();
} finally {
this.isRunning = false;
}
};
this.isRunning = true;
runner.Run();
}
}
public static ProfilerRunner CreateRunner(IProfilingDataWriter writer)
{
AbstractProject currentProj = ProjectService.CurrentProject as AbstractProject;
if (currentProj == null)
return null;
if (!currentProj.IsStartable) {
if (MessageService.AskQuestion("This project cannot be started. Do you want to profile the solution's StartUp project instead?")) {
currentProj = ProjectService.OpenSolution.StartupProject as AbstractProject;
if (currentProj == null) {
MessageService.ShowError("No startable project was found. Aborting ...");
return null;
}
} else
return null;
}
if (!File.Exists(currentProj.OutputAssemblyFullPath)) {
MessageService.ShowError("This project cannot be started because the executable file was not found, " +
"please ensure that the project and all its depencies are built correctly!");
return null;
}
ProfilerRunner runner = new ProfilerRunner(currentProj.CreateStartInfo(), true, writer);
return runner;
}
public void Dispose()
{
}
public bool IsRunning {
get {
return this.isRunning;
}
}
public void Stop()
{
this.runner.Stop();
}
}
}

2
src/AddIns/Misc/Profiler/Frontend/BenchmarkRunner/BenchmarkRunner.cs

@ -85,7 +85,7 @@ namespace BenchmarkRunner @@ -85,7 +85,7 @@ namespace BenchmarkRunner
File.Delete(fileName);
using (var profiler = new Profiler(
startInfo, new ProfilingDataSQLiteWriter(fileName), new ProfilerOptions()
startInfo, new ProfilingDataSQLiteWriter(fileName, false, null), new ProfilerOptions()
)) {
using (ManualResetEvent mre = new ManualResetEvent(false)) {
profiler.SessionEnded += delegate {

2
src/AddIns/Misc/Profiler/Frontend/Gui/Window1.xaml.cs

@ -88,7 +88,7 @@ namespace ICSharpCode.Profiler.Frontend @@ -88,7 +88,7 @@ namespace ICSharpCode.Profiler.Frontend
void profiler_SessionEnded(object sender, EventArgs e)
{
string pathToDb = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(typeof(Profiler.Controller.Profiler).Assembly.Location), "output.sdps");
ProfilingDataSQLiteWriter writer = new ProfilingDataSQLiteWriter(pathToDb);
ProfilingDataSQLiteWriter writer = new ProfilingDataSQLiteWriter(pathToDb, false, null);
this.database.WriteTo(writer, progress => true);
writer.Close();
this.database.Close();

40
src/AddIns/Misc/Profiler/Profiler.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
# SharpDevelop 3.1.0.4082
# SharpDevelop 4.0.0.4856
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5147BA25-8362-481D-8CF9-450096595B7A}"
ProjectSection(SolutionItems) = preProject
TODO.txt = TODO.txt
@ -62,6 +62,8 @@ Global @@ -62,6 +62,8 @@ Global
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FF09FBA1-86DA-4D8D-B549-A4FC70FC5AE9}.Debug|Win32.ActiveCfg = Debug|Any CPU
@ -168,6 +170,42 @@ Global @@ -168,6 +170,42 @@ Global
{D336926C-6180-4F62-B88D-E366B240127B}.Release|Win32.ActiveCfg = Release|Win32
{D336926C-6180-4F62-B88D-E366B240127B}.Release|x64.Build.0 = Release|x64
{D336926C-6180-4F62-B88D-E366B240127B}.Release|x64.ActiveCfg = Release|x64
{FE88FE17-D9FB-4FCC-9A35-6BFFB6B26CC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE88FE17-D9FB-4FCC-9A35-6BFFB6B26CC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE88FE17-D9FB-4FCC-9A35-6BFFB6B26CC6}.Release|Any CPU.Build.0 = Release|Any CPU
{FE88FE17-D9FB-4FCC-9A35-6BFFB6B26CC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2EACD124-3D84-4F4D-8C82-D3E396A5DA21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2EACD124-3D84-4F4D-8C82-D3E396A5DA21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2EACD124-3D84-4F4D-8C82-D3E396A5DA21}.Release|Any CPU.Build.0 = Release|Any CPU
{2EACD124-3D84-4F4D-8C82-D3E396A5DA21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72FFB35A-C9E2-4A31-B4FA-E3E3E28DED5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72FFB35A-C9E2-4A31-B4FA-E3E3E28DED5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72FFB35A-C9E2-4A31-B4FA-E3E3E28DED5F}.Release|Any CPU.Build.0 = Release|Any CPU
{72FFB35A-C9E2-4A31-B4FA-E3E3E28DED5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{68D5EE3B-0C35-4DF1-BD29-6606851A02C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68D5EE3B-0C35-4DF1-BD29-6606851A02C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{68D5EE3B-0C35-4DF1-BD29-6606851A02C1}.Release|Any CPU.Build.0 = Release|Any CPU
{68D5EE3B-0C35-4DF1-BD29-6606851A02C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{650AEAA0-0678-4A75-A1CC-F46DC4E44D2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{650AEAA0-0678-4A75-A1CC-F46DC4E44D2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{650AEAA0-0678-4A75-A1CC-F46DC4E44D2A}.Release|Any CPU.Build.0 = Release|Any CPU
{650AEAA0-0678-4A75-A1CC-F46DC4E44D2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF09FBA1-86DA-4D8D-B549-A4FC70FC5AE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF09FBA1-86DA-4D8D-B549-A4FC70FC5AE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF09FBA1-86DA-4D8D-B549-A4FC70FC5AE9}.Release|Any CPU.Build.0 = Release|Any CPU
{FF09FBA1-86DA-4D8D-B549-A4FC70FC5AE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DBEF953E-F7BC-4D54-8A27-B758EC875C49}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DBEF953E-F7BC-4D54-8A27-B758EC875C49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DBEF953E-F7BC-4D54-8A27-B758EC875C49}.Release|Any CPU.Build.0 = Release|Any CPU
{DBEF953E-F7BC-4D54-8A27-B758EC875C49}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D294A12D-4B38-4F25-9AA6-3D4A6CE26E7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D294A12D-4B38-4F25-9AA6-3D4A6CE26E7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D294A12D-4B38-4F25-9AA6-3D4A6CE26E7B}.Release|Any CPU.Build.0 = Release|Any CPU
{D294A12D-4B38-4F25-9AA6-3D4A6CE26E7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BDA49550-5ED1-4C6B-B648-657B2CACD8E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BDA49550-5ED1-4C6B-B648-657B2CACD8E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BDA49550-5ED1-4C6B-B648-657B2CACD8E0}.Release|Any CPU.Build.0 = Release|Any CPU
{BDA49550-5ED1-4C6B-B648-657B2CACD8E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

42
src/AddIns/Misc/UnitTesting/Src/RunTestCommands.cs

@ -16,7 +16,6 @@ using ICSharpCode.SharpDevelop.Commands; @@ -16,7 +16,6 @@ using ICSharpCode.SharpDevelop.Commands;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Profiling;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Project.Commands;
using ICSharpCode.SharpDevelop.Util;
@ -520,48 +519,7 @@ namespace ICSharpCode.UnitTesting @@ -520,48 +519,7 @@ namespace ICSharpCode.UnitTesting
WorkbenchSingleton.SafeThreadAsyncCall(TestsFinished);
}
}
public class RunTestWithProfilerCommand : AbstractRunTestCommand
{
protected override void RunTests(UnitTestApplicationStartHelper helper)
{
TestRunnerCategory.AppendLine(helper.GetCommandLine());
ProcessStartInfo startInfo = new ProcessStartInfo(helper.UnitTestApplication);
string path = ProfilerService.GetSessionFileName(helper.Project);
startInfo.Arguments = helper.GetArguments();
startInfo.WorkingDirectory = UnitTestApplicationStartHelper.UnitTestApplicationDirectory;
LoggingService.Info("starting profiler...");
ProfilerService.CurrentProfiler.Start(startInfo, path, delegate { AfterFinish(helper, path); });
}
void AfterFinish(UnitTestApplicationStartHelper helper, string path)
{
ProfilerService.AddSessionToProject(helper.Project, path);
WorkbenchSingleton.SafeThreadAsyncCall(TestsFinished);
LoggingService.Info("shutting profiler down...");
}
public override void Run()
{
if (ProfilerService.IsProfilerLoaded && ProfilerService.CurrentProfiler.IsRunning) {
MessageService.ShowError("Currently there is a profiling session in progress. " +
"Please finish the current session before starting a new one.");
} else {
base.Run();
}
}
protected override void OnStop()
{
if (ProfilerService.CurrentProfiler.IsRunning) {
LoggingService.Info("stopping profiler...");
ProfilerService.CurrentProfiler.Stop();
}
}
}
public class RunAllTestsInPadCommand : RunTestInPadCommand
{
public override void Run()

3
src/AddIns/Misc/UnitTesting/UnitTesting.addin

@ -85,9 +85,6 @@ @@ -85,9 +85,6 @@
label = "${res:ICSharpCode.UnitTesting.RunWithDebugger}"
icon = "Icons.16x16.RunProgramIcon"
class = "ICSharpCode.UnitTesting.RunTestWithDebuggerCommand"/>
<MenuItem id = "RunWithProfiler"
label = "Run with profiler"
class = "ICSharpCode.UnitTesting.RunTestWithProfilerCommand"/>
</ComplexCondition>
</Path>

4
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -147,9 +147,6 @@ @@ -147,9 +147,6 @@
<Compile Include="Src\Internal\Doozers\IDialogPanelDescriptor.cs" />
<Compile Include="Src\Services\File\FileService.cs" />
<Compile Include="Src\Services\File\FileEventArgs.cs" />
<Compile Include="Src\Services\Profiler\DefaultProfiler.cs" />
<Compile Include="Src\Services\Profiler\IProfiler.cs" />
<Compile Include="Src\Services\Profiler\ProfilerService.cs" />
<Compile Include="Src\Services\ProjectService\CompileModifiedProjectsOnly.cs" />
<Compile Include="Src\Services\RefactoringService\ExtractInterfaceOptions.cs" />
<Compile Include="Src\Services\Tasks\Task.cs" />
@ -763,7 +760,6 @@ @@ -763,7 +760,6 @@
<Content Include="..\..\..\..\AddIns\ICSharpCode.SharpDevelop.addin">
<Link>ICSharpCode.SharpDevelop.addin</Link>
</Content>
<Folder Include="Src\Services\Profiler" />
<Folder Include="Src\Util" />
<Folder Include="Src\Gui\Pads\ClassBrowser\NodeBuilder" />
<Folder Include="Src\Services\NavigationService" />

44
src/Main/Base/Project/Src/Services/Profiler/DefaultProfiler.cs

@ -1,44 +0,0 @@ @@ -1,44 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.Core;
using System;
using System.Diagnostics;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop.Profiling
{
public class DefaultProfiler : IProfiler
{
public bool CanProfile(ICSharpCode.SharpDevelop.Project.IProject project)
{
return true;
}
public void Start(ProcessStartInfo info, string outputPath, Action afterFinishedAction)
{
MessageService.ShowError("Profiling not supported! " +
"No appropriate Profiler AddIn was found.");
afterFinishedAction();
}
public void Dispose()
{
Stop();
}
public bool IsRunning {
get {
return false;
}
}
public void Stop()
{
}
}
}

21
src/Main/Base/Project/Src/Services/Profiler/IProfiler.cs

@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.SharpDevelop.Project;
using System;
using System.Diagnostics;
namespace ICSharpCode.SharpDevelop.Profiling
{
public interface IProfiler : IDisposable
{
bool CanProfile(IProject project);
void Start(ProcessStartInfo info, string outputPath, Action afterFinishedAction);
void Stop();
bool IsRunning { get; }
}
}

87
src/Main/Base/Project/Src/Services/Profiler/ProfilerService.cs

@ -1,87 +0,0 @@ @@ -1,87 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Globalization;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Profiling
{
public static class ProfilerService
{
static IProfiler currentProfiler;
static IProfiler[] profilers;
static ProfilerService()
{
profilers = AddInTree.BuildItems<IProfiler>("/SharpDevelop/Services/ProfilerService/Profiler", null, false).ToArray();
}
public static bool IsProfilerLoaded
{
get {
return currentProfiler != null;
}
}
static IProfiler GetCompatibleProfiler()
{
IProject project = null;
if (ProjectService.OpenSolution != null)
project = ProjectService.OpenSolution.StartupProject;
foreach (var p in profilers) {
if (p != null && p.CanProfile(project))
return p;
}
return new DefaultProfiler();
}
public static IProfiler CurrentProfiler {
get {
if (currentProfiler == null) {
currentProfiler = GetCompatibleProfiler();
}
return currentProfiler;
}
}
public static string GetSessionFileName(IProject project)
{
string filename = @"ProfilingSessions\Session" +
DateTime.Now.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture) +
".sdps";
string path = Path.Combine(project.Directory, filename);
Directory.CreateDirectory(Path.GetDirectoryName(path));
return path;
}
public static void AddSessionToProject(IProject project, string path)
{
Action updater = () => {
if (!File.Exists(path))
return;
FileService.OpenFile(path);
if (!project.ReadOnly) {
FileProjectItem file = new FileProjectItem(project, ItemType.Content, "ProfilingSessions\\" + Path.GetFileName(path));
ProjectService.AddProjectItem(project, file);
ProjectBrowserPad.Instance.ProjectBrowserControl.RefreshView();
project.Save();
}
};
WorkbenchSingleton.SafeThreadCall(updater);
}
}
}
Loading…
Cancel
Save