Skip to content

Commit e77c0b9

Browse files
committed
Handle exceptions thrown by PEReader
1 parent 68dcbe3 commit e77c0b9

File tree

1 file changed

+46
-29
lines changed

1 file changed

+46
-29
lines changed

src/Shared/StackTrace/StackFrame/PortablePdbReader.cs

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
@@ -66,60 +66,77 @@ public void PopulateStackFrame(StackFrameInfo frameInfo, MethodBase method, int
6666

6767
private MetadataReader GetMetadataReader(string assemblyPath)
6868
{
69-
MetadataReaderProvider provider = null;
70-
if (!_cache.TryGetValue(assemblyPath, out provider))
69+
if (string.IsNullOrEmpty(assemblyPath))
70+
{
71+
return null;
72+
}
73+
74+
if (_cache.TryGetValue(assemblyPath, out var provider))
75+
{
76+
return provider.GetMetadataReader();
77+
}
78+
79+
if (TryGetPdbPath(assemblyPath, out var pdbPath) && File.Exists(pdbPath))
7180
{
72-
var pdbPath = GetPdbPath(assemblyPath);
81+
var pdbStream = File.OpenRead(pdbPath);
7382

74-
if (!string.IsNullOrEmpty(pdbPath) && File.Exists(pdbPath) && IsPortable(pdbPath))
83+
if (IsPortable(pdbStream))
7584
{
76-
var pdbStream = File.OpenRead(pdbPath);
7785
provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream);
78-
}
7986

80-
_cache[assemblyPath] = provider;
87+
_cache[assemblyPath] = provider;
88+
89+
return provider.GetMetadataReader();
90+
}
8191
}
8292

83-
return provider?.GetMetadataReader();
93+
return null;
8494
}
8595

86-
private static string GetPdbPath(string assemblyPath)
96+
private static bool TryGetPdbPath(string assemblyPath, out string pdbPath)
8797
{
88-
if (string.IsNullOrEmpty(assemblyPath))
89-
{
90-
return null;
91-
}
92-
9398
if (File.Exists(assemblyPath))
9499
{
95100
var peStream = File.OpenRead(assemblyPath);
96101

97102
using (var peReader = new PEReader(peStream))
98103
{
99-
foreach (var entry in peReader.ReadDebugDirectory())
104+
try
100105
{
101-
if (entry.Type == DebugDirectoryEntryType.CodeView)
106+
foreach (var entry in peReader.ReadDebugDirectory())
102107
{
103-
var codeViewData = peReader.ReadCodeViewDebugDirectoryData(entry);
104-
var peDirectory = Path.GetDirectoryName(assemblyPath);
105-
return Path.Combine(peDirectory, Path.GetFileName(codeViewData.Path));
108+
if (entry.Type == DebugDirectoryEntryType.CodeView)
109+
{
110+
var codeViewData = peReader.ReadCodeViewDebugDirectoryData(entry);
111+
var peDirectory = Path.GetDirectoryName(assemblyPath);
112+
pdbPath = Path.Combine(peDirectory, Path.GetFileName(codeViewData.Path));
113+
return true;
114+
}
106115
}
107116
}
117+
catch
118+
{
119+
pdbPath = default;
120+
return false;
121+
}
108122
}
109123
}
110124

111-
return null;
125+
pdbPath = default;
126+
return false;
112127
}
113128

114-
private static bool IsPortable(string pdbPath)
129+
private static bool IsPortable(Stream pdbStream)
115130
{
116-
using (var pdbStream = File.OpenRead(pdbPath))
117-
{
118-
return pdbStream.ReadByte() == 'B' &&
119-
pdbStream.ReadByte() == 'S' &&
120-
pdbStream.ReadByte() == 'J' &&
121-
pdbStream.ReadByte() == 'B';
122-
}
131+
var result =
132+
pdbStream.ReadByte() == 'B' &&
133+
pdbStream.ReadByte() == 'S' &&
134+
pdbStream.ReadByte() == 'J' &&
135+
pdbStream.ReadByte() == 'B';
136+
137+
pdbStream.Seek(0, SeekOrigin.Begin);
138+
139+
return result;
123140
}
124141

125142
public void Dispose()

0 commit comments

Comments
 (0)