-
Notifications
You must be signed in to change notification settings - Fork 587
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Expected a null constant." error when saving assembly with pdb #550
Comments
Also, unrelated to the original issue, and could be my misunderstanding, but I can't really run this code:
as it will fail with |
It's memory mapped and you're using Windows which doesn't allow writing to the file until it's closed. You could instead read all bytes from the file and pass in the byte[] to the Load() method to load it that way and nothing gets memory mapped. |
I think you need to add an assembly resolver to fix this. See the README on how to do that. |
Yeah, reading from byte array works fine. That's what I also did in the sample.
Hm. In my actual project I did use an assembly resolver, where I initially found this issue. I trimmed everything down until I got this minimal sample. |
Make sure the assembly resolver finds the assembly with the enum CompareOptions and any other assemblies it references, if any. |
I met this issue, too. Could we just skip this error? Sometimes we cannot find every dll reference, but we still want some pdb info kept. However with this issue we can only get an empty pdb. I have written some simple code to bypass this but I don't know if it will cause more problems, like making this pdb unusable. dnlib/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs Lines 144 to 152 in 1e0ec26
case ElementType.Class when value is not byte[] && value is not null:
var realElementType = ConstantUser.GetElementType(value);
if (realElementType != ElementType.End) {
writer.WriteByte((byte)realElementType);
WritePrimitiveValue(writer, realElementType, value);
WriteTypeDefOrRef(writer, type.ToTypeDefOrRef());
return;
}
break; |
As a workaround, you can remove the "invalid" constants from the PDB: foreach (MethodDef method in new MemberFinder().FindAll(module).MethodDefs.Keys)
{
IList<PdbConstant>? constants = method.Body?.PdbMethod?.Scope?.Constants;
if (constants is not null)
{
for (int i = constants.Count - 1; i >= 0; i--)
{
// workaround for https://github.com/0xd4d/dnlib/issues/550
// remove any constant with a reference type where the value is not a byte[] or null.
PdbConstant constant = constants[i];
if (constant.Type?.ElementType is ElementType.Class &&
constant.Value is not null and not byte[])
{
constants.RemoveAt(i);
}
}
}
} |
I noticed this issue only happens when I used "local const" in the code, specifically when const type is an enum from another assembly.
For example, this method:
Simply replacing
const CompareOptions options
withCompareOptions options
will fix the problem, so we have a workaround, though this bug is confusing.Repro project (both dll project and executable console app):
ClassLibrary1.zip
The text was updated successfully, but these errors were encountered: