Closed kevingosse closed 3 years ago
It may be a file vs loaded layout issue with is controlled with the isVirtual flag passed to the ModuleInfo constructor. There isn't an easy way to determine the correct layout other than trying both. On Windows it is always "loaded" layout. It is something I want to try in clrmd (with Lee's ok) when I get time.
Can you try the latest dotnet-dump/SOS from master dump the module correctly? modules -v
is the command. The module service tries both layout types and uses whatever returns a valid header, version, IsManaged flag, etc.
Can you try the latest dotnet-dump/SOS from master dump the module correctly? modules -v is the command. The module service tries both layout types and uses whatever returns a valid header, version, IsManaged flag, etc.
Does it need to be the version from master? With the one currently installed I get:
/root/temp/bin/Release/net5.0/temp.dll
Address: 00007FC95FBF1000
FileSize: 00002000
TimeStamp: 00000000
IsManaged: True
The PEReader fails when trying to read address 0x00007fc95fbf3008
. This indeed seems to be outside of the module range.
The released dotnet-dump doesn't try both layouts.
Got it, gonna give it a try.
In any case, I confirm that switching the value of isVirtual
in the ModuleInfo constructor for that module fixes the issue, so I think you're on the right track.
With the dotnet-dump built from master, I get:
35 /root/temp/bin/Release/net5.0/temp.dll
Address: 00007FC95FBF1000
ImageSize: 00006000
IsPEImage: True
IsManaged: True
IsFileLayout: True
IndexFileSize: 32768
IndexTimeStamp: 3308427098
Version: 1.0.0.0
PdbInfo: 48166658-5a5e-4728-9767-5747633809b0 1 /root/temp/obj/Release/net5.0/temp.pdb
BuildId: <none>
Trying both works for me, I'll be keeping that workaround for now (I'm using a custom version of ClrMD for this project anyway)
public PEImage? GetPEImage()
{
try
{
var image = new PEImage(new ReadVirtualStream(DataReader, (long)ImageBase, IndexFileSize), leaveOpen: false, isVirtual: _isVirtual);
if (image.PEHeader == null)
{
image = new PEImage(new ReadVirtualStream(DataReader, (long)ImageBase, IndexFileSize), leaveOpen: false, isVirtual: !_isVirtual);
}
if (!_isManaged.HasValue)
_isManaged = image.IsManaged;
return image.IsValid ? image : null;
}
catch
{
return null;
}
}
Thanks for the help 👍
Since we don't have a good way to detect this, I think the workaround you posted here is likely what we'll go with (trying both layouts). I'll include this in the next release of ClrMD.
Getting the PEImage of some assemblies inside of a Linux memory dump fail, even though the PE header should be valid (at least I believe so).
As a simple repro, I create a console application with .NET 5:
Getting the PE header of
temp.dll
fails with the error "System.IO.EndOfStreamException: 'Unable to read beyond the end of the stream.'" :Both the DOS header check and the PE signature check are successful, so I assume the PE header should be valid.
Note that it might be an issue with System.Reflection.PortableExecutable.PEReader rather than ClrMD itself. Or it could be the
ReadVirtualStream
. I'm trying to figure out exactly what's wrong, but maybe somebody already has an idea.