Yes. Hi. I'm Johannes Pechberger. As I was already introduced, I work at the sub machine.
It's another great distribution of the OpenTraderK. So I worked since the beginning of last year
on my new project on Async Get Stack Trace. It's essentially an improved version of the
Async Get Call Trace API. And I think many of you probably don't know this API. I didn't know it
before I started this project. But essentially, it's related to profiling. So how does profiling
work? Some of you might have already seen Flamecraft. If not, there are some other talks on
profiling in the Mozilla left room that you can look it up. But essentially, what profiling is,
you want to see which parts of your applications are so, for example, here, wanted to see, I can
see that some JDK stuff is probably a thing that takes time. But essentially, how it works under
the hood is that we have a selection of threads, like for example, here, five threads. Then we
randomly select three threads because we cannot usually sample all threads because it would be
too costly. Then we pre-allocate some traces. There's just a data structure where we store the
stack frame information in. And then we ping the first thread. And with ping, I mean, we send it
the signal. And then the signal handle. We walk the stack because in the single handler, the thread
is stopped. So we can walk the stack. We do this with the thread two, with the thread five. And
we have the traces. And then we store it. And then we do some post-processing. That's
essentially how I think profile works, but just in a loop. So in a loop, we already do this. And
so we need an API because we need an API. It's called, I think it called trace because we could
use JVMTR libraries. They are safe from bias. So they let the threads wait till they're ready,
till they're at a safe point. But we want to have the call trace at a certain point where we
want it. And so I think that call trace is quite a cool API. So how it works, here we have the stack,
how it's on your system. We have at the bottom the pthread start. It's on the Unix system. And on
top, we have like some Java frames. And then it goes up till the top to write, write bytes method
because it writes to a buffered output stream. It's essentially, hello world, just print some
strings. And in the single handler, we get the top frame. That's where the U context from the
single handler points to. And then we do some stack walking. And as in get call trace does it
for us. And essentially it returns us in a preallocated data structure, the frames. And the
number of frames that we got. And it also stores a number of frames in error code if there was an
error. And so what we get for every frame is the line number. So it's called line number,
but it's essentially the byte code index. I don't know. It's historically this way because this API
is like from 2003 around. And we get a method ID. But we only get this information on Java frames.
So what are these problems? So don't get missed out. They worked on it for long enough time. So
it's unofficial. So it's there in 2003, like for three months. And then Oracle put it out,
sun at the time put it away. It's now just lying around as an exported symbol but doesn't have
its own header. It's unsupported. So if there's a change in another part of the JVM that potentially
breaks it, nobody notices it because there's only one single test that doesn't test that much. So
there's also missing information. So it only gives us information on the stack frames of the
Java stack, of the Java frames, but not on anything else. And it misses information like inlining,
which isn't that great. And so in the beginning of last year, I started to work on a new API
because this, I think, is the best we have. And maybe we could do something better. And
so I worked, I started to work on Async et cetera. It's now a CHEP candidate. It's 435. So if you
want to see the CHEP in its entirety, just go on the OpenTedicay website or read the blog post
for this talk and you get a picture of what it does. And so the idea was to create a better API
that gives us more information and is far more supported, so with lots of tests with its own
header. And so again, we have the stack, our stack, but we then get more information. For
example, we get at its most basic level, we also get the kind of the thread that we're running on.
So is this thread like in Java mode or is this in GC mode or what is this thread, which is quite
neat. And we got more information. For example, we get the BCI. It's not called BCI because, yeah,
it's the byte code index. We get the method ID. We get also the type. Is it inlined? Is it native?
With native, I mean not CC++, but these boundary methods that are defined in Java, but which code
is implemented in CC++. And we also get a compilation level. So is it C1, C2, compiled,
or don't compile at all? So this is quite neat because we get more information. But the cool
thing is we have options now. With this API, we can set in an integer. Hey, we want to have
non-Java frames and we also want to walk non-Java threads, which leads us to this situation where
we get information also on the thread on these CC++ frames, which is quite nice. Because for
these frames, we get also the type. So it's a CC++ and we also get a program counter. So we can
then go back, do some of our own analysis and use DL-SIM to get methods of the DL family and get
the method name. And we can also walk with these options non-Java threads. So we see more
information. It essentially makes the life of a profile developer far easier because we can now
just use this API. It will be supported if it gets in. It will be supported. I'm working on lots
and lots of tests. And yeah, I hope it gets in. And as a bonus, what I also introduced is new
methods for OpenShiftedHead developers to walk stacks because currently the code is like spread
between a few different places. Some of them are copies of others. So it's quite hard when you
change some port. You have to change other parts too. So it's essentially technical depth. There
were good reasons in the years before, but still I want to make stack walking easier. So the new
API that I used in the implementation of my chat proposal allows us to just give a stack walker
some options like, hey, I want to walk stacks. I want to skip. I want to walk also non-Java
frames. And I can just go over it and say, oh, give me the next frame. And on this next frame,
we can ask all the information. Is this a Java frame? Is this a native frame? Which is this
compilation level? And this makes it far easier to walk stacks and hopefully makes it easier to
combine all the stack walking from some ever-related stack traces from AsyncGetCallTrace,
from JVR using one API. And so when you make an improvement in one of these APIs and implementations,
you get an improvement on all. So what I've done is that I improved AsyncGetCallTrace with the
help of my colleagues to be much safer. So I wrote testing code that used SafeFed so that it
checks the pointer. So it kind of checks the pointer before it exists. So it's far safer than I did
here for AsyncGetStackTrace. Lots of testing, for example. I did some fuzzing. So I called AsyncGetStackTrace
with random u-context, so with randomized frame pointers and stack pointers. And it doesn't crash
like for hours on a large machine, which is quite cool. And so this covers AsyncGetAsync
profile when it modifies the frame and stack pointer to alleviate some concerns when the VM is
like an undefined state. It needs a lot of convincing, so I'm still in the process where I
have to talk with all the people from Oracle, all the JVR people. It's a long drawn-out process,
but I hope I can convince them. But clearly, because clearly the people on the profile
side are really happy to have this because it has many advantages for them. And of course,
again, testing because the whole point of this API is that you get more information,
but also that it's a better tested API. Currently, I have six tests, and I'm working on more.
So I hope that it gets in. Till then, you can see on GitHub, there's a draft PR on the
step. Just search in the PRs for draft PR with ISKST in the name. And then you can, yeah,
you can follow me on Twitter on our team at SpeedSubmachine. And that's all. Oh, yes, yes,
yeah. And I'm also blogging like on mostly nerdlers, and all the blog posts I like also put
on Fujay. But yeah, you can follow me there and read on all the topics that they talk today. So, thanks.
The question was, can safehatch be called from signal hunters because it uses signals? I think
it uses different signals because I didn't have any problems using it from signal hunters. So I
have tests. To use us and get stack drives, you have to use signal hunters. So I didn't see any
problems so far. I think that's probably, it's even weird because from signal hunters, you can,
you cannot do any malloc. So you have to preallocate, but you can call fork. So it's quite,
quite interesting. So any other questions? Does it handle in both dynamics, especially,
because within that stack, you get like the whole stack of deciding how to dispatch the call?
So the question was, does it handle in work dynamics specifically? Now, it just uses,
it just is based on the frame stack walking and like the internal mechanism of stack walking. So
it doesn't handle it differently than, for example, I think get call trace and trade for. Yeah,
that's all Java frames. So that's, that's probably fine.
Do you have to change the native parts? Or does it go on all platforms?
So the question was, does it work on all platforms? It's known that it doesn't really work on windows
just because windows hasn't really a concept of signals. If you have any ideas on getting
something like this to work on windows, feel free to drop me a message. So no,
I didn't have to change any native parts. I had to change some, I had to create some native parts
for testing to modify like the U context because this is highly applications, highly operating
systems specific. So the changes to the whole OpenJDK are fairly minimal. So they aren't that
large besides passing through some bullets to configure stuff. And the code itself is just
a few couple hundred lines. So it's quite simple also to understand. And there's a blog post that
describes like reasoning behind it. Any other questions? Yes? Is it already a sub machine?
No, it's not yet on the sub machine because I'm still in the process of testing it. So there's
of course a podcast. You can already use the JVM when you compile it yourself. I'm in the process
of updating my demo repository which contains a modified sync profile that uses it. So you can
try it out yourself. I should be right in the next few weeks. It still has some bugs. Yeah.
Anything else? Thank you very much.