scalac-profiling quietly failing and providing no output in some cases
Hi there. This is a super useful tool but unfortunately I appear to be experiencing some difficulties with it at the moment.
I've got -Vstatistics set and info associated with that flag is coming through as expected. Importantly on some of our modules we are getting expected results (deterministically), so I think the plugin must be set up correctly, but most are having the issue below, where the flamegraph file is empty and the following macro / implicit fields are all empty.
There isn't an obvious difference between the ones that are working and the ones that aren't. It's worth noting that many of these modules spend up to 5 minutes in implicit resolution, so perhaps it's overflowing something. Many fail that don't have this issue though.
scalacProfiling version: 1.1.0-RC2 Scala Version: 2.13.12 sbt version: 1.9.6
Apologies if this is not much to go on, happy to try and provide any other info I can. Perhaps scalac has some verbose mode I could turn on?
[info] Writing graph to [...]/implicit-searches-1714143535655.flamegraph
[info] Writing graph to [...]/implicit-searches-global.flamegraph
[info] Writing graph to [...]/macros-1714143535655.flamegraph
[info] Macro data per call-site:
[info] Map()
[info] Macro data per file:
[info] HashMap()
[info] Macro data in total:
[info] MacroInfo(expandedMacros = 0, expandedNodes = 0, expansionNanos = 0L)
[info] Macro repeated expansions:
[info] Map()
[info] Macro expansions by type:
[info] LinkedHashMap()
[info] Implicit searches by position:
[info] LinkedHashMap()
[info] Implicit searches by type:
[info] LinkedHashMap()
Can you share the JVM options set for SBT when running compilation to build flamegraphs data by scalac-profiling? There may be a situation where resources are exceeded. However, it's unlikely that SBT will continue to function in such cases.
Also, the -Vstatistics option and scalac-profiling plugin must be set up for all SBT submodules / or set up for the entire build (ThisBuild scope).
Thanks for getting back to me Daniel.
Here are all the java options coming through to sbt:
sbt:root> show javaOptions
...
[info] javaOptions
[info] List(-server, -XX:ReservedCodeCacheSize=192m, -Xss2m)
sbt:root> show javacOptions
...
[info] javacOptions
[info] List(-source, 17, -target, 17, -encoding, utf8, -g)
And below I've added the scalacOptions. I noticed one module didn't have -Vstatistics so I added ThisBuild / scalacOptions += "-Vstatistics" to build.sbt but that didn't alter the behaviour.
sbt:root> show scalacOptions
...
[info] scalacOptions
[info] List(-encoding, utf8, -deprecation, -feature, -unchecked, -language:existentials, -language:experimental.macros, -language:higherKinds, -language:implicitConversions, -Xlint:adapted-args, -Xlint:by-name-right-associative, -Xlint:constant, -Xlint:delayedinit-select, -Xlint:deprecation, -Xlint:doc-detached, -Xlint:inaccessible, -Xlint:infer-any, -Xlint:missing-interpolator, -Xlint:nullary-override, -Xlint:nullary-unit, -Xlint:option-implicit, -Xlint:package-object-classes, -Xlint:poly-implicit-overload, -Xlint:private-shadow, -Xlint:stars-align, -Xlint:unsound-match, -Yno-adapted-args, -Ypartial-unification, -Ywarn-dead-code, -Ywarn-extra-implicit, -Ywarn-nullary-override, -Ywarn-nullary-unit, -Ywarn-numeric-widen, -Ywarn-value-discard, -Ywarn-unused:implicits, -Ywarn-unused:imports, -Ywarn-unused:locals, -Ywarn-unused:params, -Ywarn-unused:patvars, -Ywarn-unused:privates, -Ywarn-unused:nowarn, -Wconf:cat=other-implicit-type:s, -Ybackend-parallelism, 8, -Ymacro-annotations, -Vstatistics, -Ycache-plugin-class-loader:last-modified, -P:scalac-profiling:generate-global-flamegraph, -P:scalac-profiling:generate-macro-flamegraph, -P:scalac-profiling:generate-profiledb, -P:scalac-profiling:show-profiles)
I meant options set for the SBT itself:
❯ sbt -d
...
java
-Dfile.encoding=UTF-8
-server
-XX:ReservedCodeCacheSize=512m
...
-Xmx8G
Anyway, consider setting quite a significant Xmx. But at this point, I don't have any particular clues.
I see what you mean. Yes I currently have that set to 16G.
java
-Dfile.encoding=UTF-8
-Xms16384m
-Xmx16384m
-Xss4M
-XX:ReservedCodeCacheSize=512m
-Dprofiling=true
...
-debug
Hi again. I had some time to do some trial and error here and it seems that if splain plugin is enabled it breaks scalac profiling. I don't know if that's a strange interaction in our codebase or a wider issue, but seems like all is working now - looking forward to doing some testing.
Unrelatedly sbt doesn't seem to recognise the profilingWarmupDuration. I seem to be getting reasonably stable outputs so I'm not too worried but not sure if I'm missing something obvious.
Either way - happy on my end, feel free to close out this issue if you don't think the splain thing is a wider issue.
Hi @sjorn3! Thanks for going deeper into the issue!
Unrelatedly sbt doesn't seem to recognise the profilingWarmupDuration. I seem to be getting reasonably stable outputs so I'm not too worried but not sure if I'm missing something obvious.
Was the SBT scalac-profiling plugin enabled (link to the docs)? profilingWarmupDuration comes from this plugin, so it must be enabled.
I had some time to do some trial and error here and it seems that if splain plugin is enabled it breaks scalac profiling.
Hmm, that's interesting. Perhaps scalac-profiling doesn't stack well with the splain plugin indeed. I haven't seen anything related to this, maybe will have some time to investigate this behavior.
fwiw, much (not all) of splain’s functionality was integrated into the compiler, as per 2.13.6 release notes
Without digging into the details, I'd say that any plugin that manipulates/alters implicit search info in the scalac might cause issues with integration with the scalac-profiling. But anyway, it's interesting what precisely breaks down.