code gardening
This commit is contained in:
Родитель
319d23d415
Коммит
e2b4e126c1
|
@ -79,10 +79,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeEditor.Debugger.Backend
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeEditor.Debugger.Backend.Sdb", "src\CodeEditor.Debugger.Backend.Sdb\CodeEditor.Debugger.Backend.Sdb.csproj", "{796B13D9-48B9-4EBA-B274-BBF297AFBD66}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeEditor.Debugger.IntegrationTests", "src\CodeEditor.Debugger.IntegrationTests\CodeEditor.Debugger.IntegrationTests.csproj", "{E169204B-D59F-4CDA-A0A9-CBCEF7F538B3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Debugger.Soft", "external\Mono.Debugger.Soft\Mono.Debugger.Soft.csproj", "{F2D07F82-9C51-4889-8987-4CEF47490751}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -300,18 +296,6 @@ Global
|
|||
{796B13D9-48B9-4EBA-B274-BBF297AFBD66}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{796B13D9-48B9-4EBA-B274-BBF297AFBD66}.Testing|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{796B13D9-48B9-4EBA-B274-BBF297AFBD66}.Testing|Any CPU.Build.0 = Release|Any CPU
|
||||
{E169204B-D59F-4CDA-A0A9-CBCEF7F538B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E169204B-D59F-4CDA-A0A9-CBCEF7F538B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E169204B-D59F-4CDA-A0A9-CBCEF7F538B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E169204B-D59F-4CDA-A0A9-CBCEF7F538B3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E169204B-D59F-4CDA-A0A9-CBCEF7F538B3}.Testing|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E169204B-D59F-4CDA-A0A9-CBCEF7F538B3}.Testing|Any CPU.Build.0 = Release|Any CPU
|
||||
{F2D07F82-9C51-4889-8987-4CEF47490751}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F2D07F82-9C51-4889-8987-4CEF47490751}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F2D07F82-9C51-4889-8987-4CEF47490751}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F2D07F82-9C51-4889-8987-4CEF47490751}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F2D07F82-9C51-4889-8987-4CEF47490751}.Testing|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F2D07F82-9C51-4889-8987-4CEF47490751}.Testing|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -330,8 +314,6 @@ Global
|
|||
{05848CF0-F1ED-4806-8A06-62B7AD048BE7} = {950B8E62-DD5C-4084-B4C2-42B3BAEBC001}
|
||||
{3C524BBD-42F2-4BF2-A96A-329A8C76F7F9} = {950B8E62-DD5C-4084-B4C2-42B3BAEBC001}
|
||||
{796B13D9-48B9-4EBA-B274-BBF297AFBD66} = {950B8E62-DD5C-4084-B4C2-42B3BAEBC001}
|
||||
{E169204B-D59F-4CDA-A0A9-CBCEF7F538B3} = {950B8E62-DD5C-4084-B4C2-42B3BAEBC001}
|
||||
{F2D07F82-9C51-4889-8987-4CEF47490751} = {950B8E62-DD5C-4084-B4C2-42B3BAEBC001}
|
||||
{9DB8BFD3-06C8-4A8C-8842-5931B924B56C} = {228395CA-7F86-451E-B8B7-8415EEB77AD7}
|
||||
{2ED73522-E34D-4CAB-8A42-6421FB9B1E77} = {228395CA-7F86-451E-B8B7-8415EEB77AD7}
|
||||
{489773FF-92B1-40B0-98EF-3ED337E5448F} = {228395CA-7F86-451E-B8B7-8415EEB77AD7}
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{F2D07F82-9C51-4889-8987-4CEF47490751}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Mono.Debugger.Soft</RootNamespace>
|
||||
<AssemblyName>Mono.Debugger.Soft</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;MONO_DATACONVERTER_STATIC_METHODS</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Cecil">
|
||||
<HintPath>..\..\..\..\External\Mono\builds\monodistribution\lib\mono\2.0\Mono.Cecil.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Mono.Debugger.Soft\AbsentInformationException.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\AppDomainCreateEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\AppDomainMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\AppDomainUnloadEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ArrayMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\AssemblyLoadEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\AssemblyMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\AssemblyUnloadEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\BreakpointEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\BreakpointEventRequest.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\Connection.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\CustomAttributeDataMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\CustomAttributeNamedArgumentMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\CustomAttributeTypedArgumentMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\DataConverter.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\EnumMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\Event.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\EventQueueImpl.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\EventRequest.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\EventType.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ExceptionEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ExceptionEventRequest.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\FieldInfoMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\IInvokeAsyncResult.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ILInstruction.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\IMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\InvalidStackFrameException.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\InvocationException.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\InvokeOptions.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ITargetProcess.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\LocalVariable.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\Location.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\MethodBodyMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\MethodEntryEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\MethodEntryEventRequest.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\MethodExitEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\MethodExitEventRequest.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\MethodMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\Mirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ModuleMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ObjectCollectedException.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ObjectMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ParameterInfoMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\PrimitiveValue.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\PropertyInfoMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\StackFrame.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\StepEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\StepEventRequest.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\StringMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\StructMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\SuspendPolicy.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ThreadDeathEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ThreadMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\ThreadStartEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\TypeLoadEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\TypeMirror.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\Value.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\VirtualMachine.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\VirtualMachineManager.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\VMDeathEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\VMDisconnectedException.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\VMDisconnectEvent.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\VMMismatchException.cs" />
|
||||
<Compile Include="Mono.Debugger.Soft\VMStartEvent.cs" />
|
||||
<None Include="Mono.Debugger\VirtualMachine.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class AbsentInformationException : Exception {
|
||||
|
||||
public AbsentInformationException () : base ("Debug information is not available for this frame.") {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class AppDomainCreateEvent : Event {
|
||||
AppDomainMirror domain;
|
||||
long id;
|
||||
|
||||
internal AppDomainCreateEvent (VirtualMachine vm, int req_id, long thread_id, long id) : base (EventType.AppDomainCreate, vm, req_id, thread_id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public AppDomainMirror Domain {
|
||||
get {
|
||||
if (domain == null)
|
||||
domain = vm.GetDomain (id);
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class AppDomainMirror : Mirror
|
||||
{
|
||||
string friendly_name;
|
||||
AssemblyMirror entry_assembly, corlib;
|
||||
|
||||
internal AppDomainMirror (VirtualMachine vm, long id) : base (vm, id) {
|
||||
}
|
||||
|
||||
public string FriendlyName {
|
||||
get {
|
||||
/* The name can't be empty during domain creation */
|
||||
if (friendly_name == null || friendly_name == String.Empty)
|
||||
friendly_name = vm.conn.Domain_GetName (id);
|
||||
return friendly_name;
|
||||
}
|
||||
}
|
||||
|
||||
// Not cached
|
||||
public AssemblyMirror[] GetAssemblies () {
|
||||
long[] ids = vm.conn.Domain_GetAssemblies (id);
|
||||
AssemblyMirror[] assemblies = new AssemblyMirror [ids.Length];
|
||||
// FIXME: Uniqueness
|
||||
for (int i = 0; i < ids.Length; ++i)
|
||||
assemblies [i] = vm.GetAssembly (ids [i]);
|
||||
return assemblies;
|
||||
}
|
||||
|
||||
// This returns null when called before the first AssemblyLoad event
|
||||
public AssemblyMirror GetEntryAssembly () {
|
||||
if (entry_assembly == null) {
|
||||
long ass_id = vm.conn.Domain_GetEntryAssembly (id);
|
||||
|
||||
entry_assembly = vm.GetAssembly (ass_id);
|
||||
}
|
||||
return entry_assembly;
|
||||
}
|
||||
|
||||
public AssemblyMirror Corlib {
|
||||
get {
|
||||
if (corlib == null) {
|
||||
long ass_id = vm.conn.Domain_GetCorlib (id);
|
||||
|
||||
corlib = vm.GetAssembly (ass_id);
|
||||
}
|
||||
return corlib;
|
||||
}
|
||||
}
|
||||
|
||||
public StringMirror CreateString (string s) {
|
||||
if (s == null)
|
||||
throw new ArgumentNullException ("s");
|
||||
|
||||
return vm.GetObject<StringMirror> (vm.conn.Domain_CreateString (id, s));
|
||||
}
|
||||
|
||||
public ObjectMirror CreateBoxedValue (Value value) {
|
||||
if (value == null)
|
||||
throw new ArgumentNullException ("value");
|
||||
if (!(value is PrimitiveValue) && !(value is StructMirror))
|
||||
throw new ArgumentException ("Value must be a PrimitiveValue or a StructMirror", "value");
|
||||
if ((value is PrimitiveValue) && (value as PrimitiveValue).Value == null)
|
||||
return null;
|
||||
|
||||
TypeMirror t = null;
|
||||
if (value is PrimitiveValue)
|
||||
t = GetCorrespondingType ((value as PrimitiveValue).Value.GetType ());
|
||||
else
|
||||
t = (value as StructMirror).Type;
|
||||
|
||||
return vm.GetObject<ObjectMirror> (vm.conn.Domain_CreateBoxedValue (id, t.Id, vm.EncodeValue (value)));
|
||||
}
|
||||
|
||||
TypeMirror[] primitiveTypes = new TypeMirror [32];
|
||||
|
||||
public TypeMirror GetCorrespondingType (Type t) {
|
||||
if (t == null)
|
||||
throw new ArgumentNullException ("t");
|
||||
TypeCode tc = Type.GetTypeCode (t);
|
||||
|
||||
if (tc == TypeCode.Empty || tc == TypeCode.Object)
|
||||
throw new ArgumentException ("t must be a primitive type", "t");
|
||||
|
||||
int tc_index = (int)tc;
|
||||
if (primitiveTypes [tc_index] == null) {
|
||||
primitiveTypes [tc_index] = Corlib.GetType ("System." + t.Name, false, false);
|
||||
if (primitiveTypes [tc_index] == null)
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
return primitiveTypes [tc_index];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class AppDomainUnloadEvent : Event {
|
||||
AppDomainMirror domain;
|
||||
long id;
|
||||
|
||||
internal AppDomainUnloadEvent (VirtualMachine vm, int req_id, long thread_id, long id) : base (EventType.AppDomainUnload, vm, req_id, thread_id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public AppDomainMirror Domain {
|
||||
get {
|
||||
if (domain == null)
|
||||
domain = vm.GetDomain (id);
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class ArrayMirror : ObjectMirror, IEnumerable {
|
||||
|
||||
public int[] lengths;
|
||||
public int[] lower_bounds;
|
||||
public int rank;
|
||||
|
||||
internal ArrayMirror (VirtualMachine vm, long id) : base (vm, id) {
|
||||
}
|
||||
|
||||
public int Length {
|
||||
get {
|
||||
GetLengths ();
|
||||
|
||||
int length = lengths [0];
|
||||
|
||||
for (int i = 1; i < Rank; i++) {
|
||||
length *= lengths [i];
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
public int Rank {
|
||||
get {
|
||||
GetLengths ();
|
||||
|
||||
return rank;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetLength (int dimension) {
|
||||
GetLengths ();
|
||||
|
||||
if (dimension < 0 || dimension >= Rank)
|
||||
throw new ArgumentOutOfRangeException ("dimension");
|
||||
|
||||
return lengths [dimension];
|
||||
}
|
||||
|
||||
public int GetLowerBound (int dimension) {
|
||||
GetLengths ();
|
||||
|
||||
if (dimension < 0 || dimension >= Rank)
|
||||
throw new ArgumentOutOfRangeException ("dimension");
|
||||
|
||||
return lower_bounds [dimension];
|
||||
}
|
||||
|
||||
void GetLengths () {
|
||||
if (lengths == null)
|
||||
lengths = vm.conn.Array_GetLength (id, out this.rank, out this.lower_bounds);
|
||||
}
|
||||
|
||||
public Value this [int index] {
|
||||
get {
|
||||
// FIXME: Multiple dimensions
|
||||
if (index < 0 || index > Length - 1)
|
||||
throw new IndexOutOfRangeException ();
|
||||
return vm.DecodeValue (vm.conn.Array_GetValues (id, index, 1) [0]);
|
||||
}
|
||||
set {
|
||||
// FIXME: Multiple dimensions
|
||||
if (index < 0 || index > Length - 1)
|
||||
throw new IndexOutOfRangeException ();
|
||||
vm.conn.Array_SetValues (id, index, new ValueImpl [] { vm.EncodeValue (value) });
|
||||
}
|
||||
}
|
||||
|
||||
public IList<Value> GetValues (int index, int length) {
|
||||
// FIXME: Multiple dimensions
|
||||
if (index < 0 || index > Length - length)
|
||||
throw new IndexOutOfRangeException ();
|
||||
return vm.DecodeValues (vm.conn.Array_GetValues (id, index, length));
|
||||
}
|
||||
|
||||
public void SetValues (int index, Value[] values) {
|
||||
if (values == null)
|
||||
throw new ArgumentNullException ("values");
|
||||
// FIXME: Multiple dimensions
|
||||
if (index < 0 || index > Length - values.Length)
|
||||
throw new IndexOutOfRangeException ();
|
||||
vm.conn.Array_SetValues (id, index, vm.EncodeValues (values));
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator ()
|
||||
{
|
||||
return new SimpleEnumerator (this);
|
||||
}
|
||||
|
||||
internal class SimpleEnumerator : IEnumerator, ICloneable
|
||||
{
|
||||
ArrayMirror arr;
|
||||
int pos, length;
|
||||
|
||||
public SimpleEnumerator (ArrayMirror arr)
|
||||
{
|
||||
this.arr = arr;
|
||||
this.pos = -1;
|
||||
this.length = arr.Length;
|
||||
}
|
||||
|
||||
public object Current {
|
||||
get {
|
||||
if (pos < 0 )
|
||||
throw new InvalidOperationException ("Enumeration has not started.");
|
||||
if (pos >= length)
|
||||
throw new InvalidOperationException ("Enumeration has already ended");
|
||||
return arr [pos];
|
||||
}
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (pos < length)
|
||||
pos++;
|
||||
if(pos < length)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
pos = -1;
|
||||
}
|
||||
|
||||
public object Clone ()
|
||||
{
|
||||
return MemberwiseClone ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class AssemblyLoadEvent : Event {
|
||||
AssemblyMirror assembly;
|
||||
long id;
|
||||
|
||||
internal AssemblyLoadEvent (VirtualMachine vm, int req_id, long thread_id, long id) : base (EventType.AssemblyLoad, vm, req_id, thread_id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public AssemblyMirror Assembly {
|
||||
get {
|
||||
if (assembly == null)
|
||||
assembly = vm.GetAssembly (id);
|
||||
return assembly;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using Mono.Debugger;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class AssemblyMirror : Mirror
|
||||
{
|
||||
string location;
|
||||
MethodMirror entry_point;
|
||||
bool entry_point_set;
|
||||
ModuleMirror main_module;
|
||||
AssemblyName aname;
|
||||
AssemblyDefinition meta;
|
||||
|
||||
internal AssemblyMirror (VirtualMachine vm, long id) : base (vm, id) {
|
||||
}
|
||||
|
||||
public string Location {
|
||||
get {
|
||||
if (location == null)
|
||||
location = vm.conn.Assembly_GetLocation (id);
|
||||
return location;
|
||||
}
|
||||
}
|
||||
|
||||
public MethodMirror EntryPoint {
|
||||
get {
|
||||
if (!entry_point_set) {
|
||||
long mid = vm.conn.Assembly_GetEntryPoint (id);
|
||||
|
||||
if (mid != 0)
|
||||
entry_point = vm.GetMethod (mid);
|
||||
entry_point_set = true;
|
||||
}
|
||||
return entry_point;
|
||||
}
|
||||
}
|
||||
|
||||
public ModuleMirror ManifestModule {
|
||||
get {
|
||||
if (main_module == null) {
|
||||
main_module = vm.GetModule (vm.conn.Assembly_GetManifestModule (id));
|
||||
}
|
||||
return main_module;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual AssemblyName GetName () {
|
||||
if (aname == null) {
|
||||
string name = vm.conn.Assembly_GetName (id);
|
||||
aname = new AssemblyName (name);
|
||||
}
|
||||
return aname;
|
||||
}
|
||||
|
||||
public ObjectMirror GetAssemblyObject () {
|
||||
return vm.GetObject (vm.conn.Assembly_GetObject (id));
|
||||
}
|
||||
|
||||
public TypeMirror GetType (string name, bool throwOnError, bool ignoreCase)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException (name);
|
||||
if (name.Length == 0)
|
||||
throw new ArgumentException ("name", "Name cannot be empty");
|
||||
|
||||
if (throwOnError)
|
||||
throw new NotImplementedException ();
|
||||
return vm.GetType (vm.conn.Assembly_GetType (id, name, ignoreCase));
|
||||
}
|
||||
|
||||
public TypeMirror GetType (String name, Boolean throwOnError)
|
||||
{
|
||||
return GetType (name, throwOnError, false);
|
||||
}
|
||||
|
||||
public TypeMirror GetType (String name) {
|
||||
return GetType (name, false, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* An optional Cecil assembly which could be used to access metadata instead
|
||||
* of reading it from the debuggee.
|
||||
*/
|
||||
public AssemblyDefinition Metadata {
|
||||
get {
|
||||
return meta;
|
||||
}
|
||||
set {
|
||||
if (value.MainModule.Name != ManifestModule.Name)
|
||||
throw new ArgumentException ("The supplied assembly is named '" + value.MainModule.Name + "', while the assembly in the debuggee is named '" + ManifestModule.Name + "'.");
|
||||
if (value.MainModule.Mvid != ManifestModule.ModuleVersionId)
|
||||
throw new ArgumentException ("The supplied assembly's main module has guid '" + value.MainModule.Mvid + ", while the assembly in the debuggee has guid '" + ManifestModule.ModuleVersionId + "'.", "value");
|
||||
meta = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class AssemblyUnloadEvent : Event {
|
||||
AssemblyMirror assembly;
|
||||
long id;
|
||||
|
||||
internal AssemblyUnloadEvent (VirtualMachine vm, int req_id, long thread_id, long id) : base (EventType.AssemblyUnload, vm, req_id, thread_id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public AssemblyMirror Assembly {
|
||||
get {
|
||||
if (assembly == null)
|
||||
assembly = vm.GetAssembly (id);
|
||||
return assembly;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class BreakpointEvent : Event {
|
||||
MethodMirror method;
|
||||
long id;
|
||||
|
||||
internal BreakpointEvent (VirtualMachine vm, int req_id, long thread_id, long id, long loc) : base (EventType.Breakpoint, vm, req_id, thread_id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public MethodMirror Method {
|
||||
get {
|
||||
if (method == null)
|
||||
method = vm.GetMethod (id);
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public sealed class BreakpointEventRequest : EventRequest {
|
||||
|
||||
MethodMirror method;
|
||||
long location;
|
||||
|
||||
internal BreakpointEventRequest (VirtualMachine vm, MethodMirror method, long location) : base (vm, EventType.Breakpoint) {
|
||||
if (method == null)
|
||||
throw new ArgumentNullException ("method");
|
||||
CheckMirror (vm, method);
|
||||
if (method.Locations.Count > 0 && !method.Locations.Any (l => l.ILOffset == location))
|
||||
throw new ArgumentException ("A breakpoint can only be set at an IL offset which is equal to the ILOffset property of one of the locations in method.Locations", "location");
|
||||
this.method = method;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public override void Enable () {
|
||||
var mods = new List <Modifier> ();
|
||||
mods.Add (new LocationModifier () { Method = method.Id, Location = location });
|
||||
SendReq (mods);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,207 +0,0 @@
|
|||
2010-06-04 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* StackFrame.cs (GetVisibleVariables): New method to return the set of variables
|
||||
visible at the current stack frame.
|
||||
|
||||
2010-05-24 Martin Baulig <martin@ximian.com>
|
||||
|
||||
* Connection.cs (VersionInfo): Make this public.
|
||||
|
||||
* VirtualMachine.cs (Version): New public property.
|
||||
|
||||
2010-05-07 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* VirtualMachine.cs (ErrorHandler): Convert ABSENT_INFORMATION to
|
||||
AbsentInformationException.
|
||||
|
||||
* AbsentInformationException.cs: New file.
|
||||
|
||||
2010-04-30 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* TypeMirror.cs: Add new overload for GetSourceFiles () which returns full paths.
|
||||
|
||||
2010-04-27 Lluis Sanchez <lluis@novell.com>
|
||||
|
||||
* ITargetProcess.cs:
|
||||
* VirtualMachine.cs:
|
||||
* VirtualMachineManager.cs:
|
||||
Restored old API. Renamed IProcess to ITargetProcess everywhere
|
||||
to avoid naming conflicts.
|
||||
|
||||
2010-04-26 Lluis Sanchez <lluis@novell.com>
|
||||
|
||||
* IProcess.cs:
|
||||
* VirtualMachine.cs:
|
||||
* VirtualMachineManager.cs:
|
||||
Added new IProcess interface which wraps the debugged process.
|
||||
This abstraction makes it easier to support debugging processes
|
||||
for which we don't have a direct Process reference (for example,
|
||||
if the process is remote).
|
||||
|
||||
2010-04-10 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* ThreadMirror.cs: Add a ThreadId property.
|
||||
|
||||
2010-03-05 Martin Baulig <martin@ximian.com>
|
||||
|
||||
**** Backport of r153125 and r153336 ****
|
||||
|
||||
Add support for aborting invocations.
|
||||
|
||||
* IInvokeAsyncResult.cs: New file.
|
||||
(IInvokeAsyncResult): New public interface; derives from
|
||||
`IAsyncResult' and contains an Abort() method.
|
||||
|
||||
* Connection.cs
|
||||
(Connection.VM_BeginInvokeMethod): Return the `id'.
|
||||
(Connection.VM_AbortInvoke): New method.
|
||||
|
||||
* ObjectMirror.cs
|
||||
(ObjectMirror.AbortInvoke): New internal static method.
|
||||
|
||||
2010-03-01 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* VirtualMachine.cs: Allow working with runtimes implementing a different
|
||||
minor version of the debugger protocol.
|
||||
|
||||
2010-03-01 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* Connection.cs: Send the protocol version used by the client to the debuggee
|
||||
after the handshake.
|
||||
|
||||
2010-03-01 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* Location.cs: Implement ToString ().
|
||||
|
||||
* AppDomainMirror.cs (CreateBoxedValue): New method to create a boxed value from
|
||||
a primitive value or struct.
|
||||
|
||||
2010-02-26 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* Connection.cs: Throw a NotSupportedException if the protocol version doesn't
|
||||
support the caught/uncaught flags in an exception modifier.
|
||||
|
||||
2010-02-20 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* VirtualMachine.cs (CreateExceptionRequest): Add an overload taking two
|
||||
booleans which specify whenever to report caught/uncaught exceptions.
|
||||
|
||||
* ExceptionRequest.cs: Add public properties for them.
|
||||
|
||||
* Connections.cs: Pass the caught/uncaught flags to the debuggee. Bump protocol
|
||||
minor version.
|
||||
|
||||
2010-02-11 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* AssemblyMirror.cs: Add missing GetType () overloads.
|
||||
|
||||
2010-02-04 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* TypeMirror.cs (EnumUnderlyingType): New property.
|
||||
|
||||
* EnumMirror.cs: Use it.
|
||||
|
||||
* VirtualMachine.cs (CreateEnumMirror): New method to create an EnumMirror.
|
||||
|
||||
* AppDomainMirror.cs (GetCorrespondingType): New method to return a TypeMirror
|
||||
corresponding to a primitive type.
|
||||
|
||||
* TypeMirror.cs (IsEnum): Implement.
|
||||
|
||||
* EnumMirror.cs (.ctor): New internal constructor called from CreateEnumMirror
|
||||
which does lots of error checking.
|
||||
|
||||
2010-01-28 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* AssemblyUnloadEvent: New file.
|
||||
|
||||
* VirtualMachine.cs Connection.cs: Add support for assembly unload events.
|
||||
|
||||
2009-12-05 Lluis Sanchez <lluis@novell.com>
|
||||
|
||||
* StructMirror.cs: Fix field indexer for structs with static fields.
|
||||
* VirtualMachineManager.cs: Added an option to LaunchOptions which
|
||||
allows providing a custom method for launching the process. This
|
||||
allows launching mono in a wrapper process.
|
||||
|
||||
2009-12-03 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* StructMirror.cs (this): Ignore static fields.
|
||||
|
||||
2009-12-02 Geoff Norton <gnorton@novell.com>
|
||||
|
||||
* VirtualMachineManager.cs: We might get a SocketException (interrupted)
|
||||
here, so lets just handle all Exceptions to our Accept pattern the same
|
||||
way
|
||||
|
||||
2009-12-01 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* VirtualMachine.cs (ErrorHandler): Handle NOT_SUSPENDED error code too.
|
||||
|
||||
2009-11-24 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* ObjectMirror.cs TypeMirror.cs StructMirror.cs: Make the BeginInvokeMethod
|
||||
which takes a 'vm' argument obsolete, it was added by mistake, add a version
|
||||
without that argument instead.
|
||||
|
||||
2009-11-19 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* AssemblyMirror.cs: Add a GetName () method.
|
||||
|
||||
2009-11-17 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* Connection.cs ObjectMirror.cs: Implement invokes in a real asynchronous way,
|
||||
without waiting.
|
||||
|
||||
2009-11-14 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* InvokeOptions.cs: Add SingleThreaded option, not yet works.
|
||||
|
||||
* VirtualMachineManager.cs (Launch): Pass options to BeginLaunch.
|
||||
|
||||
* ObjectMirror.cs TypeMirror.cs StructMirror.cs: Implement an async version of
|
||||
InvokeMethod ().
|
||||
|
||||
2009-11-13 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* InvokeOptions.cs: New file.
|
||||
|
||||
* ObjectMirror.cs TypeMirror.cs StructMirror.cs: Add support for passing flags
|
||||
to InvokeMethod ().
|
||||
|
||||
* Connection.cs: Bump protocol version.
|
||||
|
||||
2009-11-12 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* VirtualMachineManager.cs: Put back the old Launch (string[], LaunchOptions)
|
||||
overload.
|
||||
|
||||
2009-11-11 Geoff Norton <gnorton@novell.com>
|
||||
|
||||
* VirtualMachineManager.cs: Refactor the APIs to have async methods.
|
||||
Remove a bunch of Listen overloads that are pointless. Refactor
|
||||
Launch to take a ProcessStartInfo instead of string arguments.
|
||||
|
||||
2009-11-10 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* VirtualMachineManager.cs (Launch): Close the listening socket instead of
|
||||
shutting it down since Shutdown throws on exception on non-connected sockets
|
||||
in ms.net.
|
||||
|
||||
2009-11-05 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* VirtualMachineManager.cs (Listen): Resurrect the old listen method.
|
||||
|
||||
* VirtualMachineManager.cs (Connect): New method to connect to a runtime
|
||||
listening at the provided address.
|
||||
|
||||
2009-11-04 Lluis Sanchez <lluis@novell.com>
|
||||
|
||||
* VirtualMachineManager.cs: Properly redirect standard output.
|
||||
|
||||
2009-11-03 Zoltan Varga <vargaz@gmail.com>
|
||||
|
||||
* EventRequest.cs (AssemblyFilter): New property to filter
|
||||
events based on a list of assemblies.
|
||||
|
||||
* Connection.cs: Add assembly filters to the protocol implementation.
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,143 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Mono.Cecil.Metadata;
|
||||
|
||||
namespace Mono.Debugger.Soft {
|
||||
|
||||
public sealed class CustomAttributeDataMirror {
|
||||
MethodMirror ctorInfo;
|
||||
IList<CustomAttributeTypedArgumentMirror> ctorArgs;
|
||||
IList<CustomAttributeNamedArgumentMirror> namedArgs;
|
||||
|
||||
internal CustomAttributeDataMirror (MethodMirror ctorInfo, object [] ctorArgs, object [] namedArgs)
|
||||
{
|
||||
this.ctorInfo = ctorInfo;
|
||||
|
||||
this.ctorArgs = Array.AsReadOnly<CustomAttributeTypedArgumentMirror>
|
||||
(ctorArgs != null ? UnboxValues<CustomAttributeTypedArgumentMirror> (ctorArgs) : new CustomAttributeTypedArgumentMirror [0]);
|
||||
|
||||
this.namedArgs = Array.AsReadOnly<CustomAttributeNamedArgumentMirror>
|
||||
(namedArgs != null ? UnboxValues<CustomAttributeNamedArgumentMirror> (namedArgs) : new CustomAttributeNamedArgumentMirror [0]);
|
||||
}
|
||||
|
||||
[ComVisible (true)]
|
||||
public MethodMirror Constructor {
|
||||
get {
|
||||
return ctorInfo;
|
||||
}
|
||||
}
|
||||
|
||||
[ComVisible (true)]
|
||||
public IList<CustomAttributeTypedArgumentMirror> ConstructorArguments {
|
||||
get {
|
||||
return ctorArgs;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<CustomAttributeNamedArgumentMirror> NamedArguments {
|
||||
get {
|
||||
return namedArgs;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
|
||||
sb.Append ("[" + ctorInfo.DeclaringType.FullName + "(");
|
||||
if (ctorArgs != null) {
|
||||
for (int i = 0; i < ctorArgs.Count; i++) {
|
||||
sb.Append (ctorArgs [i].ToString ());
|
||||
if (i + 1 < ctorArgs.Count)
|
||||
sb.Append (", ");
|
||||
}
|
||||
}
|
||||
|
||||
if (namedArgs != null) {
|
||||
if (namedArgs.Count > 0)
|
||||
sb.Append (", ");
|
||||
|
||||
for (int j = 0; j < namedArgs.Count; j++) {
|
||||
sb.Append (namedArgs [j].ToString ());
|
||||
if (j + 1 < namedArgs.Count)
|
||||
sb.Append (", ");
|
||||
}
|
||||
}
|
||||
sb.AppendFormat (")]");
|
||||
|
||||
return sb.ToString ();
|
||||
}
|
||||
|
||||
static T [] UnboxValues<T> (object [] values)
|
||||
{
|
||||
T [] retval = new T [values.Length];
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
retval [i] = (T) values [i];
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a normal object from the value, so accessing the cattr doesn't
|
||||
* require remoting calls.
|
||||
*/
|
||||
static CustomAttributeTypedArgumentMirror CreateArg (VirtualMachine vm, ValueImpl vi) {
|
||||
object val;
|
||||
|
||||
/* Instead of receiving a mirror of the Type object, we receive the id of the type */
|
||||
if (vi.Type == (ElementType)ValueTypeId.VALUE_TYPE_ID_TYPE)
|
||||
val = vm.GetType (vi.Id);
|
||||
else {
|
||||
Value v = vm.DecodeValue (vi);
|
||||
if (v is PrimitiveValue)
|
||||
val = (v as PrimitiveValue).Value;
|
||||
else if (v is StringMirror)
|
||||
val = (v as StringMirror).Value;
|
||||
else
|
||||
// FIXME:
|
||||
val = v;
|
||||
}
|
||||
return new CustomAttributeTypedArgumentMirror (null, val);
|
||||
}
|
||||
|
||||
internal static CustomAttributeDataMirror[] Create (VirtualMachine vm, CattrInfo[] info) {
|
||||
var res = new CustomAttributeDataMirror [info.Length];
|
||||
for (int i = 0; i < info.Length; ++i) {
|
||||
CattrInfo attr = info [i];
|
||||
MethodMirror ctor = vm.GetMethod (attr.ctor_id);
|
||||
var ctor_args = new object [attr.ctor_args.Length];
|
||||
for (int j = 0; j < ctor_args.Length; ++j)
|
||||
ctor_args [j] = CreateArg (vm, attr.ctor_args [j]);
|
||||
var named_args = new object [attr.named_args.Length];
|
||||
for (int j = 0; j < named_args.Length; ++j) {
|
||||
CattrNamedArgInfo arg = attr.named_args [j];
|
||||
CustomAttributeTypedArgumentMirror val;
|
||||
|
||||
val = CreateArg (vm, arg.value);
|
||||
|
||||
if (arg.is_property) {
|
||||
foreach (var prop in ctor.DeclaringType.GetProperties ()) {
|
||||
if (prop.Id == arg.id)
|
||||
named_args [j] = new CustomAttributeNamedArgumentMirror (prop, null, val);
|
||||
}
|
||||
} else {
|
||||
foreach (var field in ctor.DeclaringType.GetFields ()) {
|
||||
if (field.Id == arg.id)
|
||||
named_args [j] = new CustomAttributeNamedArgumentMirror (null, field, val);
|
||||
}
|
||||
}
|
||||
if (named_args [j] == null)
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
res [i] = new CustomAttributeDataMirror (vm.GetMethod (attr.ctor_id), ctor_args, named_args);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Mono.Debugger.Soft {
|
||||
|
||||
public struct CustomAttributeNamedArgumentMirror {
|
||||
CustomAttributeTypedArgumentMirror arg;
|
||||
PropertyInfoMirror prop;
|
||||
FieldInfoMirror field;
|
||||
|
||||
internal CustomAttributeNamedArgumentMirror (PropertyInfoMirror prop, FieldInfoMirror field, CustomAttributeTypedArgumentMirror arg)
|
||||
{
|
||||
this.arg = arg;
|
||||
this.prop = prop;
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public PropertyInfoMirror Property {
|
||||
get {
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
|
||||
public FieldInfoMirror Field {
|
||||
get {
|
||||
return field;
|
||||
}
|
||||
}
|
||||
|
||||
public CustomAttributeTypedArgumentMirror TypedValue {
|
||||
get {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Mono.Debugger.Soft {
|
||||
|
||||
public struct CustomAttributeTypedArgumentMirror {
|
||||
Type type;
|
||||
object value;
|
||||
|
||||
internal CustomAttributeTypedArgumentMirror (Type type, object value)
|
||||
{
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
|
||||
if (value != null)
|
||||
this.type = value.GetType ();
|
||||
else
|
||||
this.type = typeof (void);
|
||||
|
||||
// MS seems to convert arrays into a ReadOnlyCollection
|
||||
if (value is Array) {
|
||||
Array a = (Array)value;
|
||||
|
||||
Type etype = a.GetType ().GetElementType ();
|
||||
CustomAttributeTypedArgumentMirror[] new_value = new CustomAttributeTypedArgumentMirror [a.GetLength (0)];
|
||||
for (int i = 0; i < new_value.Length; ++i)
|
||||
new_value [i] = new CustomAttributeTypedArgumentMirror (etype, a.GetValue (i));
|
||||
this.value = new ReadOnlyCollection <CustomAttributeTypedArgumentMirror> (new_value);
|
||||
}
|
||||
}
|
||||
|
||||
public Type ArgumentType {
|
||||
get {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
public object Value {
|
||||
get {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
string val = value != null ? value.ToString () : String.Empty;
|
||||
if (ArgumentType == typeof (string))
|
||||
return "\"" + val + "\"";
|
||||
if (ArgumentType == typeof (Type))
|
||||
return "typeof (" + val + ")";
|
||||
if (ArgumentType.IsEnum)
|
||||
return "(" + ArgumentType.Name + ")" + val;
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,48 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
/*
|
||||
* Represents an enum value in the debuggee
|
||||
*/
|
||||
public class EnumMirror : StructMirror {
|
||||
|
||||
internal EnumMirror (VirtualMachine vm, TypeMirror type, Value[] fields) : base (vm, type, fields) {
|
||||
}
|
||||
|
||||
internal EnumMirror (VirtualMachine vm, TypeMirror type, PrimitiveValue value) : base (vm, type, new Value[] { value }) {
|
||||
if (type == null)
|
||||
throw new ArgumentNullException ("type");
|
||||
if (value == null)
|
||||
throw new ArgumentNullException ("value");
|
||||
if (!type.IsEnum)
|
||||
throw new ArgumentException ("type must be an enum type", "type");
|
||||
TypeMirror t = type.EnumUnderlyingType;
|
||||
if (value.Value == null || !value.Value.GetType ().IsPrimitive || t != vm.RootDomain.GetCorrespondingType (value.Value.GetType ()))
|
||||
throw new ArgumentException ("Value '" + value.Value + "' does not match the type of the enum.");
|
||||
}
|
||||
|
||||
public object Value {
|
||||
get {
|
||||
return ((PrimitiveValue)Fields [0]).Value;
|
||||
}
|
||||
set {
|
||||
SetField (0, vm.CreateValue (value));
|
||||
}
|
||||
}
|
||||
|
||||
public string StringValue {
|
||||
get {
|
||||
foreach (FieldInfoMirror f in Type.GetFields ()) {
|
||||
if (f.IsStatic) {
|
||||
object v = (Type.GetValue (f) as EnumMirror).Value;
|
||||
if (f.IsStatic && v.Equals (Value))
|
||||
return f.Name;
|
||||
}
|
||||
}
|
||||
return Value.ToString ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public abstract class Event {
|
||||
protected VirtualMachine vm;
|
||||
EventType evtype;
|
||||
ThreadMirror thread;
|
||||
int req_id;
|
||||
long thread_id;
|
||||
|
||||
internal Event (EventType evtype, VirtualMachine vm, int req_id, long thread_id) {
|
||||
this.evtype = evtype;
|
||||
this.vm = vm;
|
||||
this.req_id = req_id;
|
||||
this.thread_id = thread_id;
|
||||
}
|
||||
|
||||
internal Event (EventType evtype, VirtualMachine vm) {
|
||||
this.evtype = evtype;
|
||||
this.vm = vm;
|
||||
this.thread_id = -1;
|
||||
}
|
||||
|
||||
public EventType EventType {
|
||||
get {
|
||||
return evtype;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString () {
|
||||
return evtype.ToString ();
|
||||
}
|
||||
|
||||
public ThreadMirror Thread {
|
||||
get {
|
||||
if (thread_id == -1)
|
||||
return null;
|
||||
if (thread == null)
|
||||
thread = vm.GetThread (thread_id);
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
public EventRequest Request {
|
||||
get {
|
||||
return vm.GetRequest (req_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
#if FALSE
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Mono.Debugger;
|
||||
using Mono.Debugger.Requests;
|
||||
using Mono.Debugger.Events;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
class EventQueueImpl : MirrorImpl, EventQueue
|
||||
{
|
||||
bool disconnected;
|
||||
Dictionary<int, byte[]> reply_packets;
|
||||
Thread receiver_thread;
|
||||
Queue queue;
|
||||
object queue_monitor;
|
||||
object reply_packets_monitor;
|
||||
|
||||
public EventQueueImpl (VirtualMachineImpl vm) : base (vm) {
|
||||
reply_packets = new Dictionary<int, byte[]> ();
|
||||
reply_packets_monitor = new Object ();
|
||||
|
||||
queue = new Queue ();
|
||||
queue_monitor = new Object ();
|
||||
receiver_thread = new Thread (new ThreadStart (receiver_thread_main));
|
||||
receiver_thread.Start ();
|
||||
}
|
||||
|
||||
public EventSet Remove () {
|
||||
if (disconnected)
|
||||
// FIXME: VMDisconnectedException
|
||||
throw new IOException ();
|
||||
|
||||
lock (queue_monitor) {
|
||||
if (queue.Count == 0)
|
||||
Monitor.Wait (queue_monitor);
|
||||
return (EventSet)queue.Dequeue ();
|
||||
}
|
||||
}
|
||||
|
||||
public EventSet Remove (int timeout) {
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
Event DecodeEventInfo (WireProtocol.EventInfo info) {
|
||||
EventRequest req = FindRequest (info.requestId);
|
||||
if (info.eventKind == WireProtocol.EVENT_VM_START) {
|
||||
WireProtocol.VMStartEventInfo einfo = (WireProtocol.VMStartEventInfo)info;
|
||||
return new VMStartEventImpl (vm, req, new ThreadReferenceImpl (vm, einfo.thread), new AppDomainMirrorImpl (vm, einfo.domain));
|
||||
} else if (info.eventKind == WireProtocol.EVENT_VM_DEATH) {
|
||||
return new VMDeathEventImpl (vm, req);
|
||||
} else if (info.eventKind == WireProtocol.EVENT_THREAD_START) {
|
||||
WireProtocol.ThreadStartEventInfo einfo = (WireProtocol.ThreadStartEventInfo)info;
|
||||
return new ThreadStartEventImpl (vm, req, new ThreadReferenceImpl (vm, einfo.thread));
|
||||
} else if (info.eventKind == WireProtocol.EVENT_THREAD_DEATH) {
|
||||
WireProtocol.ThreadDeathEventInfo einfo = (WireProtocol.ThreadDeathEventInfo)info;
|
||||
return new ThreadDeathEventImpl (vm, req, new ThreadReferenceImpl (vm, einfo.thread));
|
||||
} else {
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
EventRequest FindRequest (int requestId) {
|
||||
if (requestId == 0)
|
||||
return null;
|
||||
else
|
||||
return ((EventRequestManagerImpl)vm.EventRequestManager).FindRequest (requestId);
|
||||
}
|
||||
|
||||
// Wait for the reply for a command packet
|
||||
public byte[] WaitForReply (int packetId) {
|
||||
while (true) {
|
||||
lock (reply_packets_monitor) {
|
||||
if (reply_packets.ContainsKey (packetId)) {
|
||||
byte[] reply = reply_packets [packetId];
|
||||
reply_packets.Remove (packetId);
|
||||
return reply;
|
||||
} else {
|
||||
Monitor.Wait (reply_packets_monitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add_event_set (EventSet set) {
|
||||
lock (queue_monitor) {
|
||||
queue.Enqueue (set);
|
||||
Monitor.Pulse (queue_monitor);
|
||||
}
|
||||
}
|
||||
|
||||
void receiver_thread_main () {
|
||||
|
||||
Connection conn = vm.Connection;
|
||||
|
||||
while (true) {
|
||||
byte[] packet = conn.ReadPacket ();
|
||||
|
||||
if (packet.Length == 0) {
|
||||
disconnected = true;
|
||||
|
||||
VMDisconnectEventImpl ev = new VMDisconnectEventImpl (vm, null);
|
||||
add_event_set (new EventSetImpl (vm, new Event [] { ev }, SuspendPolicy.SuspendNone));
|
||||
break;
|
||||
}
|
||||
|
||||
if (WireProtocol.IsReplyPacket (packet)) {
|
||||
/* Reply packet */
|
||||
int id = WireProtocol.GetPacketId (packet);
|
||||
lock (reply_packets_monitor) {
|
||||
reply_packets [id] = packet;
|
||||
Monitor.PulseAll (reply_packets_monitor);
|
||||
}
|
||||
} else {
|
||||
WireProtocol.Packet decoded = WireProtocol.DecodePacket (packet);
|
||||
if (decoded is WireProtocol.Event.CompositePacket) {
|
||||
WireProtocol.Event.CompositePacket p = (WireProtocol.Event.CompositePacket)decoded;
|
||||
Event[] events = new Event [p.events.Length];
|
||||
for (int i = 0; i < p.events.Length; ++i) {
|
||||
events [i] = DecodeEventInfo (p.events [i]);
|
||||
}
|
||||
|
||||
add_event_set (new EventSetImpl (vm, events, p.suspendPolicy));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,142 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public abstract class EventRequest {
|
||||
protected int id;
|
||||
protected EventType etype;
|
||||
protected bool enabled;
|
||||
protected VirtualMachine vm;
|
||||
protected SuspendPolicy suspend;
|
||||
protected int count;
|
||||
protected ThreadMirror thread;
|
||||
protected IList<AssemblyMirror> assembly_filter;
|
||||
|
||||
internal EventRequest (VirtualMachine vm, EventType etype) {
|
||||
this.vm = vm;
|
||||
this.etype = etype;
|
||||
this.suspend = SuspendPolicy.All;
|
||||
}
|
||||
|
||||
internal EventRequest (EventType etype, int id) {
|
||||
this.id = id;
|
||||
this.etype = etype;
|
||||
}
|
||||
|
||||
internal int Id {
|
||||
get {
|
||||
return id;
|
||||
}
|
||||
set {
|
||||
id = value;
|
||||
}
|
||||
}
|
||||
|
||||
public EventType EventType {
|
||||
get {
|
||||
return etype;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Enabled {
|
||||
get {
|
||||
return enabled;
|
||||
}
|
||||
set {
|
||||
if (value != enabled) {
|
||||
if (value)
|
||||
Enable ();
|
||||
else
|
||||
Disable ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Count {
|
||||
get {
|
||||
return count;
|
||||
}
|
||||
set {
|
||||
CheckDisabled ();
|
||||
count = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ThreadMirror Thread {
|
||||
get {
|
||||
return thread;
|
||||
}
|
||||
set {
|
||||
CheckDisabled ();
|
||||
if (value != null && value.VirtualMachine != vm)
|
||||
throw new VMMismatchException ();
|
||||
thread = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<AssemblyMirror> AssemblyFilter {
|
||||
get {
|
||||
return assembly_filter;
|
||||
}
|
||||
set {
|
||||
CheckDisabled ();
|
||||
if (value != null) {
|
||||
foreach (var ass in value)
|
||||
if (ass == null)
|
||||
throw new ArgumentException ("one of the elements of the array is null.");
|
||||
}
|
||||
assembly_filter = value;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Every time an EventRequest object is enabled, a new JDWP event request
|
||||
* is created, and the event request's id changes.
|
||||
*/
|
||||
internal void SendReq (List<Modifier> mods) {
|
||||
if (!enabled) {
|
||||
if (Count > 0)
|
||||
mods.Add (new CountModifier () { Count = Count });
|
||||
if (Thread != null)
|
||||
mods.Add (new ThreadModifier () { Thread = Thread.Id });
|
||||
if (AssemblyFilter != null)
|
||||
mods.Add (new AssemblyModifier () { Assemblies = AssemblyFilter.Select (x => x.Id ).ToArray () });
|
||||
id = vm.conn.EnableEvent (EventType, suspend, mods);
|
||||
SetEnabled (id);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Enable () {
|
||||
SendReq (new List<Modifier> ());
|
||||
}
|
||||
|
||||
public void Disable () {
|
||||
if (enabled) {
|
||||
vm.conn.ClearEventRequest (etype, id);
|
||||
enabled = false;
|
||||
// FIXME: This causes problems because Events can still reference
|
||||
// the old id
|
||||
//vm.RemoveRequest (this, id);
|
||||
id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected void SetEnabled (int id) {
|
||||
this.id = id;
|
||||
enabled = true;
|
||||
vm.AddRequest (this, id);
|
||||
}
|
||||
|
||||
protected void CheckDisabled () {
|
||||
if (Enabled)
|
||||
throw new InvalidOperationException ("Request objects can only be modified while they are disabled.");
|
||||
}
|
||||
|
||||
protected void CheckMirror (VirtualMachine vm, Mirror m) {
|
||||
if (vm != m.VirtualMachine)
|
||||
throw new VMMismatchException ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
// Keep it in sync with debugger-agent.h
|
||||
public enum EventType {
|
||||
VMStart = 0,
|
||||
VMDeath = 1,
|
||||
ThreadStart = 2,
|
||||
ThreadDeath = 3,
|
||||
AppDomainCreate = 4,
|
||||
AppDomainUnload = 5,
|
||||
MethodEntry = 6,
|
||||
MethodExit = 7,
|
||||
AssemblyLoad = 8,
|
||||
AssemblyUnload = 9,
|
||||
Breakpoint = 10,
|
||||
Step = 11,
|
||||
TypeLoad = 12,
|
||||
Exception = 13,
|
||||
// Not part of the wire protocol
|
||||
VMDisconnect = 99
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class ExceptionEvent : Event {
|
||||
ObjectMirror exc;
|
||||
long exc_id;
|
||||
|
||||
internal ExceptionEvent (VirtualMachine vm, int req_id, long thread_id, long exc_id, long loc) : base (EventType.Exception, vm, req_id, thread_id) {
|
||||
this.exc_id = exc_id;
|
||||
}
|
||||
|
||||
public ObjectMirror Exception {
|
||||
get {
|
||||
if (exc == null)
|
||||
exc = vm.GetObject (exc_id);
|
||||
return exc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public sealed class ExceptionEventRequest : EventRequest {
|
||||
|
||||
TypeMirror exc_type;
|
||||
bool caught, uncaught;
|
||||
|
||||
internal ExceptionEventRequest (VirtualMachine vm, TypeMirror exc_type, bool caught, bool uncaught) : base (vm, EventType.Exception) {
|
||||
if (exc_type != null) {
|
||||
CheckMirror (vm, exc_type);
|
||||
TypeMirror exception_type = vm.RootDomain.Corlib.GetType ("System.Exception", false, false);
|
||||
if (!exception_type.IsAssignableFrom (exc_type))
|
||||
throw new ArgumentException ("The exception type does not inherit from System.Exception", "exc_type");
|
||||
}
|
||||
this.exc_type = exc_type;
|
||||
this.caught = caught;
|
||||
this.uncaught = uncaught;
|
||||
}
|
||||
|
||||
public TypeMirror ExceptionType {
|
||||
get {
|
||||
return exc_type;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Enable () {
|
||||
var mods = new List <Modifier> ();
|
||||
mods.Add (new ExceptionModifier () { Type = exc_type != null ? exc_type.Id : 0, Caught = caught, Uncaught = uncaught });
|
||||
SendReq (mods);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,159 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using C = Mono.Cecil;
|
||||
using Mono.Cecil.Metadata;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class FieldInfoMirror : Mirror {
|
||||
|
||||
TypeMirror parent;
|
||||
string name;
|
||||
TypeMirror type;
|
||||
FieldAttributes attrs;
|
||||
CustomAttributeDataMirror[] cattrs;
|
||||
|
||||
public FieldInfoMirror (TypeMirror parent, long id, string name, TypeMirror type, FieldAttributes attrs) : base (parent.VirtualMachine, id) {
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.attrs = attrs;
|
||||
}
|
||||
|
||||
public TypeMirror DeclaringType {
|
||||
get {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public TypeMirror FieldType {
|
||||
get {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
public FieldAttributes Attributes {
|
||||
get {
|
||||
return attrs;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsLiteral
|
||||
{
|
||||
get {return (Attributes & FieldAttributes.Literal) != 0;}
|
||||
}
|
||||
|
||||
public bool IsStatic
|
||||
{
|
||||
get {return (Attributes & FieldAttributes.Static) != 0;}
|
||||
}
|
||||
|
||||
public bool IsInitOnly
|
||||
{
|
||||
get {return (Attributes & FieldAttributes.InitOnly) != 0;}
|
||||
}
|
||||
|
||||
public Boolean IsPublic
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean IsPrivate
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean IsFamily
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean IsAssembly
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean IsFamilyAndAssembly
|
||||
{
|
||||
get {
|
||||
return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamANDAssem;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean IsFamilyOrAssembly
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean IsPinvokeImpl
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Attributes & FieldAttributes.PinvokeImpl) == FieldAttributes.PinvokeImpl;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean IsSpecialName
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Attributes & FieldAttributes.SpecialName) == FieldAttributes.SpecialName;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean IsNotSerialized
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Attributes & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
|
||||
}
|
||||
}
|
||||
|
||||
public CustomAttributeDataMirror[] GetCustomAttributes (bool inherit) {
|
||||
return GetCAttrs (null, inherit);
|
||||
}
|
||||
|
||||
public CustomAttributeDataMirror[] GetCustomAttributes (TypeMirror attributeType, bool inherit) {
|
||||
if (attributeType == null)
|
||||
throw new ArgumentNullException ("attributeType");
|
||||
return GetCAttrs (attributeType, inherit);
|
||||
}
|
||||
|
||||
CustomAttributeDataMirror[] GetCAttrs (TypeMirror type, bool inherit) {
|
||||
// FIXME: Handle inherit
|
||||
if (cattrs == null) {
|
||||
CattrInfo[] info = vm.conn.Type_GetFieldCustomAttributes (DeclaringType.Id, id, 0, false);
|
||||
cattrs = CustomAttributeDataMirror.Create (vm, info);
|
||||
}
|
||||
var res = new List<CustomAttributeDataMirror> ();
|
||||
foreach (var attr in cattrs)
|
||||
if (type == null || attr.Constructor.DeclaringType == type)
|
||||
res.Add (attr);
|
||||
return res.ToArray ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public interface IInvokeAsyncResult : IAsyncResult
|
||||
{
|
||||
void Abort ();
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Mono.Cecil.Cil;
|
||||
using Mono.Cecil.Metadata;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
/*
|
||||
* This is similar to the Instruction class in Cecil, we can't use that
|
||||
* as its constructor is internal.
|
||||
*/
|
||||
public class ILInstruction
|
||||
{
|
||||
int offset;
|
||||
OpCode opcode;
|
||||
object operand;
|
||||
ILInstruction prev, next;
|
||||
|
||||
internal ILInstruction (int offset, OpCode opcode, object operand) {
|
||||
this.offset = offset;
|
||||
this.opcode = opcode;
|
||||
this.operand = operand;
|
||||
}
|
||||
|
||||
public int Offset {
|
||||
get {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
public OpCode OpCode {
|
||||
get {
|
||||
return opcode;
|
||||
}
|
||||
}
|
||||
|
||||
public Object Operand {
|
||||
get {
|
||||
return operand;
|
||||
}
|
||||
set {
|
||||
operand = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ILInstruction Next {
|
||||
get {
|
||||
return next;
|
||||
}
|
||||
set {
|
||||
next = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ILInstruction Previous {
|
||||
get {
|
||||
return prev;
|
||||
}
|
||||
set {
|
||||
prev = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
/*
|
||||
* A Mirror represents a runtime object in the remote virtual machine. Calling
|
||||
* methods/properties of mirror objects potentially involves a remoting call,
|
||||
* which
|
||||
* has some overhead, and may also fail. Values of properties which are
|
||||
* constant (like Type.Name) are cached locally, so only the first call is
|
||||
* affected.
|
||||
* FIXME: Thread safety in the api ?
|
||||
*/
|
||||
public interface IMirror
|
||||
{
|
||||
VirtualMachine VirtualMachine {
|
||||
get;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public interface ITargetProcess
|
||||
{
|
||||
event System.EventHandler Exited;
|
||||
StreamReader StandardOutput { get; }
|
||||
StreamReader StandardError { get; }
|
||||
bool HasExited { get; }
|
||||
void Kill ();
|
||||
int Id { get; }
|
||||
string ProcessName { get; }
|
||||
}
|
||||
|
||||
internal class ProcessWrapper: ITargetProcess
|
||||
{
|
||||
Process process;
|
||||
|
||||
public ProcessWrapper (Process process)
|
||||
{
|
||||
this.process = process;
|
||||
}
|
||||
|
||||
public Process Process {
|
||||
get { return process; }
|
||||
}
|
||||
|
||||
public event System.EventHandler Exited {
|
||||
add { process.Exited += value; }
|
||||
remove { process.Exited -= value; }
|
||||
}
|
||||
|
||||
public StreamReader StandardOutput {
|
||||
get {
|
||||
return process.StandardOutput;
|
||||
}
|
||||
}
|
||||
|
||||
public StreamReader StandardError {
|
||||
get {
|
||||
return process.StandardError;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasExited {
|
||||
get {
|
||||
return process.HasExited;
|
||||
}
|
||||
}
|
||||
|
||||
public void Kill ()
|
||||
{
|
||||
process.Kill ();
|
||||
}
|
||||
|
||||
public int Id {
|
||||
get {
|
||||
return process.Id;
|
||||
}
|
||||
}
|
||||
|
||||
public string ProcessName {
|
||||
get {
|
||||
return process.ProcessName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class InvalidStackFrameException : Exception {
|
||||
|
||||
public InvalidStackFrameException () : base ("The requested operation cannot be completed because the specified stack frame is no longer valid.") {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class InvocationException : Exception {
|
||||
|
||||
ObjectMirror exception;
|
||||
|
||||
public InvocationException (ObjectMirror exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
public ObjectMirror Exception {
|
||||
get {
|
||||
return exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
[Flags]
|
||||
public enum InvokeOptions {
|
||||
None = 0,
|
||||
/*
|
||||
* Disable breakpoints on the thread doing the invoke
|
||||
*/
|
||||
DisableBreakpoints = 1,
|
||||
/*
|
||||
* Only resume the target thread during the invoke
|
||||
*/
|
||||
SingleThreaded = 2
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class LocalVariable : Mirror {
|
||||
|
||||
MethodMirror method;
|
||||
string name;
|
||||
int index;
|
||||
long type_id;
|
||||
TypeMirror t;
|
||||
bool is_arg;
|
||||
int live_range_start, live_range_end;
|
||||
|
||||
internal LocalVariable (VirtualMachine vm, MethodMirror method, int index, long type_id, string name, int live_range_start, int live_range_end, bool is_arg) : base (vm, 0) {
|
||||
this.method = method;
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
this.type_id = type_id;
|
||||
this.is_arg = is_arg;
|
||||
this.live_range_start = live_range_start;
|
||||
this.live_range_end = live_range_end;
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public int Index {
|
||||
get {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
public TypeMirror Type {
|
||||
get {
|
||||
if (t == null)
|
||||
t = vm.GetType (type_id);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsArg {
|
||||
get {
|
||||
return is_arg;
|
||||
}
|
||||
}
|
||||
|
||||
public MethodMirror Method {
|
||||
get {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
internal int LiveRangeStart {
|
||||
get {
|
||||
return live_range_start;
|
||||
}
|
||||
}
|
||||
|
||||
internal int LiveRangeEnd {
|
||||
get {
|
||||
return live_range_end;
|
||||
}
|
||||
}
|
||||
|
||||
internal int GetValueIndex {
|
||||
get {
|
||||
if (IsArg)
|
||||
return (-Index) - 1;
|
||||
else
|
||||
return Index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class Location : Mirror
|
||||
{
|
||||
MethodMirror method;
|
||||
//long native_addr;
|
||||
int il_offset;
|
||||
string source_file;
|
||||
int line_number;
|
||||
//int column_number;
|
||||
|
||||
internal Location (VirtualMachine vm, MethodMirror method, long native_addr, int il_offset, string source_file, int line_number, int column_number) : base (vm, 0) {
|
||||
this.method = method;
|
||||
//this.native_addr = native_addr;
|
||||
this.il_offset = il_offset;
|
||||
this.source_file = source_file;
|
||||
this.line_number = line_number;
|
||||
//this.column_number = column_number;
|
||||
}
|
||||
|
||||
public MethodMirror Method {
|
||||
get {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
public int ILOffset {
|
||||
get {
|
||||
return il_offset;
|
||||
}
|
||||
}
|
||||
|
||||
public string SourceFile {
|
||||
get {
|
||||
return source_file;
|
||||
}
|
||||
}
|
||||
|
||||
public int LineNumber {
|
||||
get {
|
||||
return line_number;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString () {
|
||||
return String.Format ("{0}+0x{1:x} at {2}:{3}", Method.FullName, ILOffset, SourceFile, LineNumber);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Mono.Cecil.Cil;
|
||||
using Mono.Cecil.Metadata;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class MethodBodyMirror : Mirror
|
||||
{
|
||||
MethodMirror method;
|
||||
byte[] il;
|
||||
|
||||
internal MethodBodyMirror (VirtualMachine vm, MethodMirror method, byte[] il) : base (vm, 0) {
|
||||
this.method = method;
|
||||
this.il = il;
|
||||
}
|
||||
|
||||
public MethodMirror Method {
|
||||
get {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetILAsByteArray () {
|
||||
return il;
|
||||
}
|
||||
|
||||
public List<ILInstruction> Instructions {
|
||||
get {
|
||||
return ReadCilBody (new BinaryReader (new MemoryStream (il)), il.Length);
|
||||
}
|
||||
}
|
||||
|
||||
static bool opcodes_inited;
|
||||
|
||||
static OpCode [] OneByteOpCode = new OpCode [0xe0 + 1];
|
||||
static OpCode [] TwoBytesOpCode = new OpCode [0x1e + 1];
|
||||
|
||||
// Adapted from Cecil
|
||||
List<ILInstruction> ReadCilBody (BinaryReader br, int code_size)
|
||||
{
|
||||
long start = br.BaseStream.Position;
|
||||
ILInstruction last = null;
|
||||
//GenericContext context = new GenericContext (body.Method);
|
||||
List<ILInstruction> code = new List<ILInstruction> ();
|
||||
|
||||
var by_offset = new Dictionary<int, ILInstruction> ();
|
||||
|
||||
if (!opcodes_inited) {
|
||||
foreach (FieldInfo fi in typeof (OpCodes).GetFields (BindingFlags.Static|BindingFlags.Public)) {
|
||||
var val = (OpCode)fi.GetValue (null);
|
||||
|
||||
if (val.Op1 == 0xff)
|
||||
OneByteOpCode [val.Op2] = val;
|
||||
else
|
||||
TwoBytesOpCode [val.Op2] = val;
|
||||
}
|
||||
opcodes_inited = true;
|
||||
}
|
||||
|
||||
while (br.BaseStream.Position < start + code_size) {
|
||||
OpCode op;
|
||||
long offset = br.BaseStream.Position - start;
|
||||
int cursor = br.ReadByte ();
|
||||
int token;
|
||||
ResolvedToken t;
|
||||
|
||||
if (cursor == 0xfe)
|
||||
op = TwoBytesOpCode [br.ReadByte ()];
|
||||
else
|
||||
op = OneByteOpCode [cursor];
|
||||
|
||||
ILInstruction instr = new ILInstruction ((int)offset, op, null);
|
||||
|
||||
by_offset [instr.Offset] = instr;
|
||||
|
||||
switch (op.OperandType) {
|
||||
case OperandType.InlineNone :
|
||||
break;
|
||||
case OperandType.InlineSwitch :
|
||||
uint length = br.ReadUInt32 ();
|
||||
int [] branches = new int [length];
|
||||
int [] buf = new int [length];
|
||||
for (int i = 0; i < length; i++)
|
||||
buf [i] = br.ReadInt32 ();
|
||||
for (int i = 0; i < length; i++)
|
||||
branches [i] = Convert.ToInt32 (br.BaseStream.Position - start + buf [i]);
|
||||
instr.Operand = branches;
|
||||
break;
|
||||
case OperandType.ShortInlineBrTarget :
|
||||
sbyte sbrtgt = br.ReadSByte ();
|
||||
instr.Operand = Convert.ToInt32 (br.BaseStream.Position - start + sbrtgt);
|
||||
break;
|
||||
case OperandType.InlineBrTarget :
|
||||
int brtgt = br.ReadInt32 ();
|
||||
instr.Operand = Convert.ToInt32 (br.BaseStream.Position - start + brtgt);
|
||||
break;
|
||||
case OperandType.ShortInlineI :
|
||||
if (op == OpCodes.Ldc_I4_S)
|
||||
instr.Operand = br.ReadSByte ();
|
||||
else
|
||||
instr.Operand = br.ReadByte ();
|
||||
break;
|
||||
case OperandType.ShortInlineVar :
|
||||
br.ReadByte ();
|
||||
//instr.Operand = GetVariable (body, br.ReadByte ());
|
||||
break;
|
||||
case OperandType.ShortInlineParam :
|
||||
br.ReadByte ();
|
||||
//instr.Operand = GetParameter (body, br.ReadByte ());
|
||||
break;
|
||||
case OperandType.InlineSig :
|
||||
br.ReadInt32 ();
|
||||
//instr.Operand = GetCallSiteAt (br.ReadInt32 (), context);
|
||||
break;
|
||||
case OperandType.InlineI :
|
||||
br.ReadInt32 ();
|
||||
//instr.Operand = br.ReadInt32 ();
|
||||
break;
|
||||
case OperandType.InlineVar :
|
||||
br.ReadInt16 ();
|
||||
//instr.Operand = GetVariable (body, br.ReadInt16 ());
|
||||
break;
|
||||
case OperandType.InlineParam :
|
||||
br.ReadInt16 ();
|
||||
//instr.Operand = GetParameter (body, br.ReadInt16 ());
|
||||
break;
|
||||
case OperandType.InlineI8 :
|
||||
instr.Operand = br.ReadInt64 ();
|
||||
break;
|
||||
case OperandType.ShortInlineR :
|
||||
instr.Operand = br.ReadSingle ();
|
||||
break;
|
||||
case OperandType.InlineR :
|
||||
instr.Operand = br.ReadDouble ();
|
||||
break;
|
||||
case OperandType.InlineString :
|
||||
token = br.ReadInt32 ();
|
||||
t = vm.conn.Method_ResolveToken (Method.Id, token);
|
||||
if (t.Type == TokenType.STRING)
|
||||
instr.Operand = t.Str;
|
||||
break;
|
||||
case OperandType.InlineField :
|
||||
case OperandType.InlineMethod :
|
||||
case OperandType.InlineType :
|
||||
case OperandType.InlineTok :
|
||||
token = br.ReadInt32 ();
|
||||
|
||||
t = vm.conn.Method_ResolveToken (Method.Id, token);
|
||||
|
||||
switch (t.Type) {
|
||||
case TokenType.TYPE:
|
||||
instr.Operand = vm.GetType (t.Id);
|
||||
break;
|
||||
case TokenType.FIELD:
|
||||
// FIXME: No vm.GetField ()
|
||||
//instr.Operand = vm.GetField (t.Id);
|
||||
break;
|
||||
case TokenType.METHOD:
|
||||
instr.Operand = vm.GetMethod (t.Id);
|
||||
break;
|
||||
case TokenType.UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException ("Unknown token type: " + t.Type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (last != null) {
|
||||
last.Next = instr;
|
||||
instr.Previous = last;
|
||||
}
|
||||
|
||||
last = instr;
|
||||
|
||||
code.Add (instr);
|
||||
}
|
||||
|
||||
// resolve branches
|
||||
foreach (ILInstruction i in code) {
|
||||
switch (i.OpCode.OperandType) {
|
||||
case OperandType.ShortInlineBrTarget:
|
||||
case OperandType.InlineBrTarget:
|
||||
i.Operand = by_offset [(int)i.Operand];
|
||||
break;
|
||||
case OperandType.InlineSwitch:
|
||||
int [] lbls = (int []) i.Operand;
|
||||
ILInstruction [] instrs = new ILInstruction [lbls.Length];
|
||||
for (int j = 0; j < lbls.Length; j++)
|
||||
instrs [j] = by_offset [lbls [j]];
|
||||
i.Operand = instrs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class MethodEntryEvent : Event {
|
||||
MethodMirror method;
|
||||
long id;
|
||||
|
||||
internal MethodEntryEvent (VirtualMachine vm, int req_id, long thread_id, long id) : base (EventType.MethodEntry, vm, req_id, thread_id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public MethodMirror Method {
|
||||
get {
|
||||
if (method == null)
|
||||
method = vm.GetMethod (id);
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public sealed class MethodEntryEventRequest : EventRequest {
|
||||
|
||||
internal MethodEntryEventRequest (VirtualMachine vm) : base (vm, EventType.MethodEntry) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class MethodExitEvent : Event {
|
||||
MethodMirror method;
|
||||
long id;
|
||||
|
||||
internal MethodExitEvent (VirtualMachine vm, int req_id, long thread_id, long id) : base (EventType.MethodExit, vm, req_id, thread_id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public MethodMirror Method {
|
||||
get {
|
||||
if (method == null)
|
||||
method = vm.GetMethod (id);
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public sealed class MethodExitEventRequest : EventRequest {
|
||||
|
||||
internal MethodExitEventRequest (VirtualMachine vm) : base (vm, EventType.MethodExit) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,290 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using C = Mono.Cecil;
|
||||
using Mono.Cecil.Metadata;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class MethodMirror : Mirror
|
||||
{
|
||||
string name;
|
||||
MethodInfo info;
|
||||
TypeMirror declaring_type;
|
||||
DebugInfo debug_info;
|
||||
C.MethodDefinition meta;
|
||||
ParameterInfoMirror[] param_info;
|
||||
ParameterInfoMirror ret_param;
|
||||
LocalVariable[] locals;
|
||||
IList<Location> locations;
|
||||
MethodBodyMirror body;
|
||||
|
||||
internal MethodMirror (VirtualMachine vm, long id) : base (vm, id) {
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
if (name == null)
|
||||
name = vm.conn.Method_GetName (id);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public TypeMirror DeclaringType {
|
||||
get {
|
||||
if (declaring_type == null)
|
||||
declaring_type = vm.GetType (vm.conn.Method_GetDeclaringType (id));
|
||||
return declaring_type;
|
||||
}
|
||||
}
|
||||
|
||||
public TypeMirror ReturnType {
|
||||
get {
|
||||
return ReturnParameter.ParameterType;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME:
|
||||
public string FullName {
|
||||
get {
|
||||
string type_namespace = DeclaringType.Namespace;
|
||||
string type_name = DeclaringType.Name;
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
sb.Append (ReturnType.Name);
|
||||
sb.Append (' ');
|
||||
if (type_namespace == String.Empty)
|
||||
sb.Append (type_name + ":" + Name + " ()");
|
||||
else
|
||||
sb.Append (type_namespace + "." + type_name + ":" + Name + " ()");
|
||||
return sb.ToString ();
|
||||
}
|
||||
}
|
||||
|
||||
void GetInfo () {
|
||||
if (info == null)
|
||||
info = vm.conn.Method_GetInfo (id);
|
||||
}
|
||||
|
||||
public int MetadataToken {
|
||||
get {
|
||||
GetInfo ();
|
||||
return info.token;
|
||||
}
|
||||
}
|
||||
|
||||
public MethodAttributes Attributes {
|
||||
get {
|
||||
GetInfo ();
|
||||
return (MethodAttributes)info.attributes;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPublic {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
|
||||
}
|
||||
}
|
||||
public bool IsPrivate {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
|
||||
}
|
||||
}
|
||||
public bool IsFamily {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family;
|
||||
}
|
||||
}
|
||||
public bool IsAssembly {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly;
|
||||
}
|
||||
}
|
||||
public bool IsFamilyAndAssembly {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem;
|
||||
}
|
||||
}
|
||||
public bool IsFamilyOrAssembly {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;
|
||||
}
|
||||
}
|
||||
public bool IsStatic {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.Static) != 0;
|
||||
}
|
||||
}
|
||||
public bool IsFinal {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.Final) != 0;
|
||||
}
|
||||
}
|
||||
public bool IsVirtual {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.Virtual) != 0;
|
||||
}
|
||||
}
|
||||
public bool IsHideBySig {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.HideBySig) != 0;
|
||||
}
|
||||
}
|
||||
public bool IsAbstract {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.Abstract) != 0;
|
||||
}
|
||||
}
|
||||
public bool IsSpecialName {
|
||||
get {
|
||||
return (Attributes & MethodAttributes.SpecialName) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsConstructor {
|
||||
get {
|
||||
int attr = (int)Attributes;
|
||||
return ((attr & (int)MethodAttributes.RTSpecialName) != 0
|
||||
&& (Name == ".ctor"));
|
||||
}
|
||||
}
|
||||
|
||||
public ParameterInfoMirror[] GetParameters () {
|
||||
if (param_info == null) {
|
||||
var pi = vm.conn.Method_GetParamInfo (id);
|
||||
param_info = new ParameterInfoMirror [pi.param_count];
|
||||
// Return
|
||||
ret_param = new ParameterInfoMirror (this, -1, vm.GetType (pi.ret_type), null, ParameterAttributes.Retval);
|
||||
// FIXME: this
|
||||
// FIXME: Attributes
|
||||
for (int i = 0; i < pi.param_count; ++i) {
|
||||
param_info [i] = new ParameterInfoMirror (this, i, vm.GetType (pi.param_types [i]), pi.param_names [i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
return param_info;
|
||||
}
|
||||
|
||||
public ParameterInfoMirror ReturnParameter {
|
||||
get {
|
||||
if (ret_param == null)
|
||||
GetParameters ();
|
||||
return ret_param;
|
||||
}
|
||||
}
|
||||
|
||||
public LocalVariable[] GetLocals () {
|
||||
if (locals == null) {
|
||||
var li = vm.conn.Method_GetLocalsInfo (id);
|
||||
// Add the arguments as well
|
||||
var pi = vm.conn.Method_GetParamInfo (id);
|
||||
|
||||
locals = new LocalVariable [pi.param_count + li.names.Length];
|
||||
|
||||
for (int i = 0; i < pi.param_count; ++i)
|
||||
locals [i] = new LocalVariable (vm, this, i, pi.param_types [i], pi.param_names [i], -1, -1, true);
|
||||
|
||||
for (int i = 0; i < li.names.Length; ++i)
|
||||
locals [i + pi.param_count] = new LocalVariable (vm, this, i, li.types [i], li.names [i], li.live_range_start [i], li.live_range_end [i], false);
|
||||
}
|
||||
return locals;
|
||||
}
|
||||
|
||||
public LocalVariable GetLocal (string name) {
|
||||
if (name == null)
|
||||
throw new ArgumentNullException ("name");
|
||||
|
||||
GetLocals ();
|
||||
|
||||
LocalVariable res = null;
|
||||
for (int i = 0; i < locals.Length; ++i) {
|
||||
if (locals [i].Name == name) {
|
||||
if (res != null)
|
||||
throw new AmbiguousMatchException ("More that one local has the name '" + name + "'.");
|
||||
res = locals [i];
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public MethodBodyMirror GetMethodBody () {
|
||||
if (body == null) {
|
||||
MethodBodyInfo info = vm.conn.Method_GetBody (id);
|
||||
|
||||
body = new MethodBodyMirror (vm, this, info.il);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
public IList<int> ILOffsets {
|
||||
get {
|
||||
if (debug_info == null)
|
||||
debug_info = vm.conn.Method_GetDebugInfo (id);
|
||||
return Array.AsReadOnly (debug_info.il_offsets);
|
||||
}
|
||||
}
|
||||
|
||||
public IList<int> LineNumbers {
|
||||
get {
|
||||
if (debug_info == null)
|
||||
debug_info = vm.conn.Method_GetDebugInfo (id);
|
||||
return Array.AsReadOnly (debug_info.line_numbers);
|
||||
}
|
||||
}
|
||||
|
||||
public string SourceFile {
|
||||
get {
|
||||
if (debug_info == null)
|
||||
debug_info = vm.conn.Method_GetDebugInfo (id);
|
||||
return debug_info.filename;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<Location> Locations {
|
||||
get {
|
||||
if (locations == null) {
|
||||
var il_offsets = ILOffsets;
|
||||
var line_numbers = LineNumbers;
|
||||
IList<Location> res = new Location [ILOffsets.Count];
|
||||
for (int i = 0; i < il_offsets.Count; ++i)
|
||||
res [i] = new Location (vm, this, -1, il_offsets [i], SourceFile, line_numbers [i], 0);
|
||||
locations = res;
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
}
|
||||
|
||||
internal int il_offset_to_line_number (int il_offset) {
|
||||
if (debug_info == null)
|
||||
debug_info = vm.conn.Method_GetDebugInfo (id);
|
||||
|
||||
// FIXME: Optimize this
|
||||
for (int i = debug_info.il_offsets.Length - 1; i >= 0; --i) {
|
||||
if (debug_info.il_offsets [i] <= il_offset)
|
||||
return debug_info.line_numbers [i];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public Location LocationAtILOffset (int il_offset) {
|
||||
IList<Location> locs = Locations;
|
||||
|
||||
// FIXME: Optimize this
|
||||
for (int i = locs.Count - 1; i >= 0; --i) {
|
||||
if (locs [i].ILOffset <= il_offset)
|
||||
return locs [i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public C.MethodDefinition Metadata {
|
||||
get {
|
||||
if (meta == null)
|
||||
meta = (C.MethodDefinition)DeclaringType.Assembly.Metadata.MainModule.LookupByToken (new MetadataToken (MetadataToken));
|
||||
return meta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public abstract class Mirror : IMirror
|
||||
{
|
||||
protected VirtualMachine vm;
|
||||
protected long id; // The id used in the protocol
|
||||
|
||||
internal Mirror (VirtualMachine vm, long id) {
|
||||
this.vm = vm;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
internal Mirror () {
|
||||
}
|
||||
|
||||
public VirtualMachine VirtualMachine {
|
||||
get {
|
||||
return vm;
|
||||
}
|
||||
}
|
||||
|
||||
internal long Id {
|
||||
get {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
protected void SetVirtualMachine (VirtualMachine vm) {
|
||||
this.vm = vm;
|
||||
}
|
||||
|
||||
protected void CheckMirror (Mirror m) {
|
||||
if (vm != m.VirtualMachine)
|
||||
throw new VMMismatchException ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
using System;
|
||||
using Mono.Debugger;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class ModuleMirror : Mirror
|
||||
{
|
||||
ModuleInfo info;
|
||||
Guid guid;
|
||||
AssemblyMirror assembly;
|
||||
|
||||
internal ModuleMirror (VirtualMachine vm, long id) : base (vm, id) {
|
||||
}
|
||||
|
||||
void ReadInfo () {
|
||||
if (info == null)
|
||||
info = vm.conn.Module_GetInfo (id);
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
ReadInfo ();
|
||||
return info.Name;
|
||||
}
|
||||
}
|
||||
|
||||
public string ScopeName {
|
||||
get {
|
||||
ReadInfo ();
|
||||
return info.ScopeName;
|
||||
}
|
||||
}
|
||||
|
||||
public string FullyQualifiedName {
|
||||
get {
|
||||
ReadInfo ();
|
||||
return info.FQName;
|
||||
}
|
||||
}
|
||||
|
||||
public Guid ModuleVersionId {
|
||||
get {
|
||||
if (guid == Guid.Empty) {
|
||||
ReadInfo ();
|
||||
guid = new Guid (info.Guid);
|
||||
}
|
||||
return guid;
|
||||
}
|
||||
}
|
||||
|
||||
public AssemblyMirror Assembly {
|
||||
get {
|
||||
if (assembly == null) {
|
||||
ReadInfo ();
|
||||
if (info.Assembly == 0)
|
||||
return null;
|
||||
assembly = vm.GetAssembly (info.Assembly);
|
||||
}
|
||||
return assembly;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Add function to query the guid, check in Metadata
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class ObjectCollectedException : Exception {
|
||||
|
||||
public ObjectCollectedException () : base ("The requested operation cannot be completed because the object has been garbage collected.") {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,259 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Threading;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class ObjectMirror : Value {
|
||||
|
||||
internal ObjectMirror (VirtualMachine vm, long id) : base (vm, id) {
|
||||
}
|
||||
|
||||
public TypeMirror Type {
|
||||
get {
|
||||
return vm.GetType (vm.conn.Object_GetType (id));
|
||||
}
|
||||
}
|
||||
|
||||
public AppDomainMirror Domain {
|
||||
get {
|
||||
return vm.GetDomain (vm.conn.Object_GetDomain (id));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCollected {
|
||||
get {
|
||||
return vm.conn.Object_IsCollected (id);
|
||||
}
|
||||
}
|
||||
|
||||
public Value GetValue (FieldInfoMirror field) {
|
||||
return GetValues (new FieldInfoMirror [] { field }) [0];
|
||||
}
|
||||
|
||||
public Value[] GetValues (IList<FieldInfoMirror> fields) {
|
||||
if (fields == null)
|
||||
throw new ArgumentNullException ("fields");
|
||||
foreach (FieldInfoMirror f in fields) {
|
||||
if (f == null)
|
||||
throw new ArgumentNullException ("field");
|
||||
CheckMirror (f);
|
||||
}
|
||||
long[] ids = new long [fields.Count];
|
||||
for (int i = 0; i < fields.Count; ++i)
|
||||
ids [i] = fields [i].Id;
|
||||
try {
|
||||
return vm.DecodeValues (vm.conn.Object_GetValues (id, ids));
|
||||
} catch (CommandException ex) {
|
||||
if (ex.ErrorCode == ErrorCode.INVALID_FIELDID)
|
||||
throw new ArgumentException ("One of the fields is not valid for this type.", "fields");
|
||||
else
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetValues (IList<FieldInfoMirror> fields, Value[] values) {
|
||||
if (fields == null)
|
||||
throw new ArgumentNullException ("fields");
|
||||
if (values == null)
|
||||
throw new ArgumentNullException ("values");
|
||||
foreach (FieldInfoMirror f in fields) {
|
||||
if (f == null)
|
||||
throw new ArgumentNullException ("field");
|
||||
CheckMirror (f);
|
||||
}
|
||||
foreach (Value v in values) {
|
||||
if (v == null)
|
||||
throw new ArgumentNullException ("values");
|
||||
CheckMirror (v);
|
||||
}
|
||||
long[] ids = new long [fields.Count];
|
||||
for (int i = 0; i < fields.Count; ++i)
|
||||
ids [i] = fields [i].Id;
|
||||
try {
|
||||
vm.conn.Object_SetValues (id, ids, vm.EncodeValues (values));
|
||||
} catch (CommandException ex) {
|
||||
if (ex.ErrorCode == ErrorCode.INVALID_FIELDID)
|
||||
throw new ArgumentException ("One of the fields is not valid for this type.", "fields");
|
||||
else if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
|
||||
throw new ArgumentException ("One of the values is not valid for its field.", "values");
|
||||
else
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetValue (FieldInfoMirror field, Value value) {
|
||||
SetValues (new FieldInfoMirror [] { field }, new Value [] { value });
|
||||
}
|
||||
|
||||
/*
|
||||
* The current address of the object. It can change during garbage
|
||||
* collections. Use a long since the debuggee might have a different
|
||||
* pointer size.
|
||||
*/
|
||||
public long Address {
|
||||
get {
|
||||
return vm.conn.Object_GetAddress (id);
|
||||
}
|
||||
}
|
||||
|
||||
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments) {
|
||||
return InvokeMethod (vm, thread, method, this, arguments, InvokeOptions.None);
|
||||
}
|
||||
|
||||
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options) {
|
||||
return InvokeMethod (vm, thread, method, this, arguments, options);
|
||||
}
|
||||
|
||||
[Obsolete ("Use the overload without the 'vm' argument")]
|
||||
public IAsyncResult BeginInvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
|
||||
return BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginInvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
|
||||
return BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
|
||||
}
|
||||
|
||||
public Value EndInvokeMethod (IAsyncResult asyncResult) {
|
||||
return EndInvokeMethodInternal (asyncResult);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common implementation for invokes
|
||||
*/
|
||||
|
||||
class InvokeAsyncResult : IInvokeAsyncResult {
|
||||
|
||||
public object AsyncState {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public WaitHandle AsyncWaitHandle {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public bool CompletedSynchronously {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCompleted {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public AsyncCallback Callback {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public ErrorCode ErrorCode {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public VirtualMachine VM {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public ThreadMirror Thread {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public ValueImpl Value {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public ValueImpl Exception {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public int ID {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public void Abort ()
|
||||
{
|
||||
if (ID == 0) // Ooops
|
||||
return;
|
||||
|
||||
ObjectMirror.AbortInvoke (VM, Thread, ID);
|
||||
}
|
||||
}
|
||||
|
||||
internal static IInvokeAsyncResult BeginInvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
|
||||
if (thread == null)
|
||||
throw new ArgumentNullException ("thread");
|
||||
if (method == null)
|
||||
throw new ArgumentNullException ("method");
|
||||
if (arguments == null)
|
||||
arguments = new Value [0];
|
||||
|
||||
InvokeFlags f = InvokeFlags.NONE;
|
||||
|
||||
if ((options & InvokeOptions.DisableBreakpoints) != 0)
|
||||
f |= InvokeFlags.DISABLE_BREAKPOINTS;
|
||||
if ((options & InvokeOptions.SingleThreaded) != 0)
|
||||
f |= InvokeFlags.SINGLE_THREADED;
|
||||
|
||||
InvokeAsyncResult r = new InvokeAsyncResult { AsyncState = state, AsyncWaitHandle = new ManualResetEvent (false), VM = vm, Thread = thread, Callback = callback };
|
||||
|
||||
r.ID = vm.conn.VM_BeginInvokeMethod (thread.Id, method.Id, this_obj != null ? vm.EncodeValue (this_obj) : vm.EncodeValue (vm.CreateValue (null)), vm.EncodeValues (arguments), f, InvokeCB, r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// This is called when the result of an invoke is received
|
||||
static void InvokeCB (ValueImpl v, ValueImpl exc, ErrorCode error, object state) {
|
||||
InvokeAsyncResult r = (InvokeAsyncResult)state;
|
||||
|
||||
if (error != 0) {
|
||||
r.ErrorCode = error;
|
||||
} else {
|
||||
r.Value = v;
|
||||
r.Exception = exc;
|
||||
}
|
||||
|
||||
r.IsCompleted = true;
|
||||
((ManualResetEvent)r.AsyncWaitHandle).Set ();
|
||||
|
||||
if (r.Callback != null)
|
||||
r.Callback.BeginInvoke (r, null, null);
|
||||
}
|
||||
|
||||
internal static Value EndInvokeMethodInternal (IAsyncResult asyncResult) {
|
||||
if (asyncResult == null)
|
||||
throw new ArgumentNullException ("asyncResult");
|
||||
|
||||
InvokeAsyncResult r = (InvokeAsyncResult)asyncResult;
|
||||
|
||||
if (!r.IsCompleted)
|
||||
r.AsyncWaitHandle.WaitOne ();
|
||||
|
||||
if (r.ErrorCode != 0) {
|
||||
try {
|
||||
r.VM.ErrorHandler (null, new ErrorHandlerEventArgs () { ErrorCode = r.ErrorCode });
|
||||
} catch (CommandException ex) {
|
||||
if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
|
||||
throw new ArgumentException ("Incorrect number or types of arguments", "arguments");
|
||||
else
|
||||
throw;
|
||||
}
|
||||
throw new NotImplementedException ();
|
||||
} else {
|
||||
if (r.Exception != null)
|
||||
throw new InvocationException ((ObjectMirror)r.VM.DecodeValue (r.Exception));
|
||||
else
|
||||
return r.VM.DecodeValue (r.Value);
|
||||
}
|
||||
}
|
||||
|
||||
internal static Value InvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options) {
|
||||
return EndInvokeMethodInternal (BeginInvokeMethod (vm, thread, method, this_obj, arguments, options, null, null));
|
||||
}
|
||||
|
||||
internal static void AbortInvoke (VirtualMachine vm, ThreadMirror thread, int id)
|
||||
{
|
||||
vm.conn.VM_AbortInvoke (thread.Id, id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class ParameterInfoMirror : Mirror {
|
||||
|
||||
MethodMirror method;
|
||||
TypeMirror type;
|
||||
string name;
|
||||
int pos;
|
||||
ParameterAttributes attrs;
|
||||
|
||||
internal ParameterInfoMirror (MethodMirror method, int pos, TypeMirror type, string name, ParameterAttributes attrs) : base (method.VirtualMachine, 0) {
|
||||
this.method = method;
|
||||
this.pos = pos;
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.attrs = attrs;
|
||||
}
|
||||
|
||||
public TypeMirror ParameterType {
|
||||
get {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
public MethodMirror Method {
|
||||
get {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public int Position {
|
||||
get {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
public ParameterAttributes Attributes {
|
||||
get {
|
||||
return attrs;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRetval {
|
||||
get {
|
||||
return (Attributes & ParameterAttributes.Retval) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString () {
|
||||
return String.Format ("ParameterInfo ({0})", Name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
/*
|
||||
* Represents a value of a primitive type in the debuggee
|
||||
*/
|
||||
public class PrimitiveValue : Value {
|
||||
|
||||
object value;
|
||||
|
||||
public PrimitiveValue (VirtualMachine vm, object value) : base (vm, 0) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public object Value {
|
||||
get {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals (object obj) {
|
||||
if (value == obj)
|
||||
return true;
|
||||
if (obj != null && obj is PrimitiveValue)
|
||||
return value == (obj as PrimitiveValue).Value;
|
||||
return base.Equals (obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode () {
|
||||
return base.GetHashCode ();
|
||||
}
|
||||
|
||||
public override string ToString () {
|
||||
return "PrimitiveValue<" + Value + ">";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using C = Mono.Cecil;
|
||||
using Mono.Cecil.Metadata;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class PropertyInfoMirror : Mirror {
|
||||
|
||||
TypeMirror parent;
|
||||
string name;
|
||||
PropertyAttributes attrs;
|
||||
MethodMirror get_method, set_method;
|
||||
CustomAttributeDataMirror[] cattrs;
|
||||
|
||||
public PropertyInfoMirror (TypeMirror parent, long id, string name, MethodMirror get_method, MethodMirror set_method, PropertyAttributes attrs) : base (parent.VirtualMachine, id) {
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
this.attrs = attrs;
|
||||
this.get_method = get_method;
|
||||
this.set_method = set_method;
|
||||
}
|
||||
|
||||
public TypeMirror DeclaringType {
|
||||
get {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public TypeMirror PropertyType {
|
||||
get {
|
||||
if (get_method != null)
|
||||
return get_method.ReturnType;
|
||||
else {
|
||||
ParameterInfoMirror[] parameters = set_method.GetParameters ();
|
||||
|
||||
return parameters [parameters.Length - 1].ParameterType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PropertyAttributes Attributes {
|
||||
get {
|
||||
return attrs;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSpecialName {
|
||||
get {return (Attributes & PropertyAttributes.SpecialName) != 0;}
|
||||
}
|
||||
|
||||
public MethodMirror GetGetMethod ()
|
||||
{
|
||||
return GetGetMethod (false);
|
||||
}
|
||||
|
||||
public MethodMirror GetGetMethod (bool nonPublic)
|
||||
{
|
||||
if (get_method != null && (nonPublic || get_method.IsPublic))
|
||||
return get_method;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public MethodMirror GetSetMethod ()
|
||||
{
|
||||
return GetSetMethod (false);
|
||||
}
|
||||
|
||||
public MethodMirror GetSetMethod (bool nonPublic)
|
||||
{
|
||||
if (set_method != null && (nonPublic || set_method.IsPublic))
|
||||
return set_method;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public ParameterInfoMirror[] GetIndexParameters()
|
||||
{
|
||||
if (get_method != null)
|
||||
return get_method.GetParameters ();
|
||||
return new ParameterInfoMirror [0];
|
||||
}
|
||||
|
||||
public CustomAttributeDataMirror[] GetCustomAttributes (bool inherit) {
|
||||
return GetCAttrs (null, inherit);
|
||||
}
|
||||
|
||||
public CustomAttributeDataMirror[] GetCustomAttributes (TypeMirror attributeType, bool inherit) {
|
||||
if (attributeType == null)
|
||||
throw new ArgumentNullException ("attributeType");
|
||||
return GetCAttrs (attributeType, inherit);
|
||||
}
|
||||
|
||||
CustomAttributeDataMirror[] GetCAttrs (TypeMirror type, bool inherit) {
|
||||
// FIXME: Handle inherit
|
||||
if (cattrs == null) {
|
||||
CattrInfo[] info = vm.conn.Type_GetPropertyCustomAttributes (DeclaringType.Id, id, 0, false);
|
||||
cattrs = CustomAttributeDataMirror.Create (vm, info);
|
||||
}
|
||||
var res = new List<CustomAttributeDataMirror> ();
|
||||
foreach (var attr in cattrs)
|
||||
if (type == null || attr.Constructor.DeclaringType == type)
|
||||
res.Add (attr);
|
||||
return res.ToArray ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,189 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class StackFrame : Mirror
|
||||
{
|
||||
ThreadMirror thread;
|
||||
MethodMirror method;
|
||||
int il_offset;
|
||||
Location location;
|
||||
StackFrameFlags flags;
|
||||
|
||||
/*
|
||||
* FIXME: Decide on the way to request/handle debugging information:
|
||||
* - request the info in bulk for all frames/on demand for individual frames
|
||||
* - request the info from the runtime/request only the il offset, and compute
|
||||
* everything else based on this info using the method debug info.
|
||||
*/
|
||||
|
||||
internal StackFrame (VirtualMachine vm, long id, ThreadMirror thread, MethodMirror method, int il_offset, StackFrameFlags flags) : base (vm, id) {
|
||||
this.thread = thread;
|
||||
this.method = method;
|
||||
this.il_offset = il_offset;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public ThreadMirror Thread {
|
||||
get {
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
public MethodMirror Method {
|
||||
get {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
public Location Location {
|
||||
get {
|
||||
if (location == null) {
|
||||
int line_number;
|
||||
|
||||
if (il_offset == -1)
|
||||
line_number = -1;
|
||||
else
|
||||
line_number = method.il_offset_to_line_number (il_offset);
|
||||
|
||||
location = new Location (vm, Method, 0, il_offset, method.SourceFile, line_number, 0);
|
||||
}
|
||||
return location;
|
||||
}
|
||||
}
|
||||
|
||||
public string FileName {
|
||||
get {
|
||||
return Location.SourceFile;
|
||||
}
|
||||
}
|
||||
|
||||
public int ILOffset {
|
||||
get {
|
||||
return Location.ILOffset;
|
||||
}
|
||||
}
|
||||
|
||||
public int LineNumber {
|
||||
get {
|
||||
return Location.LineNumber;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDebuggerInvoke {
|
||||
get {
|
||||
return (flags & StackFrameFlags.DEBUGGER_INVOKE) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public Value GetValue (ParameterInfoMirror param) {
|
||||
if (param == null)
|
||||
throw new ArgumentNullException ("param");
|
||||
if (param.Method != Method)
|
||||
throw new ArgumentException ("Parameter doesn't belong to this frame's method.");
|
||||
if (param.IsRetval)
|
||||
throw new ArgumentException ("Parameter represents the method return value.");
|
||||
|
||||
// FIXME: Liveness
|
||||
// FIXME: Allow returning the frame return value if possible
|
||||
return vm.DecodeValue (vm.conn.StackFrame_GetValues (thread.Id, Id, new int [] { (- param.Position) - 1 })[0]);
|
||||
}
|
||||
|
||||
public Value GetValue (LocalVariable var) {
|
||||
if (var == null)
|
||||
throw new ArgumentNullException ("var");
|
||||
if (var.Method != Method)
|
||||
throw new ArgumentException ("Local variable doesn't belong to this frame's method.");
|
||||
|
||||
// FIXME: Liveness
|
||||
// FIXME: Check for return value
|
||||
// FIXME: Allow returning the frame return value if possible
|
||||
return vm.DecodeValue (vm.conn.StackFrame_GetValues (thread.Id, Id, new int [] { var.GetValueIndex } )[0]);
|
||||
}
|
||||
|
||||
public Value[] GetValues (LocalVariable[] vars) {
|
||||
if (vars == null)
|
||||
throw new ArgumentNullException ("vars");
|
||||
for (int i = 0; i < vars.Length; ++i) {
|
||||
if (vars [i] == null)
|
||||
throw new ArgumentNullException ("vars");
|
||||
if (vars [i].Method != Method)
|
||||
throw new ArgumentException ("Local variable doesn't belong to this frame's method.");
|
||||
}
|
||||
int[] pos = new int [vars.Length];
|
||||
for (int i = 0; i < vars.Length; ++i)
|
||||
pos [i] = vars [i].GetValueIndex;
|
||||
return vm.DecodeValues (vm.conn.StackFrame_GetValues (thread.Id, Id, pos));
|
||||
}
|
||||
|
||||
public Value GetArgument (int pos) {
|
||||
return GetValue (Method.GetParameters () [pos]);
|
||||
}
|
||||
|
||||
public Value GetThis () {
|
||||
return vm.DecodeValue (vm.conn.StackFrame_GetThis (thread.Id, Id));
|
||||
}
|
||||
|
||||
public void SetValue (LocalVariable var, Value value) {
|
||||
if (var == null)
|
||||
throw new ArgumentNullException ("var");
|
||||
if (var.Method != Method)
|
||||
throw new ArgumentException ("Local variable doesn't belong to this frame's method.");
|
||||
if (value == null)
|
||||
throw new ArgumentNullException ("value");
|
||||
CheckMirror (value);
|
||||
// FIXME: Liveness
|
||||
// FIXME: Check for return value
|
||||
try {
|
||||
vm.conn.StackFrame_SetValues (thread.Id, Id, new int [] { var.GetValueIndex }, new ValueImpl [] { vm.EncodeValue (value) });
|
||||
} catch (CommandException ex) {
|
||||
if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
|
||||
throw new ArgumentException ("Value does not match the type of the local variable.");
|
||||
else
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetValue (ParameterInfoMirror param, Value value) {
|
||||
if (param == null)
|
||||
throw new ArgumentNullException ("param");
|
||||
if (param.Method != Method)
|
||||
throw new ArgumentException ("Parameter doesn't belong to this frame's method.");
|
||||
if (param.IsRetval)
|
||||
throw new ArgumentException ("Parameter represents the method return value.");
|
||||
if (value == null)
|
||||
throw new ArgumentNullException ("value");
|
||||
CheckMirror (value);
|
||||
|
||||
// FIXME: Liveness
|
||||
// FIXME: Allow setting the frame return value if possible
|
||||
try {
|
||||
vm.conn.StackFrame_SetValues (thread.Id, Id, new int [] { (- param.Position) - 1 }, new ValueImpl [] { vm.EncodeValue (value) });
|
||||
} catch (CommandException ex) {
|
||||
if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
|
||||
throw new ArgumentException ("Value does not match the type of the variable.");
|
||||
else
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<LocalVariable> GetVisibleVariables () {
|
||||
if (Location.ILOffset == -1)
|
||||
throw new AbsentInformationException ();
|
||||
|
||||
return Method.GetLocals ().Where (l => l.LiveRangeStart <= location.ILOffset && l.LiveRangeEnd >= location.ILOffset).ToList ();
|
||||
}
|
||||
|
||||
public LocalVariable GetVisibleVariableByName (string name) {
|
||||
if (name == null)
|
||||
throw new ArgumentNullException ("name");
|
||||
|
||||
if (Location.ILOffset == -1)
|
||||
throw new AbsentInformationException ();
|
||||
|
||||
return Method.GetLocals ().Where (l => l.LiveRangeStart <= location.ILOffset && l.LiveRangeEnd >= location.ILOffset && l.Name == name).FirstOrDefault ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class StepEvent : Event {
|
||||
MethodMirror method;
|
||||
long id, loc;
|
||||
|
||||
internal StepEvent (VirtualMachine vm, int req_id, long thread_id, long id, long loc) : base (EventType.Step, vm, req_id, thread_id) {
|
||||
this.id = id;
|
||||
this.loc = loc;
|
||||
}
|
||||
|
||||
public MethodMirror Method {
|
||||
get {
|
||||
if (method == null)
|
||||
method = vm.GetMethod (id);
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
public long Location {
|
||||
get {
|
||||
return loc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public enum StepDepth {
|
||||
Into = 0,
|
||||
Over = 1,
|
||||
Out = 2
|
||||
}
|
||||
|
||||
public enum StepSize {
|
||||
Min = 0,
|
||||
Line = 1
|
||||
}
|
||||
|
||||
public sealed class StepEventRequest : EventRequest {
|
||||
|
||||
ThreadMirror step_thread;
|
||||
StepDepth depth;
|
||||
StepSize size;
|
||||
|
||||
internal StepEventRequest (VirtualMachine vm, ThreadMirror thread) : base (vm, EventType.Step) {
|
||||
if (thread == null)
|
||||
throw new ArgumentNullException ("thread");
|
||||
CheckMirror (vm, thread);
|
||||
this.step_thread = thread;
|
||||
Depth = StepDepth.Into;
|
||||
Size = StepSize.Min;
|
||||
}
|
||||
|
||||
public override void Enable () {
|
||||
var mods = new List <Modifier> ();
|
||||
mods.Add (new StepModifier () { Thread = step_thread.Id, Depth = (int)Depth, Size = (int)Size });
|
||||
SendReq (mods);
|
||||
}
|
||||
|
||||
public new ThreadMirror Thread {
|
||||
get {
|
||||
return step_thread;
|
||||
}
|
||||
}
|
||||
|
||||
public StepDepth Depth {
|
||||
get {
|
||||
return depth;
|
||||
}
|
||||
set {
|
||||
CheckDisabled ();
|
||||
depth = value;
|
||||
}
|
||||
}
|
||||
|
||||
public StepSize Size {
|
||||
get {
|
||||
return size;
|
||||
}
|
||||
set {
|
||||
CheckDisabled ();
|
||||
size = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class StringMirror : ObjectMirror {
|
||||
|
||||
internal StringMirror (VirtualMachine vm, long id) : base (vm, id) {
|
||||
}
|
||||
|
||||
public string Value {
|
||||
get {
|
||||
return vm.conn.String_GetValue (id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
/*
|
||||
* Represents a valuetype value in the debuggee
|
||||
*/
|
||||
public class StructMirror : Value {
|
||||
|
||||
TypeMirror type;
|
||||
Value[] fields;
|
||||
|
||||
internal StructMirror (VirtualMachine vm, TypeMirror type, Value[] fields) : base (vm, 0) {
|
||||
this.type = type;
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
public TypeMirror Type {
|
||||
get {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
public Value[] Fields {
|
||||
get {
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
|
||||
public Value this [String field] {
|
||||
get {
|
||||
FieldInfoMirror[] field_info = Type.GetFields ();
|
||||
int nf = 0;
|
||||
for (int i = 0; i < field_info.Length; ++i) {
|
||||
if (!field_info [i].IsStatic) {
|
||||
if (field_info [i].Name == field)
|
||||
return Fields [nf];
|
||||
nf++;
|
||||
}
|
||||
}
|
||||
throw new ArgumentException ("Unknown struct field '" + field + "'.", "field");
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetField (int index, Value value) {
|
||||
fields [index] = value;
|
||||
}
|
||||
|
||||
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments) {
|
||||
return ObjectMirror.InvokeMethod (vm, thread, method, this, arguments, InvokeOptions.None);
|
||||
}
|
||||
|
||||
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options) {
|
||||
return ObjectMirror.InvokeMethod (vm, thread, method, this, arguments, options);
|
||||
}
|
||||
|
||||
[Obsolete ("Use the overload without the 'vm' argument")]
|
||||
public IAsyncResult BeginInvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
|
||||
return ObjectMirror.BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginInvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
|
||||
return ObjectMirror.BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
|
||||
}
|
||||
|
||||
public Value EndInvokeMethod (IAsyncResult asyncResult) {
|
||||
return ObjectMirror.EndInvokeMethodInternal (asyncResult);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
// Keep it in sync with debugger-agent.h
|
||||
public enum SuspendPolicy {
|
||||
None = 0,
|
||||
EventThread = 1,
|
||||
All = 2
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class ThreadDeathEvent : Event {
|
||||
internal ThreadDeathEvent (VirtualMachine vm, int req_id, long id) : base (EventType.ThreadDeath, vm, req_id, id) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class ThreadMirror : ObjectMirror
|
||||
{
|
||||
string name;
|
||||
|
||||
internal ThreadMirror (VirtualMachine vm, long id) : base (vm, id) {
|
||||
}
|
||||
|
||||
// FIXME: Cache, invalidate when the thread/runtime is resumed
|
||||
public StackFrame[] GetFrames () {
|
||||
FrameInfo[] frame_info = vm.conn.Thread_GetFrameInfo (id, 0, -1);
|
||||
|
||||
StackFrame[] frames = new StackFrame [frame_info.Length];
|
||||
for (int i = 0; i < frame_info.Length; ++i) {
|
||||
FrameInfo info = (FrameInfo)frame_info [i];
|
||||
MethodMirror method = vm.GetMethod (info.method);
|
||||
frames [i] = new StackFrame (vm, info.id, this, method, info.il_offset, info.flags);
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
if (name == null)
|
||||
name = vm.conn.Thread_GetName (id);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public new long Id {
|
||||
get {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
public ThreadState ThreadState {
|
||||
get {
|
||||
return (ThreadState)vm.conn.Thread_GetState (id);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsThreadPoolThread {
|
||||
get {
|
||||
ThreadInfo info = vm.conn.Thread_GetInfo (id);
|
||||
|
||||
return info.is_thread_pool;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a unique identifier for this thread, multiple ThreadMirror objects
|
||||
* may have the same ThreadId because of appdomains.
|
||||
*/
|
||||
public long ThreadId {
|
||||
get {
|
||||
return vm.conn.Thread_GetId (id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class ThreadStartEvent : Event {
|
||||
internal ThreadStartEvent (VirtualMachine vm, int req_id, long id) : base (EventType.ThreadStart, vm, req_id, id) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class TypeLoadEvent : Event {
|
||||
TypeMirror type;
|
||||
long id;
|
||||
|
||||
internal TypeLoadEvent (VirtualMachine vm, int req_id, long thread_id, long id) : base (EventType.TypeLoad, vm, req_id, thread_id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public TypeMirror Type {
|
||||
get {
|
||||
if (type == null)
|
||||
type = vm.GetType (id);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,650 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using C = Mono.Cecil;
|
||||
using Mono.Cecil.Metadata;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
/*
|
||||
* Represents a type in the remote virtual machine.
|
||||
* It might be better to make this a subclass of Type, but that could be
|
||||
* difficult as some of our methods like GetMethods () return Mirror objects.
|
||||
*/
|
||||
public class TypeMirror : Mirror
|
||||
{
|
||||
MethodMirror[] methods;
|
||||
AssemblyMirror ass;
|
||||
ModuleMirror module;
|
||||
C.TypeDefinition meta;
|
||||
FieldInfoMirror[] fields;
|
||||
PropertyInfoMirror[] properties;
|
||||
TypeInfo info;
|
||||
TypeMirror base_type, element_type;
|
||||
TypeMirror[] nested;
|
||||
CustomAttributeDataMirror[] cattrs;
|
||||
|
||||
internal const BindingFlags DefaultBindingFlags =
|
||||
BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
|
||||
|
||||
internal TypeMirror (VirtualMachine vm, long id) : base (vm, id) {
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
return GetInfo ().name;
|
||||
}
|
||||
}
|
||||
|
||||
public string Namespace {
|
||||
get {
|
||||
return GetInfo ().ns;
|
||||
}
|
||||
}
|
||||
|
||||
public AssemblyMirror Assembly {
|
||||
get {
|
||||
if (ass == null) {
|
||||
ass = vm.GetAssembly (GetInfo ().assembly);
|
||||
}
|
||||
return ass;
|
||||
}
|
||||
}
|
||||
|
||||
public ModuleMirror Module {
|
||||
get {
|
||||
if (module == null) {
|
||||
module = vm.GetModule (GetInfo ().module);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
}
|
||||
|
||||
public int MetadataToken {
|
||||
get {
|
||||
return GetInfo ().token;
|
||||
}
|
||||
}
|
||||
|
||||
public TypeAttributes Attributes {
|
||||
get {
|
||||
return (TypeAttributes)GetInfo ().attributes;
|
||||
}
|
||||
}
|
||||
|
||||
public TypeMirror BaseType {
|
||||
get {
|
||||
// FIXME: base_type could be null for object/interfaces
|
||||
if (base_type == null) {
|
||||
base_type = vm.GetType (GetInfo ().base_type);
|
||||
}
|
||||
return base_type;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetArrayRank () {
|
||||
GetInfo ();
|
||||
if (info.rank == 0)
|
||||
throw new ArgumentException ("Type must be an array type.");
|
||||
return info.rank;
|
||||
}
|
||||
|
||||
|
||||
public bool IsAbstract {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.Abstract) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAnsiClass {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.StringFormatMask)
|
||||
== TypeAttributes.AnsiClass;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsArray {
|
||||
get {
|
||||
return IsArrayImpl ();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAutoClass {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAutoLayout {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsByRef {
|
||||
get {
|
||||
return IsByRefImpl ();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsClass {
|
||||
get {
|
||||
if (IsInterface)
|
||||
return false;
|
||||
|
||||
return !IsValueType;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCOMObject {
|
||||
get {
|
||||
return IsCOMObjectImpl ();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsContextful {
|
||||
get {
|
||||
return IsContextfulImpl ();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEnum {
|
||||
get {
|
||||
return GetInfo ().is_enum;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsExplicitLayout {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsImport {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.Import) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsInterface {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsLayoutSequential {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsMarshalByRef {
|
||||
get {
|
||||
return IsMarshalByRefImpl ();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNestedAssembly {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNestedFamANDAssem {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNestedFamily {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNestedFamORAssem {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNestedPrivate {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNestedPublic {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNotPublic {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPointer {
|
||||
get {
|
||||
return IsPointerImpl ();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPrimitive {
|
||||
get {
|
||||
return IsPrimitiveImpl ();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPublic {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSealed {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.Sealed) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSerializable {
|
||||
get {
|
||||
if ((Attributes & TypeAttributes.Serializable) != 0)
|
||||
return true;
|
||||
|
||||
// FIXME:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSpecialName {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.SpecialName) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsUnicodeClass {
|
||||
get {
|
||||
return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValueType {
|
||||
get {
|
||||
return IsValueTypeImpl ();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasElementType {
|
||||
get {
|
||||
return HasElementTypeImpl ();
|
||||
}
|
||||
}
|
||||
|
||||
public TypeMirror GetElementType () {
|
||||
GetInfo ();
|
||||
if (element_type == null && info.element_type != 0)
|
||||
element_type = vm.GetType (info.element_type);
|
||||
return element_type;
|
||||
}
|
||||
|
||||
public string FullName {
|
||||
get {
|
||||
return GetInfo ().full_name;
|
||||
}
|
||||
}
|
||||
|
||||
public string CSharpName {
|
||||
get {
|
||||
if (IsArray) {
|
||||
if (GetArrayRank () == 1)
|
||||
return GetElementType ().CSharpName + "[]";
|
||||
else {
|
||||
string ranks = "";
|
||||
for (int i = 0; i < GetArrayRank (); ++i)
|
||||
ranks += ',';
|
||||
return GetElementType ().CSharpName + "[" + ranks + "]";
|
||||
}
|
||||
}
|
||||
if (IsPrimitive) {
|
||||
switch (Name) {
|
||||
case "Byte":
|
||||
return "byte";
|
||||
case "Int32":
|
||||
return "int";
|
||||
case "Boolean":
|
||||
return "bool";
|
||||
default:
|
||||
return FullName;
|
||||
}
|
||||
}
|
||||
// FIXME: Only do this for real corlib types
|
||||
if (Namespace == "System") {
|
||||
string s = Name;
|
||||
switch (s) {
|
||||
case "String":
|
||||
return "string";
|
||||
default:
|
||||
return FullName;
|
||||
}
|
||||
} else {
|
||||
return FullName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MethodMirror[] GetMethods () {
|
||||
if (methods == null) {
|
||||
long[] ids = vm.conn.Type_GetMethods (id);
|
||||
MethodMirror[] m = new MethodMirror [ids.Length];
|
||||
for (int i = 0; i < ids.Length; ++i) {
|
||||
m [i] = vm.GetMethod (ids [i]);
|
||||
}
|
||||
methods = m;
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
// FIXME: Sync this with Type
|
||||
public MethodMirror GetMethod (string name) {
|
||||
foreach (var m in GetMethods ())
|
||||
if (m.Name == name)
|
||||
return m;
|
||||
return null;
|
||||
}
|
||||
|
||||
public FieldInfoMirror[] GetFields () {
|
||||
if (fields != null)
|
||||
return fields;
|
||||
|
||||
string[] names;
|
||||
long[] types;
|
||||
int[] attrs;
|
||||
long[] ids = vm.conn.Type_GetFields (id, out names, out types, out attrs);
|
||||
|
||||
FieldInfoMirror[] res = new FieldInfoMirror [ids.Length];
|
||||
for (int i = 0; i < res.Length; ++i)
|
||||
res [i] = new FieldInfoMirror (this, ids [i], names [i], vm.GetType (types [i]), (FieldAttributes)attrs [i]);
|
||||
|
||||
fields = res;
|
||||
return fields;
|
||||
}
|
||||
|
||||
public FieldInfoMirror GetField (string name) {
|
||||
if (name == null)
|
||||
throw new ArgumentNullException ("name");
|
||||
foreach (var f in GetFields ())
|
||||
if (f.Name == name)
|
||||
return f;
|
||||
return null;
|
||||
}
|
||||
|
||||
public TypeMirror[] GetNestedTypes ()
|
||||
{
|
||||
return GetNestedTypes (DefaultBindingFlags);
|
||||
}
|
||||
|
||||
public TypeMirror[] GetNestedTypes (BindingFlags bindingAttr) {
|
||||
if (nested != null)
|
||||
return nested;
|
||||
|
||||
// FIXME: bindingAttr
|
||||
GetInfo ();
|
||||
var arr = new TypeMirror [info.nested.Length];
|
||||
for (int i = 0; i < arr.Length; ++i)
|
||||
arr [i] = vm.GetType (info.nested [i]);
|
||||
nested = arr;
|
||||
|
||||
return nested;
|
||||
}
|
||||
|
||||
public PropertyInfoMirror[] GetProperties () {
|
||||
return GetProperties (DefaultBindingFlags);
|
||||
}
|
||||
|
||||
public PropertyInfoMirror[] GetProperties (BindingFlags bindingAttr) {
|
||||
if (properties != null)
|
||||
return properties;
|
||||
|
||||
PropInfo[] info = vm.conn.Type_GetProperties (id);
|
||||
|
||||
PropertyInfoMirror[] res = new PropertyInfoMirror [info.Length];
|
||||
for (int i = 0; i < res.Length; ++i)
|
||||
res [i] = new PropertyInfoMirror (this, info [i].id, info [i].name, vm.GetMethod (info [i].get_method), vm.GetMethod (info [i].set_method), (PropertyAttributes)info [i].attrs);
|
||||
|
||||
properties = res;
|
||||
return properties;
|
||||
}
|
||||
|
||||
public PropertyInfoMirror GetProperty (string name) {
|
||||
if (name == null)
|
||||
throw new ArgumentNullException ("name");
|
||||
foreach (var p in GetProperties ())
|
||||
if (p.Name == name)
|
||||
return p;
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual bool IsAssignableFrom (TypeMirror c) {
|
||||
if (c == null)
|
||||
throw new ArgumentNullException ("c");
|
||||
|
||||
CheckMirror (c);
|
||||
|
||||
// This is complex so do it in the debuggee
|
||||
return vm.conn.Type_IsAssignableFrom (id, c.Id);
|
||||
}
|
||||
|
||||
public Value GetValue (FieldInfoMirror field) {
|
||||
return GetValues (new FieldInfoMirror [] { field }) [0];
|
||||
}
|
||||
|
||||
public Value[] GetValues (IList<FieldInfoMirror> fields) {
|
||||
if (fields == null)
|
||||
throw new ArgumentNullException ("fields");
|
||||
foreach (FieldInfoMirror f in fields) {
|
||||
if (f == null)
|
||||
throw new ArgumentNullException ("field");
|
||||
CheckMirror (f);
|
||||
}
|
||||
long[] ids = new long [fields.Count];
|
||||
for (int i = 0; i < fields.Count; ++i)
|
||||
ids [i] = fields [i].Id;
|
||||
try {
|
||||
return vm.DecodeValues (vm.conn.Type_GetValues (id, ids));
|
||||
} catch (CommandException ex) {
|
||||
if (ex.ErrorCode == ErrorCode.INVALID_FIELDID)
|
||||
throw new ArgumentException ("One of the fields is not valid for this type.", "fields");
|
||||
else
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetValues (IList<FieldInfoMirror> fields, Value[] values) {
|
||||
if (fields == null)
|
||||
throw new ArgumentNullException ("fields");
|
||||
if (values == null)
|
||||
throw new ArgumentNullException ("values");
|
||||
foreach (FieldInfoMirror f in fields) {
|
||||
if (f == null)
|
||||
throw new ArgumentNullException ("field");
|
||||
CheckMirror (f);
|
||||
}
|
||||
foreach (Value v in values) {
|
||||
if (v == null)
|
||||
throw new ArgumentNullException ("values");
|
||||
CheckMirror (v);
|
||||
}
|
||||
long[] ids = new long [fields.Count];
|
||||
for (int i = 0; i < fields.Count; ++i)
|
||||
ids [i] = fields [i].Id;
|
||||
try {
|
||||
vm.conn.Type_SetValues (id, ids, vm.EncodeValues (values));
|
||||
} catch (CommandException ex) {
|
||||
if (ex.ErrorCode == ErrorCode.INVALID_FIELDID)
|
||||
throw new ArgumentException ("One of the fields is not valid for this type.", "fields");
|
||||
else
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetValue (FieldInfoMirror field, Value value) {
|
||||
SetValues (new FieldInfoMirror [] { field }, new Value [] { value });
|
||||
}
|
||||
|
||||
public ObjectMirror GetTypeObject () {
|
||||
return vm.GetObject (vm.conn.Type_GetObject (id));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a list of source files without path info, where methods of
|
||||
* this type are defined. Return an empty list if the information is not
|
||||
* available.
|
||||
* This can be used by a debugger to find out which types occur in a
|
||||
* given source file, to filter the list of methods whose locations
|
||||
* have to be checked when placing breakpoints.
|
||||
*/
|
||||
public string[] GetSourceFiles () {
|
||||
return GetSourceFiles (false);
|
||||
}
|
||||
|
||||
public string[] GetSourceFiles (bool return_full_paths) {
|
||||
return vm.conn.Type_GetSourceFiles (id, return_full_paths);
|
||||
}
|
||||
|
||||
public C.TypeDefinition Metadata {
|
||||
get {
|
||||
if (meta == null) {
|
||||
if (Assembly.Metadata == null || MetadataToken == 0)
|
||||
return null;
|
||||
meta = (C.TypeDefinition)Assembly.Metadata.MainModule.LookupByToken (new MetadataToken (MetadataToken));
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
}
|
||||
|
||||
TypeInfo GetInfo () {
|
||||
if (info == null)
|
||||
info = vm.conn.Type_GetInfo (id);
|
||||
return info;
|
||||
}
|
||||
|
||||
protected virtual TypeAttributes GetAttributeFlagsImpl () {
|
||||
return (TypeAttributes)GetInfo ().attributes;
|
||||
}
|
||||
|
||||
protected virtual bool HasElementTypeImpl () {
|
||||
return IsArray || IsByRef || IsPointer;
|
||||
}
|
||||
|
||||
protected virtual bool IsArrayImpl () {
|
||||
return GetInfo ().rank > 0;
|
||||
}
|
||||
|
||||
protected virtual bool IsByRefImpl () {
|
||||
return GetInfo ().is_byref;
|
||||
}
|
||||
|
||||
protected virtual bool IsCOMObjectImpl () {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool IsPointerImpl () {
|
||||
return GetInfo ().is_pointer;
|
||||
}
|
||||
|
||||
protected virtual bool IsPrimitiveImpl () {
|
||||
return GetInfo ().is_primitive;
|
||||
}
|
||||
|
||||
protected virtual bool IsValueTypeImpl ()
|
||||
{
|
||||
return GetInfo ().is_valuetype;
|
||||
}
|
||||
|
||||
protected virtual bool IsContextfulImpl ()
|
||||
{
|
||||
// FIXME:
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool IsMarshalByRefImpl ()
|
||||
{
|
||||
// FIXME:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Same as Enum.GetUnderlyingType ()
|
||||
public TypeMirror EnumUnderlyingType {
|
||||
get {
|
||||
if (!IsEnum)
|
||||
throw new ArgumentException ("Type is not an enum type.");
|
||||
foreach (FieldInfoMirror f in GetFields ()) {
|
||||
if (!f.IsStatic)
|
||||
return f.FieldType;
|
||||
}
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Creating the custom attributes themselves could modify the behavior of the
|
||||
* debuggee, so we return objects similar to the CustomAttributeData objects
|
||||
* used by the reflection-only functionality on .net.
|
||||
*/
|
||||
public CustomAttributeDataMirror[] GetCustomAttributes (bool inherit) {
|
||||
return GetCAttrs (null, inherit);
|
||||
}
|
||||
|
||||
public CustomAttributeDataMirror[] GetCustomAttributes (TypeMirror attributeType, bool inherit) {
|
||||
if (attributeType == null)
|
||||
throw new ArgumentNullException ("attributeType");
|
||||
return GetCAttrs (attributeType, inherit);
|
||||
}
|
||||
|
||||
CustomAttributeDataMirror[] GetCAttrs (TypeMirror type, bool inherit) {
|
||||
// FIXME: Handle inherit
|
||||
if (cattrs == null) {
|
||||
CattrInfo[] info = vm.conn.Type_GetCustomAttributes (id, 0, false);
|
||||
cattrs = CustomAttributeDataMirror.Create (vm, info);
|
||||
}
|
||||
var res = new List<CustomAttributeDataMirror> ();
|
||||
foreach (var attr in cattrs)
|
||||
if (type == null || attr.Constructor.DeclaringType == type)
|
||||
res.Add (attr);
|
||||
return res.ToArray ();
|
||||
}
|
||||
|
||||
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments) {
|
||||
return ObjectMirror.InvokeMethod (vm, thread, method, null, arguments, InvokeOptions.None);
|
||||
}
|
||||
|
||||
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options) {
|
||||
return ObjectMirror.InvokeMethod (vm, thread, method, null, arguments, options);
|
||||
}
|
||||
|
||||
[Obsolete ("Use the overload without the 'vm' argument")]
|
||||
public IAsyncResult BeginInvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
|
||||
return ObjectMirror.BeginInvokeMethod (vm, thread, method, null, arguments, options, callback, state);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginInvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
|
||||
return ObjectMirror.BeginInvokeMethod (vm, thread, method, null, arguments, options, callback, state);
|
||||
}
|
||||
|
||||
public Value EndInvokeMethod (IAsyncResult asyncResult) {
|
||||
return ObjectMirror.EndInvokeMethodInternal (asyncResult);
|
||||
}
|
||||
|
||||
public Value NewInstance (ThreadMirror thread, MethodMirror method, IList<Value> arguments) {
|
||||
return ObjectMirror.InvokeMethod (vm, thread, method, null, arguments, InvokeOptions.None);
|
||||
}
|
||||
|
||||
public Value NewInstance (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options) {
|
||||
return ObjectMirror.InvokeMethod (vm, thread, method, null, arguments, options);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class VMDeathEvent : Event
|
||||
{
|
||||
public VMDeathEvent (VirtualMachine vm, int req_id) : base (EventType.VMDeath, vm, req_id, -1) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class VMDisconnectEvent : Event
|
||||
{
|
||||
public VMDisconnectEvent (VirtualMachine vm, int req_id) : base (EventType.VMDisconnect, vm, req_id, -1) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class VMDisconnectedException : Exception {
|
||||
|
||||
public VMDisconnectedException () : base () {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class VMMismatchException : Exception
|
||||
{
|
||||
public VMMismatchException () : base () {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class VMStartEvent : Event
|
||||
{
|
||||
public VMStartEvent (VirtualMachine vm, int req_id, long thread_id) : base (EventType.VMStart, vm, req_id, thread_id) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public abstract class Value : Mirror {
|
||||
|
||||
// FIXME: Add a 'Value' field
|
||||
|
||||
internal Value (VirtualMachine vm, long id) : base (vm, id) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,574 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Net;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil.Metadata;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class VirtualMachine : Mirror
|
||||
{
|
||||
Queue queue;
|
||||
object queue_monitor;
|
||||
object startup_monitor;
|
||||
AppDomainMirror root_domain;
|
||||
Dictionary<int, EventRequest> requests;
|
||||
ITargetProcess process;
|
||||
|
||||
internal Connection conn;
|
||||
|
||||
VersionInfo version;
|
||||
|
||||
internal VirtualMachine (ITargetProcess process, Connection conn) : base () {
|
||||
SetVirtualMachine (this);
|
||||
queue = new Queue ();
|
||||
queue_monitor = new Object ();
|
||||
startup_monitor = new Object ();
|
||||
requests = new Dictionary <int, EventRequest> ();
|
||||
this.conn = conn;
|
||||
this.process = process;
|
||||
conn.ErrorHandler += ErrorHandler;
|
||||
}
|
||||
|
||||
// The standard output of the process is available normally through Process
|
||||
public StreamReader StandardOutput { get; set; }
|
||||
public StreamReader StandardError { get; set; }
|
||||
|
||||
|
||||
public Process Process {
|
||||
get {
|
||||
ProcessWrapper pw = process as ProcessWrapper;
|
||||
if (pw == null)
|
||||
throw new InvalidOperationException ("Process instance not available");
|
||||
return pw.Process;
|
||||
}
|
||||
}
|
||||
|
||||
public ITargetProcess TargetProcess {
|
||||
get {
|
||||
return process;
|
||||
}
|
||||
}
|
||||
|
||||
public AppDomainMirror RootDomain {
|
||||
get {
|
||||
return root_domain;
|
||||
}
|
||||
}
|
||||
|
||||
public EndPoint EndPoint {
|
||||
get {
|
||||
return conn.EndPoint;
|
||||
}
|
||||
}
|
||||
|
||||
public VersionInfo Version {
|
||||
get {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
public Event GetNextEvent () {
|
||||
lock (queue_monitor) {
|
||||
if (queue.Count == 0)
|
||||
Monitor.Wait (queue_monitor);
|
||||
return (Event)queue.Dequeue ();
|
||||
}
|
||||
}
|
||||
|
||||
public Event GetNextEvent (int timeout) {
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public T GetNextEvent<T> () where T : Event {
|
||||
return GetNextEvent () as T;
|
||||
}
|
||||
|
||||
public void Suspend () {
|
||||
conn.VM_Suspend ();
|
||||
}
|
||||
|
||||
public void Resume () {
|
||||
try {
|
||||
conn.VM_Resume ();
|
||||
} catch (CommandException ex) {
|
||||
if (ex.ErrorCode == ErrorCode.NOT_SUSPENDED)
|
||||
throw new InvalidOperationException ("The vm is not suspended.");
|
||||
else
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void Exit (int exitCode) {
|
||||
conn.VM_Exit (exitCode);
|
||||
}
|
||||
|
||||
public void Dispose () {
|
||||
conn.VM_Dispose ();
|
||||
conn.Close ();
|
||||
}
|
||||
|
||||
public IList<ThreadMirror> GetThreads () {
|
||||
long[] ids = vm.conn.VM_GetThreads ();
|
||||
ThreadMirror[] res = new ThreadMirror [ids.Length];
|
||||
for (int i = 0; i < ids.Length; ++i)
|
||||
res [i] = GetThread (ids [i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Same as the mirrorOf methods in JDI
|
||||
public PrimitiveValue CreateValue (object value) {
|
||||
if (value == null)
|
||||
return new PrimitiveValue (vm, null);
|
||||
|
||||
if (!value.GetType ().IsPrimitive)
|
||||
throw new ArgumentException ("value must be of a primitive type instead of '" + value.GetType () + "'", "value");
|
||||
|
||||
return new PrimitiveValue (vm, value);
|
||||
}
|
||||
|
||||
public EnumMirror CreateEnumMirror (TypeMirror type, PrimitiveValue value) {
|
||||
return new EnumMirror (this, type, value);
|
||||
}
|
||||
|
||||
//
|
||||
// Methods to create event request objects
|
||||
//
|
||||
public BreakpointEventRequest CreateBreakpointRequest (MethodMirror method, long il_offset) {
|
||||
return new BreakpointEventRequest (this, method, il_offset);
|
||||
}
|
||||
|
||||
public BreakpointEventRequest CreateBreakpointRequest (Location loc) {
|
||||
if (loc == null)
|
||||
throw new ArgumentNullException ("loc");
|
||||
CheckMirror (loc);
|
||||
return new BreakpointEventRequest (this, loc.Method, loc.ILOffset);
|
||||
}
|
||||
|
||||
public StepEventRequest CreateStepRequest (ThreadMirror thread) {
|
||||
return new StepEventRequest (this, thread);
|
||||
}
|
||||
|
||||
public MethodEntryEventRequest CreateMethodEntryRequest () {
|
||||
return new MethodEntryEventRequest (this);
|
||||
}
|
||||
|
||||
public MethodExitEventRequest CreateMethodExitRequest () {
|
||||
return new MethodExitEventRequest (this);
|
||||
}
|
||||
|
||||
public ExceptionEventRequest CreateExceptionRequest (TypeMirror exc_type) {
|
||||
return new ExceptionEventRequest (this, exc_type, true, true);
|
||||
}
|
||||
|
||||
public ExceptionEventRequest CreateExceptionRequest (TypeMirror exc_type, bool caught, bool uncaught) {
|
||||
return new ExceptionEventRequest (this, exc_type, caught, uncaught);
|
||||
}
|
||||
|
||||
public void EnableEvents (params EventType[] events) {
|
||||
foreach (EventType etype in events)
|
||||
conn.EnableEvent (etype, SuspendPolicy.All, null);
|
||||
}
|
||||
|
||||
public BreakpointEventRequest SetBreakpoint (MethodMirror method, long il_offset) {
|
||||
BreakpointEventRequest req = CreateBreakpointRequest (method, il_offset);
|
||||
|
||||
req.Enable ();
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
public void ClearAllBreakpoints () {
|
||||
conn.ClearAllBreakpoints ();
|
||||
}
|
||||
|
||||
public void Disconnect () {
|
||||
conn.Close ();
|
||||
}
|
||||
|
||||
internal void queue_event (Event e) {
|
||||
lock (queue_monitor) {
|
||||
queue.Enqueue (e);
|
||||
Monitor.Pulse (queue_monitor);
|
||||
}
|
||||
}
|
||||
|
||||
internal void ErrorHandler (object sender, ErrorHandlerEventArgs args) {
|
||||
switch (args.ErrorCode) {
|
||||
case ErrorCode.INVALID_OBJECT:
|
||||
throw new ObjectCollectedException ();
|
||||
case ErrorCode.INVALID_FRAMEID:
|
||||
throw new InvalidStackFrameException ();
|
||||
case ErrorCode.NOT_SUSPENDED:
|
||||
throw new InvalidOperationException ("The vm is not suspended.");
|
||||
case ErrorCode.NOT_IMPLEMENTED:
|
||||
throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
|
||||
case ErrorCode.ABSENT_INFORMATION:
|
||||
throw new AbsentInformationException ();
|
||||
default:
|
||||
throw new CommandException (args.ErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the debuggee to start up and connect to it */
|
||||
internal void connect () {
|
||||
conn.Connect ();
|
||||
|
||||
// Test the connection
|
||||
version = conn.Version;
|
||||
if (version.MajorVersion != Connection.MAJOR_VERSION)
|
||||
throw new NotSupportedException (String.Format ("The debuggee implements protocol version {0}.{1}, while {2}.{3} is required.", version.MajorVersion, version.MinorVersion, Connection.MAJOR_VERSION, Connection.MINOR_VERSION));
|
||||
|
||||
long root_domain_id = conn.RootDomain;
|
||||
root_domain = GetDomain (root_domain_id);
|
||||
}
|
||||
|
||||
internal void notify_vm_event (EventType evtype, int req_id, long thread_id, string vm_uri) {
|
||||
//Console.WriteLine ("Event: " + evtype + "(" + vm_uri + ")");
|
||||
|
||||
switch (evtype) {
|
||||
case EventType.VMStart:
|
||||
/* Notify the main thread that the debuggee started up */
|
||||
lock (startup_monitor) {
|
||||
Monitor.Pulse (startup_monitor);
|
||||
}
|
||||
queue_event (new VMStartEvent (vm, req_id, thread_id));
|
||||
break;
|
||||
case EventType.VMDeath:
|
||||
queue_event (new VMDeathEvent (vm, req_id));
|
||||
break;
|
||||
case EventType.VMDisconnect:
|
||||
queue_event (new VMDisconnectEvent (vm, req_id));
|
||||
break;
|
||||
default:
|
||||
throw new Exception ();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Methods to create instances of mirror objects
|
||||
//
|
||||
|
||||
/*
|
||||
class MirrorCache<T> {
|
||||
static Dictionary <long, T> mirrors;
|
||||
static object mirror_lock = new object ();
|
||||
|
||||
internal static T GetMirror (VirtualMachine vm, long id) {
|
||||
lock (mirror_lock) {
|
||||
if (mirrors == null)
|
||||
mirrors = new Dictionary <long, T> ();
|
||||
T obj;
|
||||
if (!mirrors.TryGetValue (id, out obj)) {
|
||||
obj = CreateMirror (vm, id);
|
||||
mirrors [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
internal static T CreateMirror (VirtualMachine vm, long id) {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// FIXME: When to remove items from the cache ?
|
||||
|
||||
Dictionary <long, MethodMirror> methods;
|
||||
object methods_lock = new object ();
|
||||
|
||||
internal MethodMirror GetMethod (long id) {
|
||||
lock (methods_lock) {
|
||||
if (methods == null)
|
||||
methods = new Dictionary <long, MethodMirror> ();
|
||||
MethodMirror obj;
|
||||
if (id == 0)
|
||||
return null;
|
||||
if (!methods.TryGetValue (id, out obj)) {
|
||||
obj = new MethodMirror (this, id);
|
||||
methods [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary <long, AssemblyMirror> assemblies;
|
||||
object assemblies_lock = new object ();
|
||||
|
||||
internal AssemblyMirror GetAssembly (long id) {
|
||||
lock (assemblies_lock) {
|
||||
if (assemblies == null)
|
||||
assemblies = new Dictionary <long, AssemblyMirror> ();
|
||||
AssemblyMirror obj;
|
||||
if (id == 0)
|
||||
return null;
|
||||
if (!assemblies.TryGetValue (id, out obj)) {
|
||||
obj = new AssemblyMirror (this, id);
|
||||
assemblies [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary <long, ModuleMirror> modules;
|
||||
object modules_lock = new object ();
|
||||
|
||||
internal ModuleMirror GetModule (long id) {
|
||||
lock (modules_lock) {
|
||||
if (modules == null)
|
||||
modules = new Dictionary <long, ModuleMirror> ();
|
||||
ModuleMirror obj;
|
||||
if (id == 0)
|
||||
return null;
|
||||
if (!modules.TryGetValue (id, out obj)) {
|
||||
obj = new ModuleMirror (this, id);
|
||||
modules [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary <long, AppDomainMirror> domains;
|
||||
object domains_lock = new object ();
|
||||
|
||||
internal AppDomainMirror GetDomain (long id) {
|
||||
lock (domains_lock) {
|
||||
if (domains == null)
|
||||
domains = new Dictionary <long, AppDomainMirror> ();
|
||||
AppDomainMirror obj;
|
||||
if (id == 0)
|
||||
return null;
|
||||
if (!domains.TryGetValue (id, out obj)) {
|
||||
obj = new AppDomainMirror (this, id);
|
||||
domains [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary <long, TypeMirror> types;
|
||||
object types_lock = new object ();
|
||||
|
||||
internal TypeMirror GetType (long id) {
|
||||
lock (types_lock) {
|
||||
if (types == null)
|
||||
types = new Dictionary <long, TypeMirror> ();
|
||||
TypeMirror obj;
|
||||
if (id == 0)
|
||||
return null;
|
||||
if (!types.TryGetValue (id, out obj)) {
|
||||
obj = new TypeMirror (this, id);
|
||||
types [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary <long, ObjectMirror> objects;
|
||||
object objects_lock = new object ();
|
||||
|
||||
internal T GetObject<T> (long id, long domain_id, long type_id) where T : ObjectMirror {
|
||||
lock (objects_lock) {
|
||||
if (objects == null)
|
||||
objects = new Dictionary <long, ObjectMirror> ();
|
||||
ObjectMirror obj;
|
||||
if (!objects.TryGetValue (id, out obj)) {
|
||||
/*
|
||||
* Obtain the domain/type of the object to determine the type of
|
||||
* object we need to create.
|
||||
*/
|
||||
if (domain_id == 0)
|
||||
domain_id = conn.Object_GetDomain (id);
|
||||
AppDomainMirror d = GetDomain (domain_id);
|
||||
|
||||
if (type_id == 0)
|
||||
type_id = conn.Object_GetType (id);
|
||||
TypeMirror t = GetType (type_id);
|
||||
|
||||
if (t.Assembly == d.Corlib && t.Namespace == "System.Threading" && t.Name == "Thread")
|
||||
obj = new ThreadMirror (this, id);
|
||||
else if (t.Assembly == d.Corlib && t.Namespace == "System" && t.Name == "String")
|
||||
obj = new StringMirror (this, id);
|
||||
else if (typeof (T) == typeof (ArrayMirror))
|
||||
obj = new ArrayMirror (this, id);
|
||||
else
|
||||
obj = new ObjectMirror (this, id);
|
||||
objects [id] = obj;
|
||||
}
|
||||
return (T)obj;
|
||||
}
|
||||
}
|
||||
|
||||
internal T GetObject<T> (long id) where T : ObjectMirror {
|
||||
return GetObject<T> (id, 0, 0);
|
||||
}
|
||||
|
||||
internal ObjectMirror GetObject (long objid) {
|
||||
return GetObject<ObjectMirror> (objid);
|
||||
}
|
||||
|
||||
internal ThreadMirror GetThread (long id) {
|
||||
return GetObject <ThreadMirror> (id);
|
||||
}
|
||||
|
||||
object requests_lock = new object ();
|
||||
|
||||
internal void AddRequest (EventRequest req, int id) {
|
||||
lock (requests_lock) {
|
||||
requests [id] = req;
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveRequest (EventRequest req, int id) {
|
||||
lock (requests_lock) {
|
||||
requests.Remove (id);
|
||||
}
|
||||
}
|
||||
|
||||
internal EventRequest GetRequest (int id) {
|
||||
lock (requests_lock) {
|
||||
return requests [id];
|
||||
}
|
||||
}
|
||||
|
||||
internal Value DecodeValue (ValueImpl v) {
|
||||
if (v.Value != null)
|
||||
return new PrimitiveValue (this, v.Value);
|
||||
|
||||
switch (v.Type) {
|
||||
case ElementType.Void:
|
||||
return null;
|
||||
case ElementType.SzArray:
|
||||
case ElementType.Array:
|
||||
return GetObject<ArrayMirror> (v.Objid);
|
||||
case ElementType.String:
|
||||
return GetObject<StringMirror> (v.Objid);
|
||||
case ElementType.Class:
|
||||
case ElementType.Object:
|
||||
return GetObject (v.Objid);
|
||||
case ElementType.ValueType:
|
||||
if (v.IsEnum)
|
||||
return new EnumMirror (this, GetType (v.Klass), DecodeValues (v.Fields));
|
||||
else
|
||||
return new StructMirror (this, GetType (v.Klass), DecodeValues (v.Fields));
|
||||
case (ElementType)ValueTypeId.VALUE_TYPE_ID_NULL:
|
||||
return new PrimitiveValue (this, null);
|
||||
default:
|
||||
throw new NotImplementedException ("" + v.Type);
|
||||
}
|
||||
}
|
||||
|
||||
internal Value[] DecodeValues (ValueImpl[] values) {
|
||||
Value[] res = new Value [values.Length];
|
||||
for (int i = 0; i < values.Length; ++i)
|
||||
res [i] = DecodeValue (values [i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
internal ValueImpl EncodeValue (Value v) {
|
||||
if (v is PrimitiveValue) {
|
||||
object val = (v as PrimitiveValue).Value;
|
||||
if (val == null)
|
||||
return new ValueImpl { Type = (ElementType)ValueTypeId.VALUE_TYPE_ID_NULL, Objid = 0 };
|
||||
else
|
||||
return new ValueImpl { Value = val };
|
||||
} else if (v is ObjectMirror) {
|
||||
return new ValueImpl { Type = ElementType.Object, Objid = (v as ObjectMirror).Id };
|
||||
} else if (v is StructMirror) {
|
||||
return new ValueImpl { Type = ElementType.ValueType, Klass = (v as StructMirror).Type.Id, Fields = EncodeValues ((v as StructMirror).Fields) };
|
||||
} else {
|
||||
throw new NotSupportedException ();
|
||||
}
|
||||
}
|
||||
|
||||
internal ValueImpl[] EncodeValues (IList<Value> values) {
|
||||
ValueImpl[] res = new ValueImpl [values.Count];
|
||||
for (int i = 0; i < values.Count; ++i)
|
||||
res [i] = EncodeValue (values [i]);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
class EventHandler : MarshalByRefObject, IEventHandler
|
||||
{
|
||||
VirtualMachine vm;
|
||||
|
||||
public EventHandler (VirtualMachine vm) {
|
||||
this.vm = vm;
|
||||
}
|
||||
|
||||
public void VMStart (int req_id, long thread_id, string vm_uri) {
|
||||
vm.notify_vm_event (EventType.VMStart, req_id, thread_id, vm_uri);
|
||||
}
|
||||
|
||||
public void VMDeath (int req_id, long thread_id, string vm_uri) {
|
||||
vm.notify_vm_event (EventType.VMDeath, req_id, thread_id, vm_uri);
|
||||
}
|
||||
|
||||
public void VMDisconnect (int req_id, long thread_id, string vm_uri) {
|
||||
vm.notify_vm_event (EventType.VMDisconnect, req_id, thread_id, vm_uri);
|
||||
}
|
||||
|
||||
public void ThreadStart (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new ThreadStartEvent (vm, req_id, id));
|
||||
}
|
||||
|
||||
public void ThreadDeath (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new ThreadDeathEvent (vm, req_id, id));
|
||||
}
|
||||
|
||||
public void AssemblyLoad (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new AssemblyLoadEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void AssemblyUnload (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new AssemblyUnloadEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void TypeLoad (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new TypeLoadEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void MethodEntry (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new MethodEntryEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void MethodExit (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new MethodExitEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void Breakpoint (int req_id, long thread_id, long id, long loc) {
|
||||
vm.queue_event (new BreakpointEvent (vm, req_id, thread_id, id, loc));
|
||||
}
|
||||
|
||||
public void Step (int req_id, long thread_id, long id, long loc) {
|
||||
vm.queue_event (new StepEvent (vm, req_id, thread_id, id, loc));
|
||||
}
|
||||
|
||||
public void Exception (int req_id, long thread_id, long id, long loc) {
|
||||
vm.queue_event (new ExceptionEvent (vm, req_id, thread_id, id, loc));
|
||||
}
|
||||
|
||||
public void AppDomainCreate (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new AppDomainCreateEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void AppDomainUnload (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new AppDomainUnloadEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
}
|
||||
|
||||
internal class CommandException : Exception {
|
||||
|
||||
public CommandException (ErrorCode error_code) : base ("Debuggee returned error code " + error_code + ".") {
|
||||
ErrorCode = error_code;
|
||||
}
|
||||
|
||||
public ErrorCode ErrorCode {
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,308 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
|
||||
namespace Mono.Debugger.Soft
|
||||
{
|
||||
public class LaunchOptions {
|
||||
public string AgentArgs {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public bool Valgrind {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public ProcessLauncher CustomProcessLauncher {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public TargetProcessLauncher CustomTargetProcessLauncher {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public delegate Process ProcessLauncher (ProcessStartInfo info);
|
||||
public delegate ITargetProcess TargetProcessLauncher (ProcessStartInfo info);
|
||||
}
|
||||
|
||||
public class VirtualMachineManager
|
||||
{
|
||||
private delegate VirtualMachine LaunchCallback (ITargetProcess p, ProcessStartInfo info, Socket socket);
|
||||
private delegate VirtualMachine ListenCallback (Socket dbg_sock, Socket con_sock);
|
||||
private delegate VirtualMachine ConnectCallback (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep);
|
||||
|
||||
internal VirtualMachineManager () {
|
||||
}
|
||||
|
||||
public static VirtualMachine LaunchInternal (Process p, ProcessStartInfo info, Socket socket)
|
||||
{
|
||||
return LaunchInternal (new ProcessWrapper (p), info, socket);
|
||||
}
|
||||
|
||||
public static VirtualMachine LaunchInternal (ITargetProcess p, ProcessStartInfo info, Socket socket) {
|
||||
Socket accepted = null;
|
||||
try {
|
||||
accepted = socket.Accept ();
|
||||
} catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
|
||||
Connection conn = new Connection (accepted);
|
||||
|
||||
VirtualMachine vm = new VirtualMachine (p, conn);
|
||||
|
||||
if (info.RedirectStandardOutput)
|
||||
vm.StandardOutput = p.StandardOutput;
|
||||
|
||||
if (info.RedirectStandardError)
|
||||
vm.StandardError = p.StandardError;
|
||||
|
||||
conn.EventHandler = new EventHandler (vm);
|
||||
|
||||
vm.connect ();
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
public static IAsyncResult BeginLaunch (ProcessStartInfo info, AsyncCallback callback, LaunchOptions options) {
|
||||
if (info == null)
|
||||
throw new ArgumentNullException ("info");
|
||||
|
||||
Socket socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
socket.Bind (new IPEndPoint (IPAddress.Loopback, 0));
|
||||
socket.Listen (1000);
|
||||
IPEndPoint ep = (IPEndPoint) socket.LocalEndPoint;
|
||||
|
||||
// We need to inject our arguments into the psi
|
||||
info.Arguments = string.Format ("{0} --debug --debugger-agent=transport=dt_socket,address={1}:{2}{3} {4}",
|
||||
options == null || !options.Valgrind ? "" : info.FileName,
|
||||
ep.Address,
|
||||
ep.Port,
|
||||
options == null || options.AgentArgs == null ? "" : "," + options.AgentArgs,
|
||||
info.Arguments);
|
||||
|
||||
if (options != null && options.Valgrind)
|
||||
info.FileName = "valgrind";
|
||||
|
||||
ITargetProcess p;
|
||||
if (options != null && options.CustomProcessLauncher != null)
|
||||
p = new ProcessWrapper (options.CustomProcessLauncher (info));
|
||||
else if (options != null && options.CustomTargetProcessLauncher != null)
|
||||
p = options.CustomTargetProcessLauncher (info);
|
||||
else
|
||||
p = new ProcessWrapper (Process.Start (info));
|
||||
|
||||
p.Exited += delegate (object sender, EventArgs eargs) {
|
||||
socket.Close ();
|
||||
};
|
||||
|
||||
LaunchCallback c = new LaunchCallback (LaunchInternal);
|
||||
return c.BeginInvoke (p, info, socket, callback, socket);
|
||||
}
|
||||
|
||||
public static VirtualMachine EndLaunch (IAsyncResult asyncResult) {
|
||||
if (asyncResult == null)
|
||||
throw new ArgumentNullException ("asyncResult");
|
||||
|
||||
if (!asyncResult.IsCompleted)
|
||||
asyncResult.AsyncWaitHandle.WaitOne ();
|
||||
|
||||
AsyncResult async = (AsyncResult) asyncResult;
|
||||
LaunchCallback cb = (LaunchCallback) async.AsyncDelegate;
|
||||
return cb.EndInvoke (asyncResult);
|
||||
}
|
||||
|
||||
public static VirtualMachine Launch (ProcessStartInfo info, LaunchOptions options) {
|
||||
return EndLaunch (BeginLaunch (info, null, options));
|
||||
}
|
||||
|
||||
public static VirtualMachine Launch (string[] args, LaunchOptions options) {
|
||||
ProcessStartInfo pi = new ProcessStartInfo ("mono");
|
||||
pi.Arguments = String.Join (" ", args);
|
||||
|
||||
return Launch (pi, options);
|
||||
}
|
||||
|
||||
public static VirtualMachine ListenInternal (Socket dbg_sock, Socket con_sock) {
|
||||
Socket con_acc = null;
|
||||
Socket dbg_acc = null;
|
||||
|
||||
if (con_sock != null) {
|
||||
try {
|
||||
con_acc = con_sock.Accept ();
|
||||
} catch (Exception) {
|
||||
try {
|
||||
dbg_sock.Close ();
|
||||
} catch {}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
dbg_acc = dbg_sock.Accept ();
|
||||
} catch (Exception) {
|
||||
if (con_sock != null) {
|
||||
try {
|
||||
con_sock.Close ();
|
||||
con_acc.Close ();
|
||||
} catch {}
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
if (con_sock != null) {
|
||||
con_sock.Disconnect (false);
|
||||
con_sock.Close ();
|
||||
}
|
||||
|
||||
if (dbg_sock.Connected)
|
||||
dbg_sock.Disconnect (false);
|
||||
dbg_sock.Close ();
|
||||
|
||||
Connection conn = new Connection (dbg_acc);
|
||||
|
||||
VirtualMachine vm = new VirtualMachine (null, conn);
|
||||
|
||||
if (con_acc != null) {
|
||||
vm.StandardOutput = new StreamReader (new NetworkStream (con_acc));
|
||||
vm.StandardError = null;
|
||||
}
|
||||
|
||||
conn.EventHandler = new EventHandler (vm);
|
||||
|
||||
vm.connect ();
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
public static IAsyncResult BeginListen (IPEndPoint dbg_ep, AsyncCallback callback) {
|
||||
return BeginListen (dbg_ep, null, callback);
|
||||
}
|
||||
|
||||
public static IAsyncResult BeginListen (IPEndPoint dbg_ep, IPEndPoint con_ep, AsyncCallback callback) {
|
||||
Socket dbg_sock = null;
|
||||
Socket con_sock = null;
|
||||
|
||||
dbg_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
dbg_sock.Bind (dbg_ep);
|
||||
dbg_sock.Listen (1000);
|
||||
|
||||
if (con_ep != null) {
|
||||
con_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
con_sock.Bind (con_ep);
|
||||
con_sock.Listen (1000);
|
||||
}
|
||||
|
||||
ListenCallback c = new ListenCallback (ListenInternal);
|
||||
return c.BeginInvoke (dbg_sock, con_sock, callback, con_sock ?? dbg_sock);
|
||||
}
|
||||
|
||||
public static VirtualMachine EndListen (IAsyncResult asyncResult) {
|
||||
if (asyncResult == null)
|
||||
throw new ArgumentNullException ("asyncResult");
|
||||
|
||||
if (!asyncResult.IsCompleted)
|
||||
asyncResult.AsyncWaitHandle.WaitOne ();
|
||||
|
||||
AsyncResult async = (AsyncResult) asyncResult;
|
||||
ListenCallback cb = (ListenCallback) async.AsyncDelegate;
|
||||
return cb.EndInvoke (asyncResult);
|
||||
}
|
||||
|
||||
public static VirtualMachine Listen (IPEndPoint dbg_ep, IPEndPoint con_ep) {
|
||||
return EndListen (BeginListen (dbg_ep, con_ep, null));
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect to a virtual machine listening at the specified address.
|
||||
*/
|
||||
public static VirtualMachine Connect (IPEndPoint endpoint) {
|
||||
return Connect (endpoint, null);
|
||||
}
|
||||
|
||||
public static VirtualMachine Connect (IPEndPoint endpoint, IPEndPoint consoleEndpoint) {
|
||||
if (endpoint == null)
|
||||
throw new ArgumentNullException ("endpoint");
|
||||
|
||||
return EndConnect (BeginConnect (endpoint, consoleEndpoint, null));
|
||||
}
|
||||
|
||||
public static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep) {
|
||||
if (con_sock != null) {
|
||||
try {
|
||||
con_sock.Connect (con_ep);
|
||||
} catch (Exception) {
|
||||
try {
|
||||
dbg_sock.Close ();
|
||||
} catch {}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
dbg_sock.Connect (dbg_ep);
|
||||
} catch (Exception) {
|
||||
if (con_sock != null) {
|
||||
try {
|
||||
con_sock.Close ();
|
||||
} catch {}
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
Connection conn = new Connection (dbg_sock);
|
||||
|
||||
VirtualMachine vm = new VirtualMachine (null, conn);
|
||||
|
||||
if (con_sock != null) {
|
||||
vm.StandardOutput = new StreamReader (new NetworkStream (con_sock));
|
||||
vm.StandardError = null;
|
||||
}
|
||||
|
||||
conn.EventHandler = new EventHandler (vm);
|
||||
|
||||
vm.connect ();
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, AsyncCallback callback) {
|
||||
return BeginConnect (dbg_ep, null, callback);
|
||||
}
|
||||
|
||||
public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, IPEndPoint con_ep, AsyncCallback callback) {
|
||||
Socket dbg_sock = null;
|
||||
Socket con_sock = null;
|
||||
|
||||
dbg_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
|
||||
if (con_ep != null) {
|
||||
con_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
}
|
||||
|
||||
ConnectCallback c = new ConnectCallback (ConnectInternal);
|
||||
return c.BeginInvoke (dbg_sock, con_sock, dbg_ep, con_ep, callback, con_sock ?? dbg_sock);
|
||||
}
|
||||
|
||||
public static VirtualMachine EndConnect (IAsyncResult asyncResult) {
|
||||
if (asyncResult == null)
|
||||
throw new ArgumentNullException ("asyncResult");
|
||||
|
||||
if (!asyncResult.IsCompleted)
|
||||
asyncResult.AsyncWaitHandle.WaitOne ();
|
||||
|
||||
AsyncResult async = (AsyncResult) asyncResult;
|
||||
ConnectCallback cb = (ConnectCallback) async.AsyncDelegate;
|
||||
return cb.EndInvoke (asyncResult);
|
||||
}
|
||||
|
||||
public static void CancelConnection (IAsyncResult asyncResult)
|
||||
{
|
||||
((Socket)asyncResult.AsyncState).Close ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,542 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Net;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil.Metadata;
|
||||
|
||||
namespace Mono.Debugger
|
||||
{
|
||||
public class VirtualMachine : Mirror
|
||||
{
|
||||
Queue queue;
|
||||
object queue_monitor;
|
||||
object startup_monitor;
|
||||
AppDomainMirror root_domain;
|
||||
Dictionary<int, EventRequest> requests;
|
||||
Process process;
|
||||
|
||||
internal Connection conn;
|
||||
|
||||
internal VirtualMachine (Process process, Connection conn) : base () {
|
||||
SetVirtualMachine (this);
|
||||
queue = new Queue ();
|
||||
queue_monitor = new Object ();
|
||||
startup_monitor = new Object ();
|
||||
requests = new Dictionary <int, EventRequest> ();
|
||||
this.conn = conn;
|
||||
this.process = process;
|
||||
conn.ErrorHandler += ErrorHandler;
|
||||
}
|
||||
|
||||
// The standard output of the process is available normally through Process
|
||||
public StreamReader StandardOutput { get; set; }
|
||||
public StreamReader StandardError { get; set; }
|
||||
|
||||
public Process Process {
|
||||
get {
|
||||
return process;
|
||||
}
|
||||
}
|
||||
|
||||
public AppDomainMirror RootDomain {
|
||||
get {
|
||||
return root_domain;
|
||||
}
|
||||
}
|
||||
|
||||
public EndPoint EndPoint {
|
||||
get {
|
||||
return conn.EndPoint;
|
||||
}
|
||||
}
|
||||
|
||||
public Event GetNextEvent () {
|
||||
lock (queue_monitor) {
|
||||
if (queue.Count == 0)
|
||||
Monitor.Wait (queue_monitor);
|
||||
return (Event)queue.Dequeue ();
|
||||
}
|
||||
}
|
||||
|
||||
public Event GetNextEvent (int timeout) {
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public T GetNextEvent<T> () where T : Event {
|
||||
return GetNextEvent () as T;
|
||||
}
|
||||
|
||||
public void Suspend () {
|
||||
conn.VM_Suspend ();
|
||||
}
|
||||
|
||||
public void Resume () {
|
||||
try {
|
||||
conn.VM_Resume ();
|
||||
} catch (CommandException ex) {
|
||||
if (ex.ErrorCode == ErrorCode.NOT_SUSPENDED)
|
||||
throw new InvalidOperationException ("The vm is not suspended.");
|
||||
else
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void Exit (int exitCode) {
|
||||
conn.VM_Exit (exitCode);
|
||||
}
|
||||
|
||||
public void Dispose () {
|
||||
conn.VM_Dispose ();
|
||||
conn.Close ();
|
||||
notify_vm_event (EventType.VMDisconnect, 0, 0, null);
|
||||
}
|
||||
|
||||
public IList<ThreadMirror> GetThreads () {
|
||||
long[] ids = vm.conn.VM_GetThreads ();
|
||||
ThreadMirror[] res = new ThreadMirror [ids.Length];
|
||||
for (int i = 0; i < ids.Length; ++i)
|
||||
res [i] = GetThread (ids [i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Same as the mirrorOf methods in JDI
|
||||
public PrimitiveValue CreateValue (object value) {
|
||||
if (value == null)
|
||||
return new PrimitiveValue (vm, null);
|
||||
|
||||
if (!value.GetType ().IsPrimitive)
|
||||
throw new ArgumentException ("value must be of a primitive type instead of '" + value.GetType () + "'", "value");
|
||||
|
||||
return new PrimitiveValue (vm, value);
|
||||
}
|
||||
|
||||
//
|
||||
// Methods to create event request objects
|
||||
//
|
||||
public BreakpointEventRequest CreateBreakpointRequest (MethodMirror method, long il_offset) {
|
||||
return new BreakpointEventRequest (this, method, il_offset);
|
||||
}
|
||||
|
||||
public BreakpointEventRequest CreateBreakpointRequest (Location loc) {
|
||||
if (loc == null)
|
||||
throw new ArgumentNullException ("loc");
|
||||
CheckMirror (loc);
|
||||
return new BreakpointEventRequest (this, loc.Method, loc.ILOffset);
|
||||
}
|
||||
|
||||
public StepEventRequest CreateStepRequest (ThreadMirror thread) {
|
||||
return new StepEventRequest (this, thread);
|
||||
}
|
||||
|
||||
public MethodEntryEventRequest CreateMethodEntryRequest () {
|
||||
return new MethodEntryEventRequest (this);
|
||||
}
|
||||
|
||||
public MethodExitEventRequest CreateMethodExitRequest () {
|
||||
return new MethodExitEventRequest (this);
|
||||
}
|
||||
|
||||
public ExceptionEventRequest CreateExceptionRequest (TypeMirror exc_type) {
|
||||
return new ExceptionEventRequest (this, exc_type);
|
||||
}
|
||||
|
||||
public void EnableEvents (params EventType[] events) {
|
||||
foreach (EventType etype in events)
|
||||
conn.EnableEvent (etype, SuspendPolicy.All, null);
|
||||
}
|
||||
|
||||
public BreakpointEventRequest SetBreakpoint (MethodMirror method, long il_offset) {
|
||||
BreakpointEventRequest req = CreateBreakpointRequest (method, il_offset);
|
||||
|
||||
req.Enable ();
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
public void ClearAllBreakpoints () {
|
||||
conn.ClearAllBreakpoints ();
|
||||
}
|
||||
|
||||
internal void queue_event (Event e) {
|
||||
lock (queue_monitor) {
|
||||
queue.Enqueue (e);
|
||||
Monitor.Pulse (queue_monitor);
|
||||
}
|
||||
}
|
||||
|
||||
internal void ErrorHandler (object sender, ErrorHandlerEventArgs args) {
|
||||
switch (args.ErrorCode) {
|
||||
case ErrorCode.INVALID_OBJECT:
|
||||
throw new ObjectCollectedException ();
|
||||
case ErrorCode.INVALID_FRAMEID:
|
||||
throw new InvalidStackFrameException ();
|
||||
case ErrorCode.NOT_SUSPENDED:
|
||||
throw new InvalidOperationException ("The vm is not suspended.");
|
||||
default:
|
||||
throw new CommandException (args.ErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the debuggee to start up and connect to it */
|
||||
internal void connect () {
|
||||
conn.Connect ();
|
||||
|
||||
// Test the connection
|
||||
VersionInfo ver = conn.Version;
|
||||
if ((ver.MajorVersion != Connection.MAJOR_VERSION) ||
|
||||
(ver.MinorVersion > Connection.MINOR_VERSION))
|
||||
throw new NotSupportedException (String.Format ("The debuggee implements protocol version {0}.{1}, while {2}.{3} is required.", ver.MajorVersion, ver.MinorVersion, Connection.MAJOR_VERSION, Connection.MINOR_VERSION));
|
||||
|
||||
long root_domain_id = conn.RootDomain;
|
||||
root_domain = GetDomain (root_domain_id);
|
||||
}
|
||||
|
||||
internal void notify_vm_event (EventType evtype, int req_id, long thread_id, string vm_uri) {
|
||||
//Console.WriteLine ("Event: " + evtype + "(" + vm_uri + ")");
|
||||
|
||||
switch (evtype) {
|
||||
case EventType.VMStart:
|
||||
/* Notify the main thread that the debuggee started up */
|
||||
lock (startup_monitor) {
|
||||
Monitor.Pulse (startup_monitor);
|
||||
}
|
||||
queue_event (new VMStartEvent (vm, req_id, thread_id));
|
||||
break;
|
||||
case EventType.VMDeath:
|
||||
queue_event (new VMDeathEvent (vm, req_id));
|
||||
break;
|
||||
case EventType.VMDisconnect:
|
||||
queue_event (new VMDisconnectEvent (vm, req_id));
|
||||
break;
|
||||
default:
|
||||
throw new Exception ();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Methods to create instances of mirror objects
|
||||
//
|
||||
|
||||
/*
|
||||
class MirrorCache<T> {
|
||||
static Dictionary <long, T> mirrors;
|
||||
static object mirror_lock = new object ();
|
||||
|
||||
internal static T GetMirror (VirtualMachine vm, long id) {
|
||||
lock (mirror_lock) {
|
||||
if (mirrors == null)
|
||||
mirrors = new Dictionary <long, T> ();
|
||||
T obj;
|
||||
if (!mirrors.TryGetValue (id, out obj)) {
|
||||
obj = CreateMirror (vm, id);
|
||||
mirrors [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
internal static T CreateMirror (VirtualMachine vm, long id) {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// FIXME: When to remove items from the cache ?
|
||||
|
||||
Dictionary <long, MethodMirror> methods;
|
||||
object methods_lock = new object ();
|
||||
|
||||
internal MethodMirror GetMethod (long id) {
|
||||
lock (methods_lock) {
|
||||
if (methods == null)
|
||||
methods = new Dictionary <long, MethodMirror> ();
|
||||
MethodMirror obj;
|
||||
if (id == 0)
|
||||
return null;
|
||||
if (!methods.TryGetValue (id, out obj)) {
|
||||
obj = new MethodMirror (this, id);
|
||||
methods [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary <long, AssemblyMirror> assemblies;
|
||||
object assemblies_lock = new object ();
|
||||
|
||||
internal AssemblyMirror GetAssembly (long id) {
|
||||
lock (assemblies_lock) {
|
||||
if (assemblies == null)
|
||||
assemblies = new Dictionary <long, AssemblyMirror> ();
|
||||
AssemblyMirror obj;
|
||||
if (id == 0)
|
||||
return null;
|
||||
if (!assemblies.TryGetValue (id, out obj)) {
|
||||
obj = new AssemblyMirror (this, id);
|
||||
assemblies [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary <long, ModuleMirror> modules;
|
||||
object modules_lock = new object ();
|
||||
|
||||
internal ModuleMirror GetModule (long id) {
|
||||
lock (modules_lock) {
|
||||
if (modules == null)
|
||||
modules = new Dictionary <long, ModuleMirror> ();
|
||||
ModuleMirror obj;
|
||||
if (id == 0)
|
||||
return null;
|
||||
if (!modules.TryGetValue (id, out obj)) {
|
||||
obj = new ModuleMirror (this, id);
|
||||
modules [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary <long, AppDomainMirror> domains;
|
||||
object domains_lock = new object ();
|
||||
|
||||
internal AppDomainMirror GetDomain (long id) {
|
||||
lock (domains_lock) {
|
||||
if (domains == null)
|
||||
domains = new Dictionary <long, AppDomainMirror> ();
|
||||
AppDomainMirror obj;
|
||||
if (id == 0)
|
||||
return null;
|
||||
if (!domains.TryGetValue (id, out obj)) {
|
||||
obj = new AppDomainMirror (this, id);
|
||||
domains [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary <long, TypeMirror> types;
|
||||
object types_lock = new object ();
|
||||
|
||||
internal TypeMirror GetType (long id) {
|
||||
lock (types_lock) {
|
||||
if (types == null)
|
||||
types = new Dictionary <long, TypeMirror> ();
|
||||
TypeMirror obj;
|
||||
if (id == 0)
|
||||
return null;
|
||||
if (!types.TryGetValue (id, out obj)) {
|
||||
obj = new TypeMirror (this, id);
|
||||
types [id] = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary <long, ObjectMirror> objects;
|
||||
object objects_lock = new object ();
|
||||
|
||||
internal T GetObject<T> (long id, long domain_id, long type_id) where T : ObjectMirror {
|
||||
lock (objects_lock) {
|
||||
if (objects == null)
|
||||
objects = new Dictionary <long, ObjectMirror> ();
|
||||
ObjectMirror obj;
|
||||
if (!objects.TryGetValue (id, out obj)) {
|
||||
/*
|
||||
* Obtain the domain/type of the object to determine the type of
|
||||
* object we need to create.
|
||||
*/
|
||||
if (domain_id == 0)
|
||||
domain_id = conn.Object_GetDomain (id);
|
||||
AppDomainMirror d = GetDomain (domain_id);
|
||||
|
||||
if (type_id == 0)
|
||||
type_id = conn.Object_GetType (id);
|
||||
TypeMirror t = GetType (type_id);
|
||||
|
||||
if (t.Assembly == d.Corlib && t.Namespace == "System.Threading" && t.Name == "Thread")
|
||||
obj = new ThreadMirror (this, id);
|
||||
else if (t.Assembly == d.Corlib && t.Namespace == "System" && t.Name == "String")
|
||||
obj = new StringMirror (this, id);
|
||||
else if (typeof (T) == typeof (ArrayMirror))
|
||||
obj = new ArrayMirror (this, id);
|
||||
else
|
||||
obj = new ObjectMirror (this, id);
|
||||
objects [id] = obj;
|
||||
}
|
||||
return (T)obj;
|
||||
}
|
||||
}
|
||||
|
||||
internal T GetObject<T> (long id) where T : ObjectMirror {
|
||||
return GetObject<T> (id, 0, 0);
|
||||
}
|
||||
|
||||
internal ObjectMirror GetObject (long objid) {
|
||||
return GetObject<ObjectMirror> (objid);
|
||||
}
|
||||
|
||||
internal ThreadMirror GetThread (long id) {
|
||||
return GetObject <ThreadMirror> (id);
|
||||
}
|
||||
|
||||
object requests_lock = new object ();
|
||||
|
||||
internal void AddRequest (EventRequest req, int id) {
|
||||
lock (requests_lock) {
|
||||
requests [id] = req;
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveRequest (EventRequest req, int id) {
|
||||
lock (requests_lock) {
|
||||
requests.Remove (id);
|
||||
}
|
||||
}
|
||||
|
||||
internal EventRequest GetRequest (int id) {
|
||||
lock (requests_lock) {
|
||||
return requests [id];
|
||||
}
|
||||
}
|
||||
|
||||
internal Value DecodeValue (ValueImpl v) {
|
||||
if (v.Value != null)
|
||||
return new PrimitiveValue (this, v.Value);
|
||||
|
||||
switch (v.Type) {
|
||||
case ElementType.Void:
|
||||
return null;
|
||||
case ElementType.SzArray:
|
||||
case ElementType.Array:
|
||||
return GetObject<ArrayMirror> (v.Objid);
|
||||
case ElementType.String:
|
||||
return GetObject<StringMirror> (v.Objid);
|
||||
case ElementType.Class:
|
||||
case ElementType.Object:
|
||||
return GetObject (v.Objid);
|
||||
case ElementType.ValueType:
|
||||
if (v.IsEnum)
|
||||
return new EnumMirror (this, GetType (v.Klass), DecodeValues (v.Fields));
|
||||
else
|
||||
return new StructMirror (this, GetType (v.Klass), DecodeValues (v.Fields));
|
||||
case (ElementType)ValueTypeId.VALUE_TYPE_ID_NULL:
|
||||
return new PrimitiveValue (this, null);
|
||||
default:
|
||||
throw new NotImplementedException ("" + v.Type);
|
||||
}
|
||||
}
|
||||
|
||||
internal Value[] DecodeValues (ValueImpl[] values) {
|
||||
Value[] res = new Value [values.Length];
|
||||
for (int i = 0; i < values.Length; ++i)
|
||||
res [i] = DecodeValue (values [i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
internal ValueImpl EncodeValue (Value v) {
|
||||
if (v is PrimitiveValue) {
|
||||
object val = (v as PrimitiveValue).Value;
|
||||
if (val == null)
|
||||
return new ValueImpl { Type = (ElementType)ValueTypeId.VALUE_TYPE_ID_NULL, Objid = 0 };
|
||||
else
|
||||
return new ValueImpl { Value = val };
|
||||
} else if (v is ObjectMirror) {
|
||||
return new ValueImpl { Type = ElementType.Object, Objid = (v as ObjectMirror).Id };
|
||||
} else if (v is StructMirror) {
|
||||
return new ValueImpl { Type = ElementType.ValueType, Klass = (v as StructMirror).Type.Id, Fields = EncodeValues ((v as StructMirror).Fields) };
|
||||
} else {
|
||||
throw new NotSupportedException ();
|
||||
}
|
||||
}
|
||||
|
||||
internal ValueImpl[] EncodeValues (IList<Value> values) {
|
||||
ValueImpl[] res = new ValueImpl [values.Count];
|
||||
for (int i = 0; i < values.Count; ++i)
|
||||
res [i] = EncodeValue (values [i]);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
class EventHandler : MarshalByRefObject, IEventHandler
|
||||
{
|
||||
VirtualMachine vm;
|
||||
|
||||
public EventHandler (VirtualMachine vm) {
|
||||
this.vm = vm;
|
||||
}
|
||||
|
||||
public void VMStart (int req_id, long thread_id, string vm_uri) {
|
||||
vm.notify_vm_event (EventType.VMStart, req_id, thread_id, vm_uri);
|
||||
}
|
||||
|
||||
public void VMDeath (int req_id, long thread_id, string vm_uri) {
|
||||
vm.notify_vm_event (EventType.VMDeath, req_id, thread_id, vm_uri);
|
||||
}
|
||||
|
||||
public void VMDisconnect (int req_id, long thread_id, string vm_uri) {
|
||||
vm.notify_vm_event (EventType.VMDisconnect, req_id, thread_id, vm_uri);
|
||||
}
|
||||
|
||||
public void ThreadStart (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new ThreadStartEvent (vm, req_id, id));
|
||||
}
|
||||
|
||||
public void ThreadDeath (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new ThreadDeathEvent (vm, req_id, id));
|
||||
}
|
||||
|
||||
public void AssemblyLoad (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new AssemblyLoadEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void AssemblyUnload (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new AssemblyUnloadEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void TypeLoad (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new TypeLoadEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void MethodEntry (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new MethodEntryEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void MethodExit (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new MethodExitEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void Breakpoint (int req_id, long thread_id, long id, long loc) {
|
||||
vm.queue_event (new BreakpointEvent (vm, req_id, thread_id, id, loc));
|
||||
}
|
||||
|
||||
public void Step (int req_id, long thread_id, long id, long loc) {
|
||||
vm.queue_event (new StepEvent (vm, req_id, thread_id, id, loc));
|
||||
}
|
||||
|
||||
public void Exception (int req_id, long thread_id, long id, long loc) {
|
||||
vm.queue_event (new ExceptionEvent (vm, req_id, thread_id, id, loc));
|
||||
}
|
||||
|
||||
public void AppDomainCreate (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new AppDomainCreateEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
|
||||
public void AppDomainUnload (int req_id, long thread_id, long id) {
|
||||
vm.queue_event (new AppDomainUnloadEvent (vm, req_id, thread_id, id));
|
||||
}
|
||||
}
|
||||
|
||||
internal class CommandException : Exception {
|
||||
|
||||
public CommandException (ErrorCode error_code) : base ("Debuggee returned error code " + error_code + ".") {
|
||||
ErrorCode = error_code;
|
||||
}
|
||||
|
||||
public ErrorCode ErrorCode {
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,10 +40,6 @@
|
|||
<Compile Include="SdbTypeMirror.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\external\Mono.Debugger.Soft\Mono.Debugger.Soft.csproj">
|
||||
<Project>{F2D07F82-9C51-4889-8987-4CEF47490751}</Project>
|
||||
<Name>Mono.Debugger.Soft</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\CodeEditor.Composition\CodeEditor.Composition.csproj">
|
||||
<Project>{9DB8BFD3-06C8-4A8C-8842-5931B924B56C}</Project>
|
||||
<Name>CodeEditor.Composition</Name>
|
||||
|
@ -53,6 +49,11 @@
|
|||
<Name>CodeEditor.Debugger.Backend</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Debugger.Soft">
|
||||
<HintPath>..\..\..\..\External\Mono\builds\monodistribution\lib\mono\2.0\Mono.Debugger.Soft.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace CodeEditor.Debugger.Backend
|
||||
{
|
||||
public interface ITypeMirror
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CodeEditor.Debugger.IntegrationTests
|
||||
{
|
||||
public static class AssemblyCache
|
||||
{
|
||||
public static string GetCacheFolder(string fixtureName)
|
||||
{
|
||||
var cacheFolder = Path.Combine(Path.GetTempPath(), "cil2as", fixtureName);
|
||||
Directory.CreateDirectory(cacheFolder);
|
||||
return cacheFolder;
|
||||
}
|
||||
|
||||
private static string MD5String(string text)
|
||||
{
|
||||
var md5 = MD5.Create();
|
||||
var inputBytes = Encoding.UTF8.GetBytes(text);
|
||||
var hashBytes = md5.ComputeHash(inputBytes);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < hashBytes.Length; i++)
|
||||
sb.Append(hashBytes[i].ToString("x2"));
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string GetCacheKey(string fixtureName, string assemblyName, CachedAssemblyInfo info)
|
||||
{
|
||||
var cacheFolder = GetCacheFolder(fixtureName);
|
||||
|
||||
var infoText = info.ToString();
|
||||
var infoMD5 = MD5String(infoText);
|
||||
|
||||
var subFolder = Path.Combine(cacheFolder, infoMD5);
|
||||
Directory.CreateDirectory(subFolder);
|
||||
|
||||
var assemblyNameShort = Path.GetFileNameWithoutExtension(assemblyName);
|
||||
return Path.Combine(subFolder, assemblyNameShort);
|
||||
}
|
||||
|
||||
public static bool CheckCachedAssembly(string fixtureName, string assemblyName, CachedAssemblyInfo info)
|
||||
{
|
||||
var xmlPath = XmlCachePathFor(fixtureName, assemblyName, info);
|
||||
if (!File.Exists(xmlPath))
|
||||
return false;
|
||||
var cached = XmlRead(xmlPath);
|
||||
return info.Equals(cached);
|
||||
}
|
||||
|
||||
public static void SaveCachedAssembly(string fixtureName, string assemblyName, CachedAssemblyInfo info)
|
||||
{
|
||||
var xmlPath = XmlCachePathFor(fixtureName, assemblyName, info);
|
||||
XmlWrite(xmlPath, info);
|
||||
}
|
||||
|
||||
private static string XmlCachePathFor(string fixtureName, string assemblyName, CachedAssemblyInfo info)
|
||||
{
|
||||
return GetCacheKey(fixtureName, assemblyName, info) + ".xml";
|
||||
}
|
||||
|
||||
private static void XmlWrite(string path, CachedAssemblyInfo info)
|
||||
{
|
||||
var serializer = new XmlSerializer(info.GetType());
|
||||
using (var s = File.Open(path, FileMode.Create, FileAccess.Write))
|
||||
serializer.Serialize(s, info);
|
||||
}
|
||||
|
||||
private static CachedAssemblyInfo XmlRead(string path)
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(CachedAssemblyInfo));
|
||||
using (var s = File.OpenRead(path))
|
||||
return serializer.Deserialize(s) as CachedAssemblyInfo;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct CachedFileInfo
|
||||
{
|
||||
public string Path;
|
||||
public long Size;
|
||||
public DateTime LastModified;
|
||||
public bool Exists;
|
||||
|
||||
public CachedFileInfo(string existingFilePath)
|
||||
{
|
||||
Path = System.IO.Path.GetFullPath(existingFilePath).ToLowerInvariant();
|
||||
|
||||
try
|
||||
{
|
||||
var fi = new FileInfo(existingFilePath);
|
||||
Size = fi.Length;
|
||||
LastModified = fi.LastWriteTimeUtc;
|
||||
Exists = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Size = 0;
|
||||
LastModified = DateTime.MinValue;
|
||||
Exists = false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Equals(CachedFileInfo rhs)
|
||||
{
|
||||
var deltaSeconds = Math.Abs((LastModified - rhs.LastModified).TotalSeconds);
|
||||
|
||||
return Path == rhs.Path
|
||||
&& Size == rhs.Size
|
||||
&& deltaSeconds <= 1.0
|
||||
&& Exists == rhs.Exists;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is CachedFileInfo)
|
||||
return Equals((CachedFileInfo)obj);
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class CachedAssemblyInfo
|
||||
{
|
||||
public CachedFileInfo[] SourceFiles;
|
||||
public string[] References;
|
||||
|
||||
private CachedAssemblyInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public CachedAssemblyInfo(string[] sourceFiles, string[] references)
|
||||
{
|
||||
SourceFiles = sourceFiles.Select(fn => new CachedFileInfo(fn)).ToArray();
|
||||
References = references;
|
||||
}
|
||||
|
||||
// Checks to see if the output path and source files all match exactly.
|
||||
// Note that the actual output isn't compared.
|
||||
public bool Equals(CachedAssemblyInfo rhs)
|
||||
{
|
||||
if ((References == null) || (rhs.References == null))
|
||||
return false;
|
||||
if ((SourceFiles == null) || (rhs.SourceFiles == null))
|
||||
return false;
|
||||
|
||||
return SourceFiles.Length == rhs.SourceFiles.Length
|
||||
&& SourceFiles.OrderBy(sf => sf.Path)
|
||||
.SequenceEqual(rhs.SourceFiles.OrderBy(sf => sf.Path))
|
||||
&& References.Length == rhs.References.Length
|
||||
&& References.OrderBy(r => r)
|
||||
.SequenceEqual(rhs.References.OrderBy(r => r));
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var rhs = obj as CachedAssemblyInfo;
|
||||
return rhs != null ? Equals(rhs) : base.Equals(obj);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.AppendLine("Generated from inputs");
|
||||
foreach (var sourceFile in SourceFiles.OrderBy(sf => sf.Path))
|
||||
sb.AppendLine(sourceFile.ToString());
|
||||
|
||||
sb.AppendLine("With references");
|
||||
foreach (var reference in References)
|
||||
sb.AppendLine(reference);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using CodeEditor.Debugger.Implementation;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace CodeEditor.Debugger.IntegrationTests
|
||||
{
|
||||
[TestFixture]
|
||||
class BreakpointMediatorTests : DebuggerTestBase
|
||||
{
|
||||
[Test]
|
||||
[Ignore("WIP")]
|
||||
public void CanSetBreakpointOnLine ()
|
||||
{
|
||||
SetupTestWithBreakpoint();
|
||||
|
||||
_vm.OnBreakpoint += e => {
|
||||
Assert.AreEqual ("Main", e.Method.FullName);
|
||||
Finish ();
|
||||
};
|
||||
|
||||
WaitUntilFinished ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace CodeEditor.Debugger.IntegrationTests
|
||||
{
|
||||
public static class CSharpCompiler
|
||||
{
|
||||
// Returns output path of assembly
|
||||
public static string CompileAssemblyFromSourceDir(string fixtureName, string assemblyName, string sourceDir, bool generateExecutable = false, params string[] references)
|
||||
{
|
||||
var sourceFiles = SourceFilesIn(sourceDir);
|
||||
var cacheInfo = new CachedAssemblyInfo(sourceFiles, references);
|
||||
|
||||
var cacheKey = AssemblyCache.GetCacheKey(fixtureName, assemblyName, cacheInfo);
|
||||
var outputAssembly = cacheKey + (generateExecutable ? ".exe" : ".dll");
|
||||
|
||||
if (AssemblyCache.CheckCachedAssembly(fixtureName, assemblyName, cacheInfo))
|
||||
{
|
||||
var cachedCompilerOutput = File.ReadAllText(cacheKey + ".compilerOutput");
|
||||
Console.WriteLine("// Using cached assembly '{0}'. Original compiler output follows:", Path.GetFileName(Path.GetDirectoryName(cacheKey)));
|
||||
Console.WriteLine(cachedCompilerOutput);
|
||||
return outputAssembly;
|
||||
}
|
||||
|
||||
var compilerOutput = Compile(outputAssembly, sourceFiles, generateExecutable, references);
|
||||
|
||||
File.WriteAllText(cacheKey + ".compilerOutput", compilerOutput);
|
||||
Console.WriteLine(compilerOutput);
|
||||
|
||||
AssemblyCache.SaveCachedAssembly(fixtureName, assemblyName, cacheInfo);
|
||||
|
||||
return outputAssembly;
|
||||
}
|
||||
|
||||
public static string[] SourceFilesIn(string sourceDir)
|
||||
{
|
||||
return Directory.GetFiles(sourceDir, "*.cs", SearchOption.AllDirectories);
|
||||
}
|
||||
|
||||
public static string Compile(string outputAssembly, string[] sourceFiles, bool generateExecutable = false, params string[] references)
|
||||
{
|
||||
var args = new List<string>
|
||||
{
|
||||
"-out:\"" + outputAssembly + "\"",
|
||||
"-t:" + (generateExecutable ? "exe" : "library"),
|
||||
"-debug+",
|
||||
"-define:TRACE",
|
||||
"-r:System.dll",
|
||||
"-r:System.Core.dll"
|
||||
};
|
||||
args.AddRange(references.Select(r => "-r:\"" + r + "\""));
|
||||
args.AddRange(sourceFiles);
|
||||
|
||||
return Shell.Execute(Paths.MonoExecutable("bin/smcs"), string.Join(" ", args));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{E169204B-D59F-4CDA-A0A9-CBCEF7F538B3}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CodeEditor.Debugger.IntegrationTests</RootNamespace>
|
||||
<AssemblyName>CodeEditor.Debugger.IntegrationTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Moq">
|
||||
<HintPath>..\..\..\Moq\Moq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=2.6.0.12051, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\NUnit\bin\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyCache.cs" />
|
||||
<Compile Include="BreakpointMediatorTests.cs" />
|
||||
<Compile Include="DebuggerTestBase.cs" />
|
||||
<Compile Include="ExecutingLocationProviderTests.cs" />
|
||||
<Compile Include="Synchronization.cs" />
|
||||
<Compile Include="VirtualMachineTests.cs" />
|
||||
<Compile Include="CSharpCompiler.cs" />
|
||||
<Compile Include="Paths.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Shell.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\external\Mono.Debugger.Soft\Mono.Debugger.Soft.csproj">
|
||||
<Project>{F2D07F82-9C51-4889-8987-4CEF47490751}</Project>
|
||||
<Name>Mono.Debugger.Soft</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\CodeEditor.Composition\CodeEditor.Composition.csproj">
|
||||
<Project>{9DB8BFD3-06C8-4A8C-8842-5931B924B56C}</Project>
|
||||
<Name>CodeEditor.Composition</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\CodeEditor.Debugger\CodeEditor.Debugger.csproj">
|
||||
<Project>{6441A270-0DF3-42C9-9409-02BC273507DA}</Project>
|
||||
<Name>CodeEditor.Debugger</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,138 +0,0 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using CodeEditor.Debugger.Implementation;
|
||||
using Mono.Debugger.Soft;
|
||||
using NUnit.Framework;
|
||||
using VirtualMachine = CodeEditor.Debugger.Implementation.VirtualMachine;
|
||||
|
||||
namespace CodeEditor.Debugger.IntegrationTests
|
||||
{
|
||||
internal class DebuggerTestBase
|
||||
{
|
||||
public const bool DebugMono = false;
|
||||
protected VirtualMachine _vm;
|
||||
private bool _finished;
|
||||
private BreakpointProvider _breakpointProvider;
|
||||
protected IExecutingLocationProvider ExecutingLocationProvider;
|
||||
|
||||
private static LaunchOptions DebuggerOptions
|
||||
{
|
||||
get { return new LaunchOptions () { AgentArgs = "loglevel=2,logfile=c:/as3/sdblog" }; }
|
||||
}
|
||||
|
||||
public static string DebugeeProgramClassName
|
||||
{
|
||||
get { return "TestClass"; }
|
||||
}
|
||||
|
||||
public static string AssemblyName
|
||||
{
|
||||
get { return "TestAssembly"; }
|
||||
}
|
||||
|
||||
public static string Filename
|
||||
{
|
||||
get { return AssemblyName+".exe"; }
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_vm = SetupVirtualMachineRunning (CompileSimpleProgram ());
|
||||
}
|
||||
|
||||
protected void WaitUntilFinished ()
|
||||
{
|
||||
Synchronization.WaitFor (() => _finished, "Waiting for _finished");
|
||||
try
|
||||
{
|
||||
_vm.Exit ();
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
}
|
||||
Synchronization.WaitFor (() => _vm.Process.HasExited, "Waiting for process to exit");
|
||||
|
||||
foreach (var error in _vm.Errors)
|
||||
Console.WriteLine ("VM had error: "+error);
|
||||
|
||||
Assert.IsEmpty (_vm.Errors);
|
||||
}
|
||||
|
||||
protected void Finish ()
|
||||
{
|
||||
_finished = true;
|
||||
}
|
||||
|
||||
private static VirtualMachine SetupVirtualMachineRunning (string exe)
|
||||
{
|
||||
var psi = ProcessStartInfoFor (exe);
|
||||
|
||||
Console.WriteLine ((string) psi.FileName);
|
||||
|
||||
var sdb = VirtualMachineManager.Launch ((ProcessStartInfo) psi, DebuggerOptions);
|
||||
var vm = new VirtualMachine (sdb);
|
||||
return vm;
|
||||
}
|
||||
|
||||
public static ProcessStartInfo ProcessStartInfoFor (string exe)
|
||||
{
|
||||
var psi = new ProcessStartInfo ()
|
||||
{
|
||||
Arguments = exe,
|
||||
CreateNoWindow = true,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardError = true,
|
||||
FileName = Paths.MonoExecutable ("bin/cli")
|
||||
};
|
||||
|
||||
if (DebugMono)
|
||||
psi.EnvironmentVariables.Add ("UNITY_GIVE_CHANCE_TO_ATTACH_DEBUGGER", "1");
|
||||
return psi;
|
||||
}
|
||||
|
||||
public static string CompileSimpleProgram ()
|
||||
{
|
||||
var csharp = @"
|
||||
using System;
|
||||
|
||||
class "+DebugeeProgramClassName + @"
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
Console.WriteLine(""Hello"");
|
||||
}
|
||||
}
|
||||
";
|
||||
var tmp = LocationOfSourceFile;
|
||||
File.WriteAllText (tmp,csharp);
|
||||
CSharpCompiler.Compile (Filename, new[] {tmp}, true);
|
||||
return Filename;
|
||||
}
|
||||
|
||||
protected static string LocationOfSourceFile
|
||||
{
|
||||
get { return Path.Combine (Path.GetTempPath (), SourceFileName); }
|
||||
}
|
||||
|
||||
public static string SourceFileName
|
||||
{
|
||||
get { return "source.cs"; }
|
||||
}
|
||||
|
||||
protected void SetupTestWithBreakpoint()
|
||||
{
|
||||
_vm.OnVMStart += e => _vm.Resume();
|
||||
_vm.OnTypeLoad += e => _vm.Resume();
|
||||
_vm.OnAssemblyLoad += e => _vm.Resume();
|
||||
|
||||
_breakpointProvider = new BreakpointProvider();
|
||||
_breakpointProvider.ToggleBreakPointAt(LocationOfSourceFile, 9);
|
||||
new BreakpointMediator(_vm, _breakpointProvider);
|
||||
ExecutingLocationProvider = new ExecutingLocationProvider(_vm);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
using NUnit.Framework;
|
||||
|
||||
namespace CodeEditor.Debugger.IntegrationTests
|
||||
{
|
||||
[TestFixture]
|
||||
class ExecutingLocationProviderTests : DebuggerTestBase
|
||||
{
|
||||
[Test]
|
||||
public void ReturnsCorrectLocationOnBreakpoint()
|
||||
{
|
||||
SetupTestWithBreakpoint();
|
||||
|
||||
_vm.OnBreakpoint += e => {
|
||||
Assert.AreEqual(9, ExecutingLocationProvider.Location.LineNumber);
|
||||
Assert.AreEqual(LocationOfSourceFile, ExecutingLocationProvider.Location.SourceFile);
|
||||
Finish ();
|
||||
};
|
||||
|
||||
WaitUntilFinished ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace CodeEditor.Debugger.IntegrationTests
|
||||
{
|
||||
public static class Paths
|
||||
{
|
||||
public static string ProjectPath(string path)
|
||||
{
|
||||
return Path.GetFullPath(Path.Combine(ProjectDirectory, path));
|
||||
}
|
||||
|
||||
private static string CalculateProjectDirectory()
|
||||
{
|
||||
var assembly = new Uri(typeof(Paths).Assembly.CodeBase).AbsolutePath;
|
||||
return Path.Combine(Path.GetDirectoryName(assembly), "../../..");
|
||||
}
|
||||
|
||||
static readonly string ProjectDirectory = CalculateProjectDirectory();
|
||||
|
||||
public static string ExecutablePath(string path)
|
||||
{
|
||||
return ExecutablePath(path, ".exe");
|
||||
}
|
||||
|
||||
private static string ExecutablePath(string path, string windowsExtension)
|
||||
{
|
||||
return FixExecutableExtension(ProjectPath(path), windowsExtension);
|
||||
}
|
||||
|
||||
public static string MonoExecutable(string path)
|
||||
{
|
||||
return FixExecutableExtension(MonoPath(path), ".bat");
|
||||
}
|
||||
|
||||
private static string FixExecutableExtension(string result, string windowsExtension)
|
||||
{
|
||||
if (IsWindows()) result += windowsExtension;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool IsWindows()
|
||||
{
|
||||
switch (Environment.OSVersion.Platform)
|
||||
{
|
||||
case PlatformID.Win32Windows:
|
||||
case PlatformID.Win32NT:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string MonoPath(string path)
|
||||
{
|
||||
return Path.Combine(ProjectPath("../../../External/Mono/builds/monodistribution"), path);
|
||||
}
|
||||
|
||||
public static string PrepareFileName(string file)
|
||||
{
|
||||
return "\"" + file + "\"";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("CodeEditor.Debugger.IntegrationTests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("CodeEditor.Debugger.IntegrationTests")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("f05762ff-3aab-458a-b745-41b8ac30da74")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,65 +0,0 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace CodeEditor.Debugger.IntegrationTests
|
||||
{
|
||||
internal static class Shell
|
||||
{
|
||||
public static string Execute(string filename, string arguments)
|
||||
{
|
||||
var p = StartProcess(filename, arguments);
|
||||
var error = p.StandardError.ReadToEnd();
|
||||
var output = p.StandardOutput.ReadToEnd();
|
||||
p.WaitForExit();
|
||||
var allConsoleOutput = error + output;
|
||||
Assert.AreEqual(0, p.ExitCode, allConsoleOutput);
|
||||
return allConsoleOutput;
|
||||
}
|
||||
|
||||
public static Process StartProcess(string filename, string arguments)
|
||||
{
|
||||
var p = new Process
|
||||
{
|
||||
StartInfo =
|
||||
{
|
||||
Arguments = arguments,
|
||||
CreateNoWindow = true,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardError = true,
|
||||
FileName = filename
|
||||
}
|
||||
};
|
||||
p.Start();
|
||||
return p;
|
||||
}
|
||||
|
||||
public static string CapturingStdout(Action action)
|
||||
{
|
||||
return Capturing(Console.Out, Console.SetOut, action);
|
||||
}
|
||||
|
||||
public static string CapturingStderr(Action action)
|
||||
{
|
||||
return Capturing(Console.Error, Console.SetError, action);
|
||||
}
|
||||
|
||||
private static string Capturing(TextWriter previous, Action<TextWriter> setter, Action action)
|
||||
{
|
||||
var stdout = new StringWriter();
|
||||
setter(stdout);
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
setter(previous);
|
||||
}
|
||||
return stdout.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace CodeEditor.Debugger.IntegrationTests
|
||||
{
|
||||
class Synchronization
|
||||
{
|
||||
public static void WaitFor(Func<bool> condition, string msg)
|
||||
{
|
||||
var stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
while(true)
|
||||
{
|
||||
if (condition())
|
||||
return;
|
||||
|
||||
if (stopWatch.Elapsed > TimeSpan.FromSeconds(IsHumanDebugging() ? 10000 : 5))
|
||||
throw new TimeoutException(msg);
|
||||
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsHumanDebugging()
|
||||
{
|
||||
return VirtualMachineTests.DebugMono || System.Diagnostics.Debugger.IsAttached;
|
||||
}
|
||||
|
||||
public static void WaitFor(Func<bool> condition)
|
||||
{
|
||||
WaitFor(condition,"No msg");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Mono.Debugger.Soft;
|
||||
using NUnit.Framework;
|
||||
using VirtualMachine = CodeEditor.Debugger.Implementation.VirtualMachine;
|
||||
|
||||
namespace CodeEditor.Debugger.IntegrationTests
|
||||
{
|
||||
[TestFixture]
|
||||
class VirtualMachineTests : DebuggerTestBase
|
||||
{
|
||||
[Test]
|
||||
public void PublishesVMStartEventOnStartup ()
|
||||
{
|
||||
_vm.OnVMStart += e =>
|
||||
{
|
||||
Assert.IsNotNull (e);
|
||||
Finish ();
|
||||
};
|
||||
|
||||
WaitUntilFinished ();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PublishesVMGotSuspendedOnStartup ()
|
||||
{
|
||||
_vm.OnVMGotSuspended += e => Finish();
|
||||
WaitUntilFinished ();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PublishesAssemblyLoadEventOnStartup ()
|
||||
{
|
||||
_vm.OnVMStart += e => _vm.Resume ();
|
||||
_vm.OnAssemblyLoad += e => {
|
||||
Assert.AreEqual (AssemblyName, e.Assembly.GetName ().Name);
|
||||
Finish();
|
||||
};
|
||||
|
||||
WaitUntilFinished ();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PublishesVMDeathOnEndOfProgram ()
|
||||
{
|
||||
_vm.OnVMStart += e => _vm.Resume ();
|
||||
_vm.OnTypeLoad += e => _vm.Resume ();
|
||||
_vm.OnAssemblyLoad += e => _vm.Resume ();
|
||||
_vm.OnVMDeath += e => {
|
||||
Assert.NotNull (e);
|
||||
Finish ();
|
||||
};
|
||||
|
||||
WaitUntilFinished ();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PublishesTypeLoadEventOnStartup ()
|
||||
{
|
||||
_vm.OnVMStart += e => _vm.Resume ();
|
||||
_vm.OnAssemblyLoad += e => _vm.Resume ();
|
||||
_vm.OnTypeLoad += e => {
|
||||
if (DebugeeProgramClassName == e.Type.FullName)
|
||||
Finish ();
|
||||
_vm.Resume ();
|
||||
};
|
||||
WaitUntilFinished ();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BreakPointOnMainWillHit ()
|
||||
{
|
||||
_vm.OnVMStart += e => _vm.Resume ();
|
||||
_vm.OnAssemblyLoad += e => _vm.Resume ();
|
||||
|
||||
BreakpointEventRequest request = null;
|
||||
_vm.OnTypeLoad += e => {
|
||||
if (DebugeeProgramClassName == e.Type.FullName)
|
||||
{
|
||||
var locations = e.Type.GetMethod ("Main").Locations;
|
||||
Assert.AreEqual (4, locations.Count);
|
||||
|
||||
Assert.AreEqual (7, locations[0].LineNumber);
|
||||
Assert.AreEqual (8, locations[1].LineNumber);
|
||||
Assert.AreEqual (9, locations[2].LineNumber);
|
||||
Assert.AreEqual (9, locations[3].LineNumber);
|
||||
|
||||
request = _vm.CreateBreakpointRequest (locations.First ());
|
||||
request.Enable ();
|
||||
}
|
||||
_vm.Resume ();
|
||||
};
|
||||
|
||||
_vm.OnBreakpoint += e => {
|
||||
Assert.AreEqual ("Main", e.Method.Name);
|
||||
Assert.AreSame (e.Request, request);
|
||||
Finish ();
|
||||
};
|
||||
|
||||
WaitUntilFinished ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
using CodeEditor.Debugger.Backend;
|
||||
using CodeEditor.Debugger.Implementation;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace CodeEditor.Debugger.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class BreakPointMediatorTests
|
||||
{
|
||||
private Mock<IDebuggerSession> _session;
|
||||
private BreakpointProvider _breakPointProvider;
|
||||
private ITypeMirrorProvider _typeMirrorProvider;
|
||||
private Mock<IBreakpointEventRequestFactory> _breakpointEventRequestFactory;
|
||||
private Mock<IBreakpointEventRequest> _breakRequest;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_session = new Mock<IDebuggerSession>();
|
||||
_breakPointProvider = new BreakpointProvider();
|
||||
_typeMirrorProvider = new TypeMirrorProvider(_session.Object);
|
||||
_breakpointEventRequestFactory = new Mock<IBreakpointEventRequestFactory>(MockBehavior.Strict);
|
||||
_breakRequest = new Mock<IBreakpointEventRequest>();
|
||||
new BreakpointMediator(_breakPointProvider, _typeMirrorProvider, _breakpointEventRequestFactory.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenTypeLoadsMatchingExistingBreakPoint_CreatesBreakRequest()
|
||||
{
|
||||
SetupBreakEventRequestFactory("myfile.cs", 3, _breakRequest.Object);
|
||||
AddBreakpoint("myfile.cs",3);
|
||||
RaiseTypeLoad(MockTypeWithMethodFrom("myfile.cs", 3));
|
||||
|
||||
_breakRequest.Verify(r=>r.Enable());
|
||||
VerifyMocks();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BreakPointGetsAddedMatchingAlreadyLoadedType_CreatesBreakRequest()
|
||||
{
|
||||
SetupBreakEventRequestFactory("myfile.cs", 5, _breakRequest.Object);
|
||||
RaiseTypeLoad(MockTypeWithMethodFrom("myfile.cs",5));
|
||||
AddBreakpoint("myfile.cs",5);
|
||||
|
||||
_breakRequest.Verify(r => r.Enable());
|
||||
VerifyMocks();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TypeLoadWithMethodInSameFileButDifferentLine_DoesNotCreateBreakRequest()
|
||||
{
|
||||
AddBreakpoint("myfile.cs", 5);
|
||||
RaiseTypeLoad(MockTypeWithMethodFrom("myfile.cs", 10));
|
||||
}
|
||||
|
||||
private void SetupBreakEventRequestFactory(string file, int lineNumber, IBreakpointEventRequest breakRequestToCreate)
|
||||
{
|
||||
_breakpointEventRequestFactory
|
||||
.Setup(f => f.Create(It.Is<ILocation>(location => location.File == file && location.LineNumber == lineNumber)))
|
||||
.Returns(breakRequestToCreate);
|
||||
}
|
||||
|
||||
private void VerifyMocks()
|
||||
{
|
||||
_breakpointEventRequestFactory.VerifyAll();
|
||||
_session.VerifyAll();
|
||||
_breakRequest.VerifyAll();
|
||||
}
|
||||
|
||||
private void AddBreakpoint(string file, int line)
|
||||
{
|
||||
_breakPointProvider.ToggleBreakPointAt(file,line);
|
||||
}
|
||||
|
||||
private void RaiseTypeLoad(Mock<ITypeMirror> debugType)
|
||||
{
|
||||
_session.Raise(tp => tp.TypeLoaded += null, debugType.Object);
|
||||
}
|
||||
|
||||
private static Mock<ITypeMirror> MockTypeWithMethodFrom(string sourceFile, int line)
|
||||
{
|
||||
var debugType = new Mock<ITypeMirror>();
|
||||
debugType.SetupGet(t => t.SourceFiles).Returns(new[] {sourceFile});
|
||||
|
||||
var debugMethod = new Mock<IMethodMirror>();
|
||||
var debugLocation = new Mock<ILocation>();
|
||||
debugLocation.SetupGet(l => l.File).Returns(sourceFile);
|
||||
debugLocation.SetupGet(l => l.LineNumber).Returns(line);
|
||||
debugMethod.SetupGet(m => m.Locations).Returns(new[] {debugLocation.Object});
|
||||
debugType.SetupGet(t => t.Methods).Returns(new[] {debugMethod.Object});
|
||||
|
||||
return debugType;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -70,6 +70,7 @@
|
|||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BreakPointMediatorTests.cs" />
|
||||
<Compile Include="TypeProviderTests.cs" />
|
||||
<Compile Include="SourceToTypeMapperTests.cs" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Debugger.Soft">
|
||||
<HintPath>..\..\..\..\External\Mono\builds\monodistribution\lib\mono\2.0\Mono.Debugger.Soft.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
|
@ -73,10 +76,6 @@
|
|||
<Project>{F0499708-3EB6-4026-8362-97E6FFC4E7C8}</Project>
|
||||
<Name>UnityEngine</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\external\Mono.Debugger.Soft\Mono.Debugger.Soft.csproj">
|
||||
<Project>{F2D07F82-9C51-4889-8987-4CEF47490751}</Project>
|
||||
<Name>Mono.Debugger.Soft</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\CodeEditor.Composition\CodeEditor.Composition.csproj">
|
||||
<Project>{9DB8BFD3-06C8-4A8C-8842-5931B924B56C}</Project>
|
||||
<Name>CodeEditor.Composition</Name>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using CodeEditor.Composition;
|
||||
using CodeEditor.Debugger.Implementation;
|
||||
using CodeEditor.Text.UI.Unity.Engine;
|
||||
using UnityEngine;
|
||||
|
||||
|
@ -8,11 +9,11 @@ namespace CodeEditor.Debugger.Unity.Engine
|
|||
class ExecutingLineAdornment : ITextViewAdornment
|
||||
{
|
||||
[Import]
|
||||
IExecutingLocationProvider ExecutingLocationProvider { get; set; }
|
||||
ExecutingLineProvider ExecutingLineProvider { get; set; }
|
||||
|
||||
public void Draw(ITextViewLine line, Rect lineRect)
|
||||
{
|
||||
if (line.LineNumber == ExecutingLocationProvider.Location.LineNumber)
|
||||
if (line.LineNumber == ExecutingLineProvider.LineNumber)
|
||||
Draw(lineRect);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,8 +69,7 @@
|
|||
-->
|
||||
|
||||
<PropertyGroup>
|
||||
<UnityDebuggerDir>\Data\Tools\Debugger\</UnityDebuggerDir>
|
||||
<UnityDebuggerDataDir>$(UnityDebuggerDir)Debugger_Data\Managed\</UnityDebuggerDataDir>
|
||||
<UnityDebuggerDir>\Data\Tools\Debugger\Debugger_Data\Managed\</UnityDebuggerDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(OS)' == 'Unix' ">
|
||||
|
@ -93,26 +92,20 @@
|
|||
<Touch Files="@(IntermediateAssembly)" AlwaysCreate="true" />
|
||||
</Target>
|
||||
|
||||
<Target Name="AfterBuild" DependsOnTargets="_CopyDependenciesToDebuggerDir;_CopyDebuggerBuild" />
|
||||
<Target Name="AfterBuild" DependsOnTargets="_CopyDependenciesToDebuggerDir" />
|
||||
|
||||
<!-- Make sure all the assemblies are cleaned from the debugger dir as well -->
|
||||
<Target Name="AfterClean" DependsOnTargets="_ResolveOutputs">
|
||||
<Delete Files="@(_Files->'$(UnityBuildDir)$(UnityDebuggerDataDir)%(Filename)%(Extension)')" />
|
||||
<Delete Files="@(_Files->'$(UnityBuildDir)$(UnityDebuggerDir)%(Filename)%(Extension)')" />
|
||||
</Target>
|
||||
|
||||
<!-- This target resolves all the assemblies that this project references directly or
|
||||
indirectly, excluding the UnityEngine.dll and UnityEditor.dll -->
|
||||
<Target Name="_ResolveOutputs"
|
||||
DependsOnTargets="_ResolvePaths"
|
||||
>
|
||||
<Target Name="_ResolveOutputs">
|
||||
<CreateItem Include="$(OutDir)\*.dll" Exclude="$(OutDir)\UnityEngine*;$(OutDir)\UnityEditor*;$(OutDir)$(TargetFilename)">
|
||||
<Output TaskParameter="Include" ItemName="_Files"/>
|
||||
</CreateItem>
|
||||
<Message Text="@(_Files)" />
|
||||
|
||||
<CreateItem Include="$(_ProjectAbsPath)$(UnityDebuggerProjectBuildDir)\**">
|
||||
<Output TaskParameter="Include" ItemName="_DebuggerFiles" />
|
||||
</CreateItem>
|
||||
</Target>
|
||||
|
||||
<!-- This target resolves full project and tool paths for the _BuildDebuggerProject target -->
|
||||
|
@ -146,30 +139,17 @@
|
|||
<!-- Take all the assemblies and copy them to the debugger dir,
|
||||
with dependency checks (only copies what's changed) -->
|
||||
<Target Name="_CopyDependenciesToDebuggerDir"
|
||||
DependsOnTargets="_ResolveOutputs"
|
||||
DependsOnTargets="_ResolveOutputs;_ResolvePaths"
|
||||
Inputs="@(_Files)"
|
||||
Outputs="@(_Files->'$(UnityBuildDir)$(UnityDebuggerDataDir)%(Filename)%(Extension)')">
|
||||
Outputs="@(_Files->'$(UnityBuildDir)$(UnityDebuggerDir)%(Filename)%(Extension)')">
|
||||
|
||||
<MakeDir Directories="$(UnityBuildDir)$(UnityDebuggerDataDir)" />
|
||||
<MakeDir Directories="$(UnityBuildDir)$(UnityDebuggerDir)" />
|
||||
<Copy
|
||||
SourceFiles="@(_Files)"
|
||||
DestinationFolder="$(UnityBuildDir)$(UnityDebuggerDataDir)"
|
||||
DestinationFolder="$(UnityBuildDir)$(UnityDebuggerDir)"
|
||||
SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_CopyDebuggerBuild"
|
||||
DependsOnTargets="_ResolvePaths"
|
||||
Inputs="@(_DebuggerFiles)"
|
||||
Outputs="@(_DebuggerFiles->'$(UnityBuildDir)$(UnityDebuggerDir)%(RecursiveDir)%(Filename)%(Extension)')">
|
||||
|
||||
<Message Text="DEBUGGER: @(_DebuggerFiles)" />
|
||||
|
||||
<Copy
|
||||
SourceFiles="@(_DebuggerFiles)"
|
||||
DestinationFiles="@(_DebuggerFiles->'$(UnityBuildDir)$(UnityDebuggerDir)%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
SkipUnchangedFiles="true" />
|
||||
|
||||
</Target>
|
||||
|
||||
<!-- This target is called by the BuildDebuggerProject target. It builds the unity debugger
|
||||
project and deploys the result to the proper directories -->
|
||||
|
@ -196,5 +176,5 @@
|
|||
</Target>
|
||||
|
||||
<Target Name="Deploy" DependsOnTargets="Build" />
|
||||
<Target Name="BuildDebuggerProject" DependsOnTargets="_BuildDebuggerProject;_CopyDebuggerBuild" />
|
||||
<Target Name="BuildDebuggerProject" DependsOnTargets="_BuildDebuggerProject" />
|
||||
</Project>
|
|
@ -50,6 +50,10 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Debugger.Soft, Version=0.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\External\Mono\builds\monodistribution\lib\mono\2.0\Mono.Debugger.Soft.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
|
@ -67,10 +71,6 @@
|
|||
<Project>{F0499708-3EB6-4026-8362-97E6FFC4E7C8}</Project>
|
||||
<Name>UnityEngine</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\external\Mono.Debugger.Soft\Mono.Debugger.Soft.csproj">
|
||||
<Project>{F2D07F82-9C51-4889-8987-4CEF47490751}</Project>
|
||||
<Name>Mono.Debugger.Soft</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\CodeEditor.Composition\CodeEditor.Composition.csproj">
|
||||
<Project>{9DB8BFD3-06C8-4A8C-8842-5931B924B56C}</Project>
|
||||
<Name>CodeEditor.Composition</Name>
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -60,10 +60,6 @@
|
|||
</Target>
|
||||
-->
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\external\Mono.Debugger.Soft\Mono.Debugger.Soft.csproj">
|
||||
<Project>{F2D07F82-9C51-4889-8987-4CEF47490751}</Project>
|
||||
<Name>Mono.Debugger.Soft</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\CodeEditor.Composition\CodeEditor.Composition.csproj">
|
||||
<Project>{9DB8BFD3-06C8-4A8C-8842-5931B924B56C}</Project>
|
||||
<Name>CodeEditor.Composition</Name>
|
||||
|
@ -94,6 +90,10 @@
|
|||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\External\Mono\builds\monodistribution\lib\mono\2.0\Mono.Cecil.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Mono.Debugger.Soft, Version=0.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\External\Mono\builds\monodistribution\lib\mono\2.0\Mono.Debugger.Soft.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
|
@ -105,21 +105,16 @@
|
|||
<Compile Include="IBreakpointProvider.cs" />
|
||||
<Compile Include="IDebuggerSession.cs" />
|
||||
<Compile Include="IDebuggerSessionAssembler.cs" />
|
||||
<Compile Include="IExecutingLocationProvider.cs" />
|
||||
<Compile Include="Implementation\BreakpointMediator.cs" />
|
||||
<Compile Include="ILocation.cs" />
|
||||
<Compile Include="Implementation\Location.cs" />
|
||||
<Compile Include="IVirtualMachine.cs" />
|
||||
<Compile Include="Implementation\VirtualMachine.cs" />
|
||||
<Compile Include="IThreadProvider.cs" />
|
||||
<Compile Include="Implementation\BreakpointEventRequestFactory.cs" />
|
||||
<Compile Include="Implementation\BreakpointMediator.cs" />
|
||||
<Compile Include="Implementation\BreakPoint.cs" />
|
||||
<Compile Include="Implementation\BreakpointProvider.cs" />
|
||||
<Compile Include="Implementation\DebuggerSession.cs" />
|
||||
<Compile Include="Implementation\DebuggerSessionAssembler.cs" />
|
||||
<Compile Include="Implementation\ThreadProvider.cs" />
|
||||
<Compile Include="Implementation\TypeMirrorProvider.cs" />
|
||||
<Compile Include="Implementation\ExecutingLocationProvider.cs" />
|
||||
<Compile Include="Implementation\ExecutingLineProvider.cs" />
|
||||
<Compile Include="IBreakPoint.cs" />
|
||||
<Compile Include="IDebuggerSessionCreationListener.cs" />
|
||||
<Compile Include="ILogProvider.cs" />
|
||||
|
|
|
@ -2,6 +2,7 @@ namespace CodeEditor.Debugger
|
|||
{
|
||||
public interface IBreakPoint
|
||||
{
|
||||
ILocation Location { get; }
|
||||
string File { get; }
|
||||
int LineNumber { get; }
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ namespace CodeEditor.Debugger
|
|||
void Disconnect();
|
||||
void Update();
|
||||
ThreadsRequest GetThreadsAsync();
|
||||
BreakpointEventRequest CreateBreakpointRequest(Mono.Debugger.Soft.Location location);
|
||||
BreakpointEventRequest CreateBreakpointRequest(Location location);
|
||||
event Action<ITypeMirror> TypeLoaded;
|
||||
event Action<IAssemblyMirror> AssemblyLoaded;
|
||||
event Action<IAssemblyMirror> AssemblyUnloaded;
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
using CodeEditor.Debugger.Implementation;
|
||||
|
||||
namespace CodeEditor.Debugger
|
||||
{
|
||||
public interface IExecutingLocationProvider
|
||||
{
|
||||
ILocation Location { get; }
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
namespace CodeEditor.Debugger
|
||||
{
|
||||
public interface ILocation
|
||||
{
|
||||
int LineNumber { get; }
|
||||
string SourceFile { get; }
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
using System;
|
||||
using Mono.Debugger.Soft;
|
||||
|
||||
namespace CodeEditor.Debugger
|
||||
{
|
||||
public interface IVirtualMachine
|
||||
{
|
||||
event Action<Event> OnVMGotSuspended;
|
||||
event Action<TypeLoadEvent> OnTypeLoad;
|
||||
BreakpointEventRequest CreateBreakpointRequest (Location location);
|
||||
}
|
||||
}
|
|
@ -2,13 +2,13 @@ namespace CodeEditor.Debugger.Implementation
|
|||
{
|
||||
class BreakPoint : IBreakPoint
|
||||
{
|
||||
private readonly Location _location;
|
||||
public string File { get; private set; }
|
||||
public int LineNumber { get; private set; }
|
||||
|
||||
public BreakPoint(Location location)
|
||||
public BreakPoint(string fileName, int lineNumber)
|
||||
{
|
||||
_location = location;
|
||||
File = fileName;
|
||||
LineNumber = lineNumber;
|
||||
}
|
||||
|
||||
public ILocation Location { get { return _location; } }
|
||||
}
|
||||
}
|
|
@ -1,54 +1,89 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MDS = Mono.Debugger.Soft;
|
||||
using Mono.Debugger.Soft;
|
||||
using CodeEditor.Composition;
|
||||
using CodeEditor.Debugger.Backend;
|
||||
|
||||
namespace CodeEditor.Debugger.Implementation
|
||||
{
|
||||
public class BreakpointMediator
|
||||
[Export(typeof(IDebuggerSessionCreationListener))]
|
||||
class BreakPointMediatorFactory : IDebuggerSessionCreationListener
|
||||
{
|
||||
[Import]
|
||||
private IBreakpointProvider BreakpointProvider { get; set; }
|
||||
|
||||
[Import]
|
||||
private ITypeMirrorProvider TypeMirrorProvider { get; set; }
|
||||
|
||||
[Import]
|
||||
private IBreakpointEventRequestFactory BreakpointEventRequestFactory { get; set; }
|
||||
|
||||
public void OnCreate(IDebuggerSession session)
|
||||
{
|
||||
new BreakpointMediator(BreakpointProvider, TypeMirrorProvider, BreakpointEventRequestFactory);
|
||||
}
|
||||
}
|
||||
|
||||
class BreakpointMediator
|
||||
{
|
||||
private readonly IVirtualMachine _vm;
|
||||
private readonly IBreakpointProvider _breakpointProvider;
|
||||
private readonly ITypeMirrorProvider _typeMirrorProvider;
|
||||
private readonly IBreakpointEventRequestFactory _breakpointEventRequestFactory;
|
||||
|
||||
public BreakpointMediator (IVirtualMachine vm, IBreakpointProvider breakpointProvider)
|
||||
public BreakpointMediator(IBreakpointProvider breakpointProvider, ITypeMirrorProvider typeMirrorProvider, IBreakpointEventRequestFactory breakpointEventRequestFactory)
|
||||
{
|
||||
_vm = vm;
|
||||
_breakpointProvider = breakpointProvider;
|
||||
|
||||
_vm.OnTypeLoad += OnTypeLoad;
|
||||
_typeMirrorProvider = typeMirrorProvider;
|
||||
_breakpointEventRequestFactory = breakpointEventRequestFactory;
|
||||
_breakpointProvider.BreakpointAdded += BreakpointAdded;
|
||||
_typeMirrorProvider.TypeLoaded += TypeMirrorLoaded;
|
||||
}
|
||||
|
||||
private void OnTypeLoad (TypeLoadEvent e)
|
||||
private void TypeMirrorLoaded(ITypeMirror typeMirror)
|
||||
{
|
||||
var sourcefiles = e.Type.GetSourceFiles (true);
|
||||
|
||||
if (e.Type.Name == "TestClass")
|
||||
foreach (var breakpoint in typeMirror.SourceFiles.SelectMany(BreakPointsIn))
|
||||
{
|
||||
int a = 4;
|
||||
}
|
||||
|
||||
var breakPoints = _breakpointProvider.Breakpoints;
|
||||
var relevantBreakPoints = breakPoints.Where (bp => sourcefiles.Contains (bp.Location.SourceFile));
|
||||
|
||||
var methodMirrors = e.Type.GetMethods ();
|
||||
foreach (var bp in relevantBreakPoints)
|
||||
{
|
||||
foreach (var method in methodMirrors)
|
||||
{
|
||||
var bestLocation = BestLocationIn (method, bp);
|
||||
if (bestLocation == null)
|
||||
continue;
|
||||
|
||||
_vm.CreateBreakpointRequest (bestLocation).Enable();
|
||||
}
|
||||
IBreakPoint breakpoint1 = breakpoint;
|
||||
var locations = typeMirror.Methods.SelectMany(m => m.Locations).Where(l => LocationsMatch(l, breakpoint1));
|
||||
foreach(var location in locations)
|
||||
CreateEventRequest(location);
|
||||
}
|
||||
}
|
||||
|
||||
private MDS.Location BestLocationIn (MethodMirror method, IBreakPoint bp)
|
||||
private IEnumerable<IBreakPoint> BreakPointsIn(string file)
|
||||
{
|
||||
var locations = method.Locations.ToArray ();
|
||||
var name = method.FullName;
|
||||
return _breakpointProvider.Breakpoints.Where(b => b.File == file);
|
||||
}
|
||||
|
||||
return locations.FirstOrDefault (l => l.SourceFile == bp.Location.SourceFile && l.LineNumber == bp.Location.LineNumber);
|
||||
private bool LocationsMatch(ILocation location, IBreakPoint breakpoint)
|
||||
{
|
||||
return breakpoint.File == location.File && breakpoint.LineNumber == location.LineNumber;
|
||||
}
|
||||
|
||||
private static bool DoesTypeHaveCodeIn(ITypeMirror typeMirror, string sourceFile)
|
||||
{
|
||||
return typeMirror.SourceFiles.Contains(sourceFile);
|
||||
}
|
||||
|
||||
private void BreakpointAdded(IBreakPoint breakpoint)
|
||||
{
|
||||
foreach (var type in TypesWithCodeIn(breakpoint.File))
|
||||
{
|
||||
var locationInMethod = type.Methods.SelectMany(m => m.Locations).FirstOrDefault(l => LocationsMatch(l, breakpoint));
|
||||
if (locationInMethod == null)
|
||||
continue;
|
||||
CreateEventRequest(locationInMethod);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<ITypeMirror> TypesWithCodeIn(string sourceFile)
|
||||
{
|
||||
return _typeMirrorProvider.LoadedTypesMirror.Where(t => DoesTypeHaveCodeIn(t, sourceFile));
|
||||
}
|
||||
|
||||
private void CreateEventRequest(ILocation locationInMethod)
|
||||
{
|
||||
var request = _breakpointEventRequestFactory.Create(locationInMethod);
|
||||
request.Enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace CodeEditor.Debugger.Implementation
|
|||
|
||||
public IBreakPoint GetBreakPointAt(string file, int lineNumber)
|
||||
{
|
||||
return _breakPoints.FirstOrDefault(bp => bp.Location.SourceFile == file && bp.Location.LineNumber == lineNumber);
|
||||
return _breakPoints.FirstOrDefault(bp => bp.File == file && bp.LineNumber == lineNumber);
|
||||
}
|
||||
|
||||
public void ToggleBreakPointAt(string fileName, int lineNumber)
|
||||
|
@ -28,7 +28,7 @@ namespace CodeEditor.Debugger.Implementation
|
|||
Console.WriteLine("Toggling breakpoint at line: "+lineNumber);
|
||||
var breakPoint = GetBreakPointAt(fileName, lineNumber);
|
||||
if (breakPoint == null)
|
||||
AddBreakPoint(new BreakPoint(new Location(lineNumber,fileName)));
|
||||
AddBreakPoint(new BreakPoint(fileName, lineNumber));
|
||||
else
|
||||
RemoveBreakPoint(breakPoint);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ using CodeEditor.Composition;
|
|||
using CodeEditor.Debugger.Backend;
|
||||
using CodeEditor.Debugger.Backend.Sdb;
|
||||
using Mono.Debugger.Soft;
|
||||
using MDS = Mono.Debugger.Soft;
|
||||
|
||||
namespace CodeEditor.Debugger.Implementation
|
||||
{
|
||||
|
@ -16,7 +15,7 @@ namespace CodeEditor.Debugger.Implementation
|
|||
internal class DebuggerSession : IDebuggerSession
|
||||
{
|
||||
private int _debuggerPort;
|
||||
private volatile Mono.Debugger.Soft.VirtualMachine _vm;
|
||||
private volatile VirtualMachine _vm;
|
||||
private MethodEntryEventRequest _methodEntryRequest;
|
||||
private bool _vmSuspended;
|
||||
private readonly Queue<Event> _queuedEvents = new Queue<Event>();
|
||||
|
@ -27,7 +26,7 @@ namespace CodeEditor.Debugger.Implementation
|
|||
public event Action<string> TraceCallback ;
|
||||
private ThreadMirror _mainThread;
|
||||
private readonly List<AssemblyMirror> _loadedAssemblies = new List<AssemblyMirror>();
|
||||
private Dictionary<MDS.Location,BreakpointEventRequest> _breakpointEventRequests = new Dictionary<MDS.Location, BreakpointEventRequest>();
|
||||
private Dictionary<Location,BreakpointEventRequest> _breakpointEventRequests = new Dictionary<Location, BreakpointEventRequest>();
|
||||
private readonly List<SdbAssemblyMirror> _debugAssemblies = new List<SdbAssemblyMirror>();
|
||||
|
||||
public void Start(int debuggerPort)
|
||||
|
@ -325,7 +324,7 @@ namespace CodeEditor.Debugger.Implementation
|
|||
return new ThreadsRequest();
|
||||
}
|
||||
|
||||
public BreakpointEventRequest CreateBreakpointRequest(Mono.Debugger.Soft.Location location)
|
||||
public BreakpointEventRequest CreateBreakpointRequest(Location location)
|
||||
{
|
||||
var request = _vm.CreateBreakpointRequest(location);
|
||||
_breakpointEventRequests[location] = request;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
using CodeEditor.Composition;
|
||||
using Mono.Debugger.Soft;
|
||||
|
||||
namespace CodeEditor.Debugger.Implementation
|
||||
{
|
||||
[Export]
|
||||
public class ExecutingLineProvider
|
||||
{
|
||||
private int _currentLocation;
|
||||
private readonly IDebuggerSession _debuggerSession;
|
||||
|
||||
[ImportingConstructor]
|
||||
public ExecutingLineProvider(IDebuggerSession debuggerSession)
|
||||
{
|
||||
_debuggerSession = debuggerSession;
|
||||
_debuggerSession.VMGotSuspended += VMGotSuspended;
|
||||
}
|
||||
|
||||
private void VMGotSuspended(Event e)
|
||||
{
|
||||
var frames = e.Thread.GetFrames();
|
||||
_currentLocation = frames.Length==0 ? 0 : frames[0].LineNumber - 1;
|
||||
}
|
||||
|
||||
public int LineNumber
|
||||
{
|
||||
get { return _currentLocation; }
|
||||
}
|
||||
}
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче