Repository navigation
BadImageFormatException : Bad IL format when using base #13926
Copy link
Copy link
Closed
Labels
Area-Compiler-CheckingType checking, attributes and all aspects of logic checkingType checking, attributes and all aspects of logic checkingBugImpact-Medium(Internal MS Team use only) Describes an issue with moderate impact on existing code.(Internal MS Team use only) Describes an issue with moderate impact on existing code.
Milestone
Description
Activity
Reproduces on
module Testing open System.Text.Json open System.Text.Json.Serialization type StringTrimJsonSerializer(o: JsonSerializerOptions) = inherit JsonConverter<string>() override this.Read(reader, _, _) = match reader.TokenType with | JsonTokenType.String -> reader.GetString().Trim() | _ -> JsonException("Type is not a string") |> raise override this.Write(writer, objectToWrite, options) = base.Write(writer, objectToWrite, options) type SomeType = { Foo: string} let serialize item = let options = JsonSerializerOptions() StringTrimJsonSerializer options |> options.Converters.Add JsonSerializer.Serialize(item, options) [<EntryPoint>] let main _ = { Foo = "a" } |> serialize 0
Does not reproduce on:
module Testing open System.Text.Json open System.Text.Json.Serialization type StringTrimJsonSerializer(o: JsonSerializerOptions) = inherit JsonConverter<string>() override this.Read(reader, _, _) = match reader.TokenType with | JsonTokenType.String -> reader.GetString().Trim() | _ -> JsonException("Type is not a string") |> raise override this.Write(writer, objectToWrite, options) = base.Write(writer, objectToWrite, options) type SomeType = { Foo: int } let serialize item = let options = JsonSerializerOptions() StringTrimJsonSerializer options |> options.Converters.Add JsonSerializer.Serialize(item, options) [<EntryPoint>] let main _ = { Foo = 1 } |> serialize 0
Both release and debug
@vzarytovskii The latter never calls the
StringTrimJsonSerializer.Writemethod (there's no string in the type), so it makes sense that it doesn't fail. The JIT never has to emit the method, so you won't get theBadImageFormatException.The problem seems to be that
basehere is an abstract class and theWritemethod itself is alsoabstract. In other words, it should never compile. If you try this with F# classes (abstract A, concrete B derives from A) then ifBusesbase.Fooit'll give a compile error saying that you cannot call an abstract method.The same is true here, but for some reason, F# doesn't consider it an abstract method.
- addedArea-Compiler-CheckingType checking, attributes and all aspects of logic checkingType checking, attributes and all aspects of logic checkingArea-Compiler-CodeGenIlxGen, ilwrite and things at the backendIlxGen, ilwrite and things at the backend
on Sep 21, 2022 - added a commit that references this issue
on Mar 5, 2024 - added a commit that references this issue
on Mar 5, 2024
Metadata
Metadata
Assignees
Labels
Area-Compiler-CheckingType checking, attributes and all aspects of logic checkingType checking, attributes and all aspects of logic checkingBugImpact-Medium(Internal MS Team use only) Describes an issue with moderate impact on existing code.(Internal MS Team use only) Describes an issue with moderate impact on existing code.
Type
Projects
- StatusShow more project fieldsDone
Using
base.XXXto call a base method causes aBadImageFormatExceptionto be raised.EDIT: it looks like F# allowing me to call an abstract method, as the
baseclass is abstract. This, I believe, should not be allowed and JIT therefore throws aBadImageFormatException. If you try to write code in F# with anAbstractClassand a derived class, you'd receive a normal compile-time error.Repro steps
The following code (requires Giraffe and FsUnit to run the test) throws a
BadImageFormatExceptionExpected behavior
Should call the base method or give compile error if such method doesn't exist.
Actual behavior
Throws:
Known workarounds
Don't use
basein a derived method.Related information
On dotnet 6, using
System.Text.Jsonserialization BCL classes, Windows 10/11.EDIT, the IL of the offending code looks as follows (Release build):