RFR: 8306758: com/sun/jdi/ConnectedVMs.java fails with "Non-zero debuggee exitValue: 143"
Chris Plummer
cjplummer at openjdk.org
Sat May 6 01:24:27 UTC 2023
On Fri, 5 May 2023 22:21:36 GMT, Chris Plummer <cjplummer at openjdk.org> wrote:
> This test was very rarely failing with a exitValue 143 from the debuggee. It only happened when the machine was under a lot of stress. After some investigation it was realized that on unix OSes it should *always* expect exitValue 143, but for some reason was normally getting exitValue 0. The reason 143 should be expected is because `Process.destroy()` is used on the debuggee, which results in a SIGTERM, which should produce exitValue 143. The reason we were not normally seeing this is because the `Process.destroy()` was done while the debuggee was suspended at a breakpoint. Nothing can be done with the SIGTERM while all threads are suspended, but once the debugger does the `vm.resume()` the SIGTERM can be handled. But by that time it is a race between some thread handling SIGTERM and doing the exit(143), and the main debuggee thread resuming and exiting cleanly (producing exitValue 0). In almost all cases the clean exit was winning. By adding a 5 second sleep before exiting, I mad
e it so the SIGTERM exit always wins. Once this was in place, I had to make changes so the test would pass with exitCode 143. This was done by adding a `TestScaffold.allowExitValue()` method, which the test can override. Note I'll have more uses for this in the future, as I plan to no longer by default allow exitValue 1 (exit with an uncaught exception) and requiring tests to override this method if needed. That will be done by [JDK-8307559](https://bugs.openjdk.org/browse/JDK-8307559).
>
> Tested by running all of test/jdk/com/sun/jdi with and without virtual threads, 10x times on each platform.
test/jdk/com/sun/jdi/ConnectedVMs.java line 101:
> 99: BreakpointEvent bp = startToMain("InstTarg");
> 100: waitForVMStart();
> 101: StepEvent stepEvent = stepIntoLine(bp.thread());
These changes were needed for virtual thread support. `startToMain("InstTarg")` causes the debuggee to run until it it is suspended at a breakpoint in `InstTarg.main()`. `waitForVMStart()` will return right away since the VM has already started, and will return the main thread of the debuggee, but this is the thread running `TestScaffold.main()`, which started up `InstTarg.main()` in a virtual thread. If we single step in the main thread in this case, the single step is not in `InstTarg.main()` as it should be, but is instead in main thread, which is blocked in the `join()` call waiting for the virtual thread to complete. The single step resumes all threads, but can't complete until the virtual thread exits. So before the test ever gets to do the `Process.destroy()`, `InstTarg.main()` has already exited
Fortunately it was easy to find the proper thread to single step in, since the virtual thread is the `BreakpointEvent` thread.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/13848#discussion_r1186539805
More information about the serviceability-dev
mailing list