<div dir="ltr"><div dir="ltr">Thanks to Alan and Ron for your replies. <br></div><div><br></div><div>There are sort of two separate issues here, one narrow (how to reliably stop a thread) and one larger (what is sandboxing and how best to do it).<br></div><div><br></div><div>The discussion about sandboxing is very interesting but for now I'm really just using it as a motivating example for the more narrow question, which is about whether and how it should be possible to stop a thread (no matter what it's doing). There are other scenarios where one might want to ensure a thread stops regardless of what it's doing (e.g., JShell).<br></div><div><br></div><div>So my question is simply what's the implementation distance between X and Y? Where X = [We are now after implementing virtual threads], and Y = [The ability to always unblock a blocked thread].</div><div><br></div><div>For the sake of clarity let's assume whoever wants to do this is able to rewrite bytecode (e.g., to add checks for a "stop" flag on backward branches) to avoid infinite loops, etc., so the only real barrier is the thread being stuck in a blocking method call.<br></div><div><br></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Sep 1, 2022 at 4:04 AM Ron Pressler <<a href="mailto:ron.pressler@oracle.com">ron.pressler@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">



<div style="overflow-wrap: break-word;">See Alan’s response re the details of interruption.
</div></blockquote><div><br></div><div>Thread interrupts definitely make sense as the right way to unblock a thread.</div><div><br></div><div>But will that ALWAYS work? No, currently, it does not (see previous example).</div><div><br></div><div>Question - what are the blocking operations that can't be interrupted, and would it be possible to include them as well somehow? This would be one solution.<br></div> <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;"><div>When it comes to the question of forcibly killing threads, for it to be generally useful, there must be limitations imposed on what the threads can do to data that is accessed by other threads, as an errant thread could otherwise harm other threads.</div></div></blockquote><div><br></div>If you're talking about releasing object monitors, then I agree with you (were you thinking of others?). I don't think a "kill -9" style solution works. Instead, you would need to do something like this:<br></div><div class="gmail_quote"><br></div><div class="gmail_quote">  1. Ensure the thread wakes up if blocked (this is what I'm asking about currently)</div><div class="gmail_quote">  2. Trigger the throwing of ThreadDeath or similar exception to unwind the stack<br></div><div><br></div><div>Step #2 could be via Thread.stop() or via bytecode rewriting (checks at backward branches). Basically #1 is the only part that can't reliably be solved today.<br></div><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;"><div>
 The Java platform (and language) currently does not impose such “isolation” limitation, but some language targeting the Java platform could, and so it could also emit interruption checks when compiling to bytecode. A language that behaves in this way is Erlang
 (although I don’t know if implementations targeting Java are currently maintained), but even there there are pitfalls.</div></div></blockquote><div><br></div><div>You've got me curious... What are the additional pitfalls?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;"><div> A similar path is available to jshell as well, as it can emit interruption checks in the bytecode.</div></div></blockquote><div><br></div><div>Yep. Currently it just resorts to ThreadGroup.stop()... obviously, it's in the same boat here.</div><div><br></div><div>---snip---<br></div><div><br></div><div>Transitioning now from the "how to stop a thread" discussion to the larger "sandbox" discussion...<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;"><div>Even if all “dangerous” APIs are blocked, any user code could allocate as much memory as it likes,
 exhausting the memory available for the entire process.</div></div></blockquote><div><br></div><div>Not necessarily. Bytecode rewriting could be used to track memory allocations with weak references used to track deallocations. This would impose a performance penalty of course, and the accounting wouldn't be perfectly accurate, but you could make that inaccuracy conservative so it would work for the purposes of containment.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;"><div>If it is also allowed to spawn platform threads at will, it can also exhaust the CPU allocation for the entire process.</div></div></blockquote><div><br></div><div>Not sure I understand... with bytecode rewriting (e.g., adding checks at backward branches), you should be able to limit the total CPU utilization of a thread or group of threads. Kind of clunky for sure but it should work, right?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;">
<div>The Java runtime could be changed to support isolated heaps in imitations of the isolation and memory restrictions offered by the OS, but if the goal is to share some internal runtime data structures for efficiency, there are ways to do that for
 multiple processes. Given that the kernel has more arrows in its quiver to support such isolation, including at the native code level, that is probably the most appropriate level to provide it, I think, so much so that trying to implement proper and secure
 isolation in multi-user server programs in user mode is a fool’s errand. A multi-user Java runtime running in *kernel* mode is a different matter altogether, but it is currently beyond the scope of the OpenJDK JDK.
</div></div></blockquote><div><br></div>OK so let me throw out a not-so hypothetical example. Oracle supports <a href="https://docs.oracle.com/database/121/JJDEV/chfive.htm#JJDEV13247">Java stored procedures</a>. I'm not familiar with it, but is this not implemented as server-side sandboxed code? Isn't that a valid motivating example?<br></div><div class="gmail_quote"><br></div><div class="gmail_quote">The Java code may be prevented (via Java permissions) from doing any file or network I/O, in which case the stuck thread problem gets a lot easier (probably all blocking system calls require interaction with some file, process, or network socket).</div><div class="gmail_quote"><br></div><div class="gmail_quote">But I'm still curious how they stop runaway Java code or runaway memory allocation?<br clear="all"></div><div><br></div><div>-Archie</div><div><br></div>-- <br><div dir="ltr" class="gmail_signature">Archie L. Cobbs<br></div></div>