public void EditAndContinueLambdaAndClosureMap_NegativeSyntaxOffsets() { var slots = ImmutableArray <LocalSlotDebugInfo> .Empty; var closures = ImmutableArray.Create( new ClosureDebugInfo(-100, new DebugId(0, 0)), new ClosureDebugInfo(10, new DebugId(1, 0)), new ClosureDebugInfo(-200, new DebugId(2, 0))); var lambdas = ImmutableArray.Create( new LambdaDebugInfo(20, new DebugId(0, 0), 1), new LambdaDebugInfo(-50, new DebugId(1, 0), 0), new LambdaDebugInfo(-180, new DebugId(2, 0), LambdaDebugInfo.StaticClosureOrdinal)); var cmw = new BlobBuilder(); new EditAndContinueMethodDebugInformation(0x7b, slots, closures, lambdas).SerializeLambdaMap(cmw); var bytes = cmw.ToImmutableArray(); AssertEx.Equal(new byte[] { 0x7C, 0x80, 0xC8, 0x03, 0x64, 0x80, 0xD2, 0x00, 0x80, 0xDC, 0x03, 0x80, 0x96, 0x02, 0x14, 0x01 }, bytes); var deserialized = EditAndContinueMethodDebugInformation.Create(default(ImmutableArray <byte>), bytes); AssertEx.Equal(closures, deserialized.Closures); AssertEx.Equal(lambdas, deserialized.Lambdas); }
public static EditAndContinueMethodDebugInformation GetEncMethodDebugInfo(byte[] customDebugInfoBlob) { var localSlots = CustomDebugInfoReader.TryGetCustomDebugInfoRecord(customDebugInfoBlob, CustomDebugInfoKind.EditAndContinueLocalSlotMap); var lambdaMap = CustomDebugInfoReader.TryGetCustomDebugInfoRecord(customDebugInfoBlob, CustomDebugInfoKind.EditAndContinueLambdaMap); return(EditAndContinueMethodDebugInformation.Create(localSlots, lambdaMap)); }
public static unsafe EditAndContinueMethodDebugInformation GetEncMethodDebugInfo(this ISymUnmanagedReader3 symReader, MethodDefinitionHandle handle) { const int S_OK = 0; if (symReader is ISymUnmanagedReader4 symReader4) { int hr = symReader4.GetPortableDebugMetadata(out byte *metadata, out int size); Marshal.ThrowExceptionForHR(hr); if (hr == S_OK) { var pdbReader = new MetadataReader(metadata, size); ImmutableArray <byte> GetCdiBytes(Guid kind) => TryGetCustomDebugInformation(pdbReader, handle, kind, out var info) ? pdbReader.GetBlobContent(info.Value) : default(ImmutableArray <byte>); return(EditAndContinueMethodDebugInformation.Create( compressedSlotMap: GetCdiBytes(PortableCustomDebugInfoKinds.EncLocalSlotMap), compressedLambdaMap: GetCdiBytes(PortableCustomDebugInfoKinds.EncLambdaAndClosureMap))); } } var cdi = CustomDebugInfoUtilities.GetCustomDebugInfoBytes(symReader, handle, methodVersion: 1); if (cdi == null) { return(EditAndContinueMethodDebugInformation.Create(default(ImmutableArray <byte>), default(ImmutableArray <byte>))); } return(GetEncMethodDebugInfo(cdi)); }
public void EditAndContinueLambdaAndClosureMap_NegativeSyntaxOffsets() { var slots = ImmutableArray <LocalSlotDebugInfo> .Empty; var closures = ImmutableArray.Create( new ClosureDebugInfo(-100), new ClosureDebugInfo(10), new ClosureDebugInfo(-200)); var lambdas = ImmutableArray.Create( new LambdaDebugInfo(20, 1), new LambdaDebugInfo(-50, 0), new LambdaDebugInfo(-180, -1)); var customMetadata = new Cci.MemoryStream(); var cmw = new Cci.BinaryWriter(customMetadata); new EditAndContinueMethodDebugInformation(0x7b, slots, closures, lambdas).SerializeLambdaMap(cmw); var bytes = customMetadata.ToImmutableArray(); AssertEx.Equal(new byte[] { 0x7C, 0x80, 0xC8, 0x03, 0x64, 0x80, 0xD2, 0x00, 0x80, 0xDC, 0x02, 0x80, 0x96, 0x01, 0x14, 0x00 }, bytes); var deserialized = EditAndContinueMethodDebugInformation.Create(default(ImmutableArray <byte>), bytes); AssertEx.Equal(closures, deserialized.Closures); AssertEx.Equal(lambdas, deserialized.Lambdas); }
public void EditAndContinueLambdaAndClosureMap_NoLambdas() { // should not happen in practice, but EditAndContinueMethodDebugInformation should handle it just fine var slots = ImmutableArray <LocalSlotDebugInfo> .Empty; var closures = ImmutableArray <ClosureDebugInfo> .Empty; var lambdas = ImmutableArray <LambdaDebugInfo> .Empty; var cmw = new BlobBuilder(); new EditAndContinueMethodDebugInformation( 10, slots, closures, lambdas ).SerializeLambdaMap(cmw); var bytes = cmw.ToImmutableArray(); AssertEx.Equal(new byte[] { 0x0B, 0x01, 0x00 }, bytes); var deserialized = EditAndContinueMethodDebugInformation.Create( default(ImmutableArray <byte>), bytes ); AssertEx.Equal(closures, deserialized.Closures); AssertEx.Equal(lambdas, deserialized.Lambdas); }
public void EditAndContinueLambdaAndClosureMap_NoClosures() { var slots = ImmutableArray <LocalSlotDebugInfo> .Empty; var closures = ImmutableArray <ClosureDebugInfo> .Empty; var lambdas = ImmutableArray.Create( new LambdaDebugInfo(20, new DebugId(0, 0), LambdaDebugInfo.StaticClosureOrdinal) ); var cmw = new BlobBuilder(); new EditAndContinueMethodDebugInformation( -1, slots, closures, lambdas ).SerializeLambdaMap(cmw); var bytes = cmw.ToImmutableArray(); AssertEx.Equal(new byte[] { 0x00, 0x01, 0x00, 0x15, 0x01 }, bytes); var deserialized = EditAndContinueMethodDebugInformation.Create( default(ImmutableArray <byte>), bytes ); AssertEx.Equal(closures, deserialized.Closures); AssertEx.Equal(lambdas, deserialized.Lambdas); }
public static EditAndContinueMethodDebugInformation GetEncMethodDebugInfo( byte[] customDebugInfoBlob ) { return(EditAndContinueMethodDebugInformation.Create( CustomDebugInfoUtilities.GetEditAndContinueLocalSlotMapRecord(customDebugInfoBlob), CustomDebugInfoUtilities.GetEditAndContinueLambdaMapRecord(customDebugInfoBlob) )); }
public static EditAndContinueMethodDebugInformation GetEncMethodDebugInfo(this ISymUnmanagedReader3 symReader, MethodDefinitionHandle handle) { var cdi = CustomDebugInfoUtilities.GetCustomDebugInfoBytes(symReader, handle, methodVersion: 1); if (cdi == null) { return(EditAndContinueMethodDebugInformation.Create(default(ImmutableArray <byte>), default(ImmutableArray <byte>))); } return(GetEncMethodDebugInfo(cdi)); }
public void EditAndContinueLocalSlotMap_NegativeSyntaxOffsets() { var slots = ImmutableArray.Create( new LocalSlotDebugInfo(SynthesizedLocalKind.UserDefined, new LocalDebugId(-1, 10)), new LocalSlotDebugInfo( SynthesizedLocalKind.TryAwaitPendingCaughtException, new LocalDebugId(-20000, 10) ) ); var closures = ImmutableArray <ClosureDebugInfo> .Empty; var lambdas = ImmutableArray <LambdaDebugInfo> .Empty; var cmw = new BlobBuilder(); new EditAndContinueMethodDebugInformation( 123, slots, closures, lambdas ).SerializeLocalSlots(cmw); var bytes = cmw.ToImmutableArray(); AssertEx.Equal( new byte[] { 0xFF, 0xC0, 0x00, 0x4E, 0x20, 0x81, 0xC0, 0x00, 0x4E, 0x1F, 0x0A, 0x9A, 0x00, 0x0A }, bytes ); var deserialized = EditAndContinueMethodDebugInformation.Create( bytes, default(ImmutableArray <byte>) ).LocalSlots; AssertEx.Equal(slots, deserialized); }
public override EditAndContinueMethodDebugInformation GetDebugInfo( MethodDefinitionHandle methodHandle ) => EditAndContinueMethodDebugInformation.Create( compressedSlotMap: GetCdiBytes( methodHandle, PortableCustomDebugInfoKinds.EncLocalSlotMap ), compressedLambdaMap: GetCdiBytes( methodHandle, PortableCustomDebugInfoKinds.EncLambdaAndClosureMap ) );
public override EditAndContinueMethodDebugInformation GetDebugInfo( MethodDefinitionHandle methodHandle ) { var methodToken = MetadataTokens.GetToken(methodHandle); byte[] debugInfo; try { debugInfo = _symReader.GetCustomDebugInfo(methodToken, _version); } catch (ArgumentOutOfRangeException) { // Sometimes the debugger returns the HRESULT for ArgumentOutOfRangeException, rather than E_FAIL, // for methods without custom debug info (https://github.com/dotnet/roslyn/issues/4138). debugInfo = null; } catch (Exception e) when(FatalError.ReportAndCatch(e)) // likely a bug in the compiler/debugger { throw new InvalidDataException(e.Message, e); } try { ImmutableArray <byte> localSlots, lambdaMap; if (debugInfo != null) { localSlots = CustomDebugInfoReader.TryGetCustomDebugInfoRecord( debugInfo, CustomDebugInfoKind.EditAndContinueLocalSlotMap ); lambdaMap = CustomDebugInfoReader.TryGetCustomDebugInfoRecord( debugInfo, CustomDebugInfoKind.EditAndContinueLambdaMap ); } else { localSlots = lambdaMap = default; } return(EditAndContinueMethodDebugInformation.Create(localSlots, lambdaMap)); } catch (InvalidOperationException e) when(FatalError.ReportAndCatch(e)) // likely a bug in the compiler/debugger { // TODO: CustomDebugInfoReader should throw InvalidDataException throw new InvalidDataException(e.Message, e); } }
public void EditAndContinueLocalSlotMap_NegativeSyntaxOffsets() { var slots = ImmutableArray.Create( new LocalSlotDebugInfo(SynthesizedLocalKind.UserDefined, new LocalDebugId(-1, 10)), new LocalSlotDebugInfo(SynthesizedLocalKind.TryAwaitPendingCaughtException, new LocalDebugId(-20000, 10))); var customMetadata = new Cci.MemoryStream(); var cmw = new Cci.BinaryWriter(customMetadata); new EditAndContinueMethodDebugInformation(slots).SerializeLocalSlots(cmw); var bytes = customMetadata.ToImmutableArray(); AssertEx.Equal(new byte[] { 0xFE, 0xC0, 0x00, 0x4E, 0x20, 0x81, 0xC0, 0x00, 0x4E, 0x1F, 0x0A, 0x9A, 0x00, 0x0A }, bytes); var deserialized = EditAndContinueMethodDebugInformation.Create(bytes).LocalSlots; AssertEx.Equal(slots, deserialized); }
public void UncompressSlotMap1() { using (new EnsureEnglishUICulture()) { var e = Assert.Throws <InvalidDataException>(() => EditAndContinueMethodDebugInformation.Create(ImmutableArray.Create(new byte[] { 0x01, 0x68, 0xff }), ImmutableArray <byte> .Empty)); Assert.Equal("Invalid data at offset 3: 01-68-FF*", e.Message); e = Assert.Throws <InvalidDataException>(() => EditAndContinueMethodDebugInformation.Create(ImmutableArray.Create(new byte[] { 0x01, 0x68, 0xff, 0xff, 0xff, 0xff }), ImmutableArray <byte> .Empty)); Assert.Equal("Invalid data at offset 3: 01-68-FF*FF-FF-FF", e.Message); e = Assert.Throws <InvalidDataException>(() => EditAndContinueMethodDebugInformation.Create(ImmutableArray.Create(new byte[] { 0xff, 0xff, 0xff, 0xff }), ImmutableArray <byte> .Empty)); Assert.Equal("Invalid data at offset 1: FF*FF-FF-FF", e.Message); byte[] largeData = new byte[10000]; largeData[400] = 0xff; largeData[401] = 0xff; largeData[402] = 0xff; largeData[403] = 0xff; largeData[404] = 0xff; largeData[405] = 0xff; e = Assert.Throws <InvalidDataException>(() => EditAndContinueMethodDebugInformation.Create(ImmutableArray.Create(largeData), ImmutableArray <byte> .Empty)); Assert.Equal( "Invalid data at offset 401: 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-FF*FF-FF-FF-FF-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-" + "00-00-00-00-00-00-00-00-00-00-00...", e.Message); } }
public void EditAndContinueLambdaAndClosureMap_NoClosures() { var slots = ImmutableArray <LocalSlotDebugInfo> .Empty; var closures = ImmutableArray <ClosureDebugInfo> .Empty; var lambdas = ImmutableArray.Create(new LambdaDebugInfo(20, LambdaDebugInfo.StaticClosureOrdinal)); var customMetadata = new Cci.MemoryStream(); var cmw = new Cci.BinaryWriter(customMetadata); new EditAndContinueMethodDebugInformation(-1, slots, closures, lambdas).SerializeLambdaMap(cmw); var bytes = customMetadata.ToImmutableArray(); AssertEx.Equal(new byte[] { 0x00, 0x01, 0x00, 0x15, 0x01 }, bytes); var deserialized = EditAndContinueMethodDebugInformation.Create(default(ImmutableArray <byte>), bytes); AssertEx.Equal(closures, deserialized.Closures); AssertEx.Equal(lambdas, deserialized.Lambdas); }