<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:DengXian;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
@font-face
{font-family:"\@DengXian";
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
code
{mso-style-priority:99;
font-family:"Courier New";}
pre
{mso-style-priority:99;
mso-style-link:"HTML Preformatted Char";
margin:0cm;
font-size:11.0pt;
font-family:"Courier New";}
span.HTMLPreformattedChar
{mso-style-name:"HTML Preformatted Char";
mso-style-priority:99;
mso-style-link:"HTML Preformatted";
font-family:Consolas;}
span.EmailStyle24
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-CA" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Hi Maurizio,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I really appreciate your explanation in more details which helps me better understand how to deal with the lifetime of the memory segment in downcall/upcall.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Best Regards<o:p></o:p></p>
<p class="MsoNormal">Cheng Jin<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US">From:</span></b><span lang="EN-US"> Maurizio Cimadamore <maurizio.cimadamore@oracle.com>
<br>
<b>Sent:</b> February 2, 2023 9:09 AM<br>
<b>To:</b> Jorn Vernee <jorn.vernee@oracle.com>; Cheng Jin <jincheng@ca.ibm.com>; panama-dev@openjdk.org<br>
<b>Subject:</b> Re: [External] : RE: Inappropriate use of the implicit session in allocating the upcall stub in SafeFunctionAccessTest.java<o:p></o:p></span></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal" style="mso-line-height-alt:.75pt"><span style="font-size:1.0pt;color:white">To add to Jorn’s great reply, let’s also look at this from a different angle. The question you are asking in reality has nothing to do with upcalls. It has to do
with memory segments that are passed by reference (e. g. by passing their address
<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-line-height-alt:.75pt"><span style="font-size:1.0pt;color:white">ZjQcmQRYFpfptBannerStart<o:p></o:p></span></p>
</div>
<table class="MsoNormalTable" border="0" cellspacing="0" cellpadding="0" width="100%" style="width:100.0%;border-radius:4px">
<tbody>
<tr>
<td style="padding:12.0pt 0cm 12.0pt 0cm">
<table class="MsoNormalTable" border="1" cellspacing="0" cellpadding="0" width="100%" style="width:100.0%;background:#D0D8DC;border:none;border-top:solid #90A4AE 3.0pt">
<tbody>
<tr>
<td valign="top" style="border:none;padding:0cm 7.5pt 3.75pt 4.5pt">
<table class="MsoNormalTable" border="0" cellspacing="0" cellpadding="0" align="left">
<tbody>
<tr>
<td style="padding:3.0pt 6.0pt 3.0pt 6.0pt">
<p class="MsoNormal"><b><span style="font-size:10.5pt;font-family:"Arial",sans-serif;color:black">This Message Is From an External Sender
<o:p></o:p></span></b></p>
</td>
</tr>
<tr>
<td style="padding:3.0pt 6.0pt 3.0pt 6.0pt">
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Arial",sans-serif;color:black">This message came from outside your organization.
<o:p></o:p></span></p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<div>
<p class="MsoNormal" style="mso-line-height-alt:.75pt"><span style="font-size:1.0pt;color:white">ZjQcmQRYFpfptBannerEnd<o:p></o:p></span></p>
</div>
<div>
<p style="mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:14.4pt;margin-left:0cm">
To add to Jorn’s great reply, let’s also look at this from a different angle.<o:p></o:p></p>
<p style="mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:14.4pt;margin-left:0cm">
The question you are asking in reality has nothing to do with upcalls. It has to do with memory segments that are passed
<em><span style="font-family:"Calibri",sans-serif">by reference</span></em> (e.g. by passing their address in some register and/or stack slot).<o:p></o:p></p>
<p style="mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:14.4pt;margin-left:0cm">
Even a call to something as simple as this:<o:p></o:p></p>
<pre style="mso-margin-top-alt:0cm;margin-right:1.8pt;margin-bottom:0cm;margin-left:1.8pt;margin-bottom:.0001pt;line-height:14.4pt"><code><span style="font-size:9.5pt;font-family:Consolas;color:black;border:solid #CCCCCC 1.0pt;padding:6.0pt;background:#F8F8F8"> size_t strlen(const char *s);</span></code><code><span style="font-size:9.5pt;font-family:Consolas;border:solid #CCCCCC 1.0pt;padding:6.0pt;background:#F8F8F8"><o:p></o:p></span></code></pre>
<p style="margin:0cm">can be problematic: consider the case where the string is stored in a memory segment whose lifetime is managed by an automatic scope. It would be bad if the segment could become unreachable
<em><span style="font-family:"Calibri",sans-serif">while</span></em> executing <code>
<span style="font-size:9.5pt;font-family:Consolas;color:black;border:solid #EAEAEA 1.0pt;padding:0cm;background:#F8F8F8">strlen</span></code>.<o:p></o:p></p>
<p style="margin:0cm">This is why the Linker provides a lifetime guarantee for all memory segments passed by reference: such arguments will be forcefully kept alive for the entire duration of the call. This means that a segment passed to
<code><span style="font-size:9.5pt;font-family:Consolas;color:black;border:solid #EAEAEA 1.0pt;padding:0cm;background:#F8F8F8">strlen</span></code>, no matter how allocated, will never be deallocated while the
<code><span style="font-size:9.5pt;font-family:Consolas;color:black;border:solid #EAEAEA 1.0pt;padding:0cm;background:#F8F8F8">strlen</span></code> code is executing.<o:p></o:p></p>
<p style="mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:14.4pt;margin-left:0cm">
This is, of course an 80% (90% ?) guarantee: it works well when the native code uses the provided segment
<em><span style="font-family:"Calibri",sans-serif">locally</span></em>. But in cases where the native code stashes the segment pointer somewhere (e.g. a global variable) and then, later on, re-access that same pointer (maybe while evaluating a different function)
there can be issues. The problem here is that the native code as certain expectations on the lifetime of the provided pointer (e.g. this pointer should remain alive after the call). In such cases, the Java code using Linker should reflect the expected lifetime
accordingly, either by adding reachability fences as required (if the segment is managed by the GC), or by keeping the Arena alive for as long as required. Whenever this doesn’t happen, the native code can be exposed to use-after-free bugs. There is nothing
a Java API can do to protect against these sneaky cases: handling these cases correctly is really a result of a deeper understanding of the lifetime expectations of the library we’re interacting with.<o:p></o:p></p>
<p style="mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:14.4pt;margin-left:0cm">
Upcall stubs are “just another kind of segment” that can be passed by reference. As such, it is subject to the same guarantees described above, which can fail exactly in the same ways as described above for non-upcall segments.<o:p></o:p></p>
<p style="mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:14.4pt;margin-left:0cm">
Cheers<br>
Maurizio<o:p></o:p></p>
<p style="mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:14.4pt;margin-left:0cm">
On 31/01/2023 22:20, Jorn Vernee wrote:<o:p></o:p></p>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p>Hi,<o:p></o:p></p>
<p>The section of javadoc that you reference is talking about a case like this:<br>
<br>
<span style="font-family:"Courier New""> static MemorySegment target() {<br>
try (Arena arena = Arena.openConfined()) {<br>
return arena.allocate(JAVA_INT);<br>
}<br>
}</span><br>
<br>
Note that the memory will be freed before the target function returns, so if this function is used as the target method of an upcall stub, it will effectively return a dangling pointer to native code. If the native code then dereferences the returned pointer,
this can crash the VM.<o:p></o:p></p>
<p>> I don’t understand how/what clients should do to ensure the address of the upcall stub is alive during the upcall invocation within an implication session.<o:p></o:p></p>
<p>In the case of an implicit scope, the scope of the upcall stub should be kept reachable (per [1]) until the upcall stub can no longer be called. The Reference::reachability fence method can be used for this. But, it might be easier to use an explicitly closed
scope for the upcall stub instead, if you plan on storing it in native memory and calling it later.<o:p></o:p></p>
<p>> Does that mean the implicit session is ALREADY kept alive in the existing implementation of OpenJDK (which I don’t think so) to guarantee the upcall stub works during the upcall invocation based on the explanation in [1]?<br>
<br>
Not quite. The current implementation guarantees that the implicit session of an upcall stub is kept alive (and the upcall stub works) during and invocation of a _downcall_ to which the upcall stub memory segment is passed. i.e. if an upcall stub is passed
to a downcall, the scope it is attached to can not be closed for the duration of that downcall (and this goes for any MemorySegment passed to a downcall). This is achieved by calling ImplicitSession::release [2] after a downcall returns.<o:p></o:p></p>
<p>There is no guarantee that an arbitrary upcall stub will be kept alive until it is invoked. For instance, if I pass an upcall stub to native code, and store the pointer in some memory there (e.g. a global variable), then I return back to Java. If I don't
have a strong reference to the upcall stub's scope, the upcall stub might be freed. If I then later try to invoke the upcall stub again through the pointer I stored in native code, the VM can crash. In short: the JVM can not 'see' any pointer to the upcall
stub from native code, so they don't count toward its reachability.<o:p></o:p></p>
<p>To illustrate the problematic case, consider this native library and Java program that calls into it (using the Java 20 API):<br>
<br>
libMylib.c:<br>
<br>
<span style="font-family:"Courier New"">typedef void (*callback_t)(void);</span><o:p></o:p></p>
<p><span style="font-family:"Courier New"">static callback_t GLOBAL_CB; // global pointer variable</span><o:p></o:p></p>
<p><span style="font-family:"Courier New"">void store(callback_t cb) {<br>
GLOBAL_CB = cb;<br>
}<br>
<br>
void call() {<br>
GLOBAL_CB();<br>
}</span><br>
<br>
Main.java:<br>
<span style="font-family:"Courier New""><br>
import java.lang.foreign.*;<br>
import java.lang.invoke.*;<br>
<br>
import static java.lang.foreign.ValueLayout.*;<br>
<br>
public class Main {<br>
static final Linker LINKER = Linker.nativeLinker();<br>
<br>
static final MethodHandle STORE;<br>
static final MethodHandle CALL;<br>
static final MethodHandle TARGET;<br>
<br>
static {<br>
System.loadLibrary("Mylib");<br>
SymbolLookup lookup = SymbolLookup.loaderLookup();<br>
STORE = LINKER.downcallHandle(lookup.find("store").get(), FunctionDescriptor.ofVoid(ADDRESS));<br>
CALL = LINKER.downcallHandle(lookup.find("call").get(), FunctionDescriptor.ofVoid());<br>
try {<br>
TARGET = MethodHandles.lookup().findStatic(Main.class, "target", MethodType.methodType(void.class));<br>
} catch (ReflectiveOperationException e) {<br>
throw new InternalError(e);<br>
}<br>
}<br>
public static void main(String[] args) throws Throwable {<br>
store();<br>
System.gc(); // invoke gc which can clean up 'stub'<br>
call();<br>
}<br>
<br>
static void store() throws Throwable {<br>
MemorySegment stub = LINKER.upcallStub(TARGET, FunctionDescriptor.ofVoid(), SegmentScope.auto());<br>
STORE.invokeExact(stub);<br>
// stub is unreachable here<br>
}<br>
<br>
static void call() throws Throwable {<br>
CALL.invokeExact();<br>
}<br>
<br>
static void target() {}<br>
}</span><o:p></o:p></p>
<p>On my machine this code reliably crashes the VM, since the upcall stub is called after it becomes unreachable (and is freed).<o:p></o:p></p>
<p>In order to fix this, I would have to keep the stub alive until after I call the 'call' function from the native library:<br>
<br>
<span style="font-family:"Courier New""> public static void main(String[] args) throws Throwable {<br>
MemorySegment stub = store(); // <-----<br>
System.gc(); // invoke gc<br>
call();<br>
Reference.reachabilityFence(stub); // <----- keep stub alive until after I call it<br>
}<br>
<br>
static MemorySegment store() throws Throwable {<br>
MemorySegment stub = LINKER.upcallStub(TARGET, FunctionDescriptor.ofVoid(), SegmentScope.auto());<br>
STORE.invokeExact(stub);<br>
return stub; // <--- return stub here<br>
}</span><o:p></o:p></p>
<p>Hope that helps,<br>
Jorn<o:p></o:p></p>
<p>[1]: <a href="https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/ref/package-summary.html#reachability">https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/ref/package-summary.html#reachability</a><br>
[2]: <a href="https://github.com/openjdk/panama-foreign/blob/a943c2eb10ba40c36d5a6e874160d0a747457510/src/java.base/share/classes/jdk/internal/foreign/ImplicitSession.java#L50">https://github.com/openjdk/panama-foreign/blob/a943c2eb10ba40c36d5a6e874160d0a747457510/src/java.base/share/classes/jdk/internal/foreign/ImplicitSession.java#L50</a><o:p></o:p></p>
<div>
<p class="MsoNormal">On 31/01/2023 21:01, Cheng Jin wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">Hi Jorn,<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">Correct but these bullets are only intended for the downcall invocation rather than the upcall stub.<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">According to the explanation of upcall stub in [1] as follows:<o:p></o:p></p>
<p class="MsoNormal">“When creating upcall stubs the linker runtime....<o:p></o:p></p>
<p class="MsoNormal">Moreover, if the target method handle associated with an upcall stub returns a memory address,<o:p></o:p></p>
<p class="MsoNormal">clients must ensure that this address cannot become invalid after the upcall completes.
<span style="font-family:Wingdings">ß</span>-----------------<o:p></o:p></p>
<p class="MsoNormal">This can lead to unspecified behavior, and even JVM crashes, since an upcall is
<o:p></o:p></p>
<p class="MsoNormal">typically executed in the context of a downcall method handle invocation.”<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">I don’t understand how/what clients should do to ensure the address of the upcall stub is alive during the upcall invocation within an implication session.<o:p></o:p></p>
<p class="MsoNormal">Does that mean the implicit session is ALREADY kept alive in the existing implementation of OpenJDK (which I don’t think so) to guarantee the upcall stub works during the upcall invocation based on the explanation in [1]?<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">Best Regards<o:p></o:p></p>
<p class="MsoNormal">Cheng Jin<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US">From:</span></b><span lang="EN-US"> Jorn Vernee
<a href="mailto:jorn.vernee@oracle.com"><jorn.vernee@oracle.com></a> <br>
<b>Sent:</b> January 31, 2023 2:14 PM<br>
<b>To:</b> Cheng Jin <a href="mailto:jincheng@ca.ibm.com"><jincheng@ca.ibm.com></a>;
<a href="mailto:panama-dev@openjdk.org">panama-dev@openjdk.org</a><br>
<b>Subject:</b> [EXTERNAL] Re: Inappropriate use of the implicit session in allocating the upcall stub in SafeFunctionAccessTest.java</span><o:p></o:p></p>
</div>
<p class="MsoNormal"> <o:p></o:p></p>
<div>
<p class="MsoNormal" style="mso-line-height-alt:.75pt"><span style="font-size:1.0pt;color:white">Hi Cheng Jin, Thanks for the email. In this case it is not a problem since memory sessions (including upcall stubs) are kept alive/reachable for the duration of
a downcall (see the third bullet here: [1]) "The memory session of R is kept </span>
<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-line-height-alt:.75pt"><span style="font-size:1.0pt;color:white">ZjQcmQRYFpfptBannerStart</span><o:p></o:p></p>
</div>
<table class="MsoNormalTable" border="0" cellspacing="0" cellpadding="0" width="100%" style="width:100.0%;border-radius:4px">
<tbody>
<tr>
<td style="padding:12.0pt 0cm 12.0pt 0cm">
<table class="MsoNormalTable" border="1" cellspacing="0" cellpadding="0" width="100%" style="width:100.0%;background:#D0D8DC;border:none;border-top:solid #90A4AE 3.0pt">
<tbody>
<tr>
<td valign="top" style="border:none;padding:0cm 7.5pt 3.75pt 4.5pt">
<table class="MsoNormalTable" border="0" cellspacing="0" cellpadding="0" align="left">
<tbody>
<tr>
<td style="padding:3.0pt 6.0pt 3.0pt 6.0pt">
<p class="MsoNormal"><b><span style="font-size:10.5pt;font-family:"Arial",sans-serif;color:black">This Message Is From an External Sender
</span></b><o:p></o:p></p>
</td>
</tr>
<tr>
<td style="padding:3.0pt 6.0pt 3.0pt 6.0pt">
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Arial",sans-serif;color:black">This message came from outside your organization.
</span><o:p></o:p></p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<div>
<p class="MsoNormal" style="mso-line-height-alt:.75pt"><span style="font-size:1.0pt;color:white">ZjQcmQRYFpfptBannerEnd</span><o:p></o:p></p>
</div>
<p>Hi Cheng Jin,<o:p></o:p></p>
<p>Thanks for the email.<br>
<br>
In this case it is not a problem since memory sessions (including upcall stubs) are kept alive/reachable for the duration of a downcall (see the third bullet here: [1])<o:p></o:p></p>
<p> "The memory session of R is kept alive (and cannot be closed) during the invocation."<o:p></o:p></p>
<p>Since we don't store a reference to the upcall stub in native code until after the downcall returns, this is safe to rely on.<o:p></o:p></p>
<p>Cheers,<br>
Jorn<o:p></o:p></p>
<p>[1]: <a href="https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/foreign/Linker.html#safety">https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/foreign/Linker.html#safety</a><o:p></o:p></p>
<div>
<p class="MsoNormal">On 31/01/2023 18:49, Cheng Jin wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">Hi there, <o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">I notice there might be an issue with the allocation of upcall stub under an implicit session at test/jdk/java/foreign/SafeFunctionAccessTest.java in JDK19+ as follows:<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">e.g.<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> @Test<o:p></o:p></p>
<p class="MsoNormal"> public void testClosedStructCallback() throws Throwable {<o:p></o:p></p>
<p class="MsoNormal"> MethodHandle handle = Linker.nativeLinker().downcallHandle(<o:p></o:p></p>
<p class="MsoNormal"> findNativeOrThrow("addr_func_cb"),<o:p></o:p></p>
<p class="MsoNormal"> FunctionDescriptor.ofVoid(C_POINTER, C_POINTER));<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> try (MemorySession session = MemorySession.openConfined()) {<o:p></o:p></p>
<p class="MsoNormal"> MemorySegment segment = MemorySegment.allocateNative(POINT, session);<o:p></o:p></p>
<p class="MsoNormal"> handle.invoke(segment, sessionChecker(session));
<span style="font-family:Wingdings">ß</span>--------------- the upcall stub is allocated in sessionChecker()<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> MemorySegment sessionChecker(MemorySession session) {<o:p></o:p></p>
<p class="MsoNormal"> try {<o:p></o:p></p>
<p class="MsoNormal"> MethodHandle handle = MethodHandles.lookup().findStatic(SafeFunctionAccessTest.class, "checkSession",<o:p></o:p></p>
<p class="MsoNormal"> MethodType.methodType(void.class, MemorySession.class));<o:p></o:p></p>
<p class="MsoNormal"> handle = handle.bindTo(session);<o:p></o:p></p>
<p class="MsoNormal"> return Linker.nativeLinker().upcallStub(handle, FunctionDescriptor.ofVoid(), MemorySession.openImplicit());
<span style="font-family:Wingdings">ß</span>-----the upcall stub is allocated with an implicit session<o:p></o:p></p>
<p class="MsoNormal"> } catch (Throwable ex) {<o:p></o:p></p>
<p class="MsoNormal"> throw new AssertionError(ex);<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal" style="text-indent:9.9pt">}<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">It is correct to allocate the upcall stub with a session different from the current session in tests given these tests intend to close the current session in upcall to verify the behavior. But it is problematic to exploit an implicit session
backed by GC, in which case the memory of the upcall stub is more likely to be forced to release by GC (when implicitly closing the session to free memory) especially on the memory-restricted machines, which leads to unexpected behavior in upcall (e.g. crash
which was captured recently). To work around this case, I’d suggest to replace it with a global session or others so as to keep the upcall stub alive during the upcall.<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">Best Regards<o:p></o:p></p>
<p class="MsoNormal">Cheng Jin<o:p></o:p></p>
</blockquote>
</blockquote>
</blockquote>
</div>
<div>
<p class="MsoNormal"><span style="font-size:1.0pt"><o:p></o:p></span></p>
</div>
</div>
</div>
</body>
</html>