Classfile API proposal to integrate basic print functionality directly to ClassModel and MethodModel

Adam Sotona adam.sotona at oracle.com
Thu Jul 21 15:39:49 UTC 2022


As it is probably not the best to print to System.err and also filling large method print into an Exception message is overkill.
I would suggest to create a new Classfile.Option for debug output, where user can specify a Consumer<String> as handler for such situations.
For verification purposes such handler is a direct method argument, which can be unified to use the new Option.

BTW: turning unfinished CodeBuilder into a MethodModel to re-use ClassPrinter is a bit tricky, however I already have a prototype and it seems to be valuable feature

And one trick to debug stack map generation I almost forgot – look at the StackMapGenerator Javadoc:
https://htmlpreview.github.io/?https://raw.githubusercontent.com/openjdk/jdk-sandbox/classfile-api-javadoc-branch/doc/classfile-api/javadoc/jdk/classfile/impl/StackMapGenerator.html


In case of an exception during the Generator loop there is just minimal information available in the exception message.

To determine root cause of the exception it is recommended to enable debug logging of the Generator in one of the two modes using following java.lang.System properties:
-Djdk.classfile.impl.StackMapGenerator.DEBUG=true
Activates debug logging with basic information + generated stack map frames in case of success. It also re-runs with enabled full trace logging in case of an error or exception.
-Djdk.classfile.impl.StackMapGenerator.TRACE=true
Activates full detailed tracing of the generator process for all invocations.


From: Brian Goetz <brian.goetz at oracle.com>
Date: Thursday, 21 July 2022 16:15
To: Michael van Acken <michael.van.acken at gmail.com>
Cc: Adam Sotona <adam.sotona at oracle.com>, classfile-api-dev at openjdk.org <classfile-api-dev at openjdk.org>
Subject: Re: Classfile API proposal to integrate basic print functionality directly to ClassModel and MethodModel
I think the root of the problem here is that CodeBuilder combines the “build my method” with stackmap generation, and if the latter fails, nothing is produced.  And when stack map generation fails, you’d like to see a javap-like output so you can see what you did wrong.

You can suppress stack map generation with an Option, and then you’ll get a classfile out, but that is probably a little hard to discover.

This is a more general problem, not just for stack maps; there are other things that can cause code generation to fail (e.g., forward branch to a label that is never defined; invalid labels in exception tables; etc.)  The main vector we have for feeding back information is the exception message, but putting the entire javap output of the method body in the exception message might be too much (but might not be, since any exception from building a classfile will trigger a round of debugging.)

Any thoughts on how you would like to see this information fed back?


Is there a way to print out a trace of parts fed to CodeBuilder instances?

Just this morning I had Classfile die on me because of a stack underflow,
and it was quite hard to find out which parts were missing from the Code
attribute.  And that with a Code totalling just 5 instructions...

If there would have been bytes output, then I could have inspected the
situation with javap.  But if I mess up and pass inconsistent data to
CodeBuilder, causing it to throw instead of producing a byte array, then
I have an observability gap.

-- mva


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20220721/851133ef/attachment.htm>


More information about the classfile-api-dev mailing list