Issues with dtraceasm, and a workaround
Aleksey Shipilev
shade at redhat.com
Thu Feb 18 12:24:21 UTC 2021
On 2/18/21 1:14 PM, Aleksey Shipilev wrote:
> Hi,
>
> On 1/25/21 6:16 PM, Paul Sandoz wrote:
>> Sending a TERM signal before destroying the process works around this issue (see patch below).
>> It kicks the dtrace process, resulting in the process relinquishing the remaining dtrace output
>> to theoutput file.
>
> This is weird!
>
>> --- a/jmh-core/src/main/java/org/openjdk/jmh/profile/DTraceAsmProfiler.java
>> +++ b/jmh-core/src/main/java/org/openjdk/jmh/profile/DTraceAsmProfiler.java
>> @@ -87,6 +87,9 @@ public class DTraceAsmProfiler extends AbstractPerfAsmProfiler {
>> throw new IllegalStateException("DTrace needs the forked VM PID, but it is not initialized");
>> }
>>
>> + long dtracePid = dtraceProcess.pid();
>> + Utils.tryWith("sudo", "kill", "-15", Long.toString(dtracePid));
>> +
>> Collection<String> messages = Utils.destroy(dtraceProcess);
>> if (!messages.isEmpty()) {
>> throw new IllegalStateException(messages.toString());
>>
>
> Because a few lines below, JMH calls Utils.destroy, which in turns calls java.lang.Process::destroy,
> which in turns calls java.lang.ProcessHandleImpl::destroy(), which in turn calls
> java.lang.ProcessHandleImpl::destroyProcess(/* force = */ false), which calls (I think)
> Java_java_lang_ProcessHandleImpl_destroy0 from ProcessHandleImpl_unix.c, which does deliver SIGTERM:
>
> JNIEXPORT jboolean JNICALL
> Java_java_lang_ProcessHandleImpl_destroy0(JNIEnv *env,
> jobject obj,
> jlong jpid,
> jlong startTime,
> jboolean force) {
> pid_t pid = (pid_t) jpid;
> int sig = (force == JNI_TRUE) ? SIGKILL : SIGTERM; // <--- here
> jlong start = Java_java_lang_ProcessHandleImpl_isAlive0(env, obj, jpid);
>
> if (start == startTime || start == 0 || startTime == 0) {
> return (kill(pid, sig) < 0) ? JNI_FALSE : JNI_TRUE;
> } else {
> return JNI_FALSE;
> }
> }
>
> ...so if we actually deliver KILL not TERM on MacOS, that looks like a JDK bug?
Hold on. So if we call Process.destroy, then we also close all the streams at the same time?
https://bugs.openjdk.java.net/browse/JDK-8216990
Whoa. So even the workaround above does not work reliably, as it races with the profiler process: if
we are lucky, profiler would succeed in dumping the output after the first SIGTERM, until
Process.destroy comes and closes everything. Hm.
--
Thanks,
-Aleksey
More information about the jmh-dev
mailing list