-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8371380: [LOOM] The debug agent should avoid enabling VIRTUAL_THREAD_START/END events when possible #28485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
8371380: [LOOM] The debug agent should avoid enabling VIRTUAL_THREAD_START/END events when possible #28485
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /* | ||
| * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. | ||
| * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. | ||
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| * | ||
| * This code is free software; you can redistribute it and/or modify it | ||
|
|
@@ -1640,29 +1640,6 @@ eventHandler_initialize(jbyte sessionID) | |
|
|
||
| void | ||
| eventHandler_onConnect() { | ||
| debugMonitorEnter(handlerLock); | ||
|
|
||
| /* | ||
| * Enable vthread START and END events if they are not already always enabled. | ||
| * They are always enabled if we are remembering vthreads when no debugger is | ||
| * connected. Otherwise they are only enabled when connected because they can | ||
| * be very noisy and hurt performance a lot. | ||
| */ | ||
| if (gdata->vthreadsSupported && !gdata->rememberVThreadsWhenDisconnected) { | ||
| jvmtiError error; | ||
| error = threadControl_setEventMode(JVMTI_ENABLE, | ||
| EI_VIRTUAL_THREAD_START, NULL); | ||
| if (error != JVMTI_ERROR_NONE) { | ||
| EXIT_ERROR(error,"Can't enable vthread start events"); | ||
| } | ||
| error = threadControl_setEventMode(JVMTI_ENABLE, | ||
| EI_VIRTUAL_THREAD_END, NULL); | ||
| if (error != JVMTI_ERROR_NONE) { | ||
| EXIT_ERROR(error,"Can't enable vthread end events"); | ||
| } | ||
| } | ||
|
|
||
| debugMonitorExit(handlerLock); | ||
| } | ||
|
|
||
| static jvmtiError | ||
|
|
@@ -1708,6 +1685,19 @@ eventHandler_reset(jbyte sessionID) | |
| } | ||
| } | ||
|
|
||
| /* We also want to disable VIRTUAL_THREAD_START events if they were enabled due to | ||
| * a deferred event request. | ||
| */ | ||
| if (gdata->virtualThreadStartEventsPermanentlyEnabled) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like this block can disable VITRUAL_THREAD_START when
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. virtualThreadStartEventsPermanentlyEnabled is only set true if includeVThreads is false, which means rememberVThreadsWhenDisconnected is also false (they are always set the same, as I discuss in my new comment below). virtualThreadStartEventsPermanentlyEnabled could use a better name because it means "permanently enabled for handling deferred event enabling", whereas if includeVThreads is true, VITRUAL_THREAD_START events are always permanently enabled, but virtualThreadStartEventsPermanentlyEnabled will never be set true.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about virtualThreadStartEventsEnabledForDeferredEventMode? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Super long :) But makes it much clearer, so I'm fine with it
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Agree with Alex, long but cleaner. |
||
| jvmtiError error; | ||
| error = threadControl_setEventMode(JVMTI_DISABLE, | ||
| EI_VIRTUAL_THREAD_START, NULL); | ||
| if (adjust_jvmti_error(error) != JVMTI_ERROR_NONE) { | ||
| EXIT_ERROR(error,"Can't disable vthread start events"); | ||
| } | ||
| gdata->virtualThreadStartEventsPermanentlyEnabled = JNI_FALSE; | ||
| } | ||
|
|
||
| /* Reset the event helper thread, purging all queued and | ||
| * in-process commands. | ||
| */ | ||
|
|
@@ -1931,6 +1921,8 @@ eventHandler_dumpHandlers(EventIndex ei, jboolean dumpPermanent) | |
| void | ||
| eventHandler_dumpHandler(HandlerNode *node) | ||
| { | ||
| tty_message("Handler for %s(%d)\n", eventIndex2EventName(node->ei), node->ei); | ||
| tty_message("handlerID(%d) for %s(%d) suspendPolicy(%d) permanent(%d)", | ||
| node->handlerID, eventIndex2EventName(node->ei), node->ei, | ||
| node->suspendPolicy, node->permanent); | ||
| eventFilter_dumpHandlerFilters(node); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: Why is the
THREAD_STARTevent disabled globally (for all threads) but theTHREAD_ENDevent is disabled for specific thread?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
THREAD_START can't have a thread filter. THREAD_END can. "thread" == requestThread(node) == the thread filter if there is one, so when disabling THREAD_START it could be an actual thread or it could just be NULL. For THREAD_START "thread" should always be NULL, so I suppose I could have just asserted that and used "thread" as the argument instead of "NULL".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually it appears that JDWP THREAD_START can have a filter but JVMTI THREAD_START does not allow you to set the thread to enable the events on. That means when JDWP THREAD_START events are requested and a thread filter is provided, JVMTI THREAD_START needs to be enabled for all threads. That's actually how it is working now. I tried adding the assert and it was triggered. So that means passing "thread" instead of NULL would sometimes end up passing an actual thread to JVMTI and it would produce a [JVMTI_ERROR_ILLEGAL_ARGUMENT in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a bug in the call to eventHandlerRestricted_iterator() at line 1436. For VIRTUAL_THREAD_START I should be explicitly passing in NULL for the thread. Otherwise it will consider the thread when deciding if other event handlers are a match to this one, and I don't think we want that. It could lead to disabling VIRTUAL_THREAD_START events when we shouldn't. Seems we don't have any tests for this but I modified an existing test and got a failure. The test creates a ThreadStartRequest with a thread filter and expects that to trigger a ThreadStartEvent for the filter thread. If I create a second ThreadStartRequest with a filter on a different thread, enable it, and then disable it, that ends up disabling all VIRTUAL_THREAD_START events, and the expected event never arrives. Passing NULL fixes the problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, the last problem I pointed out is fixed now. The fix was done in matchHasNoPlatformThreadsOnlyFilter(). I was going to pass NULL for "thread" when ei == EI_THREAD_START, but this turned out not to be enough and changes were also needed in matchHasNoPlatformThreadsOnlyFilter(). Once those changes were in place there was no longer a need to pass NULL for "thread".
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I know that but keep forgetting that
ThreadStartcan not be thread-filtered. :)I'd suggest to add a small comment to remind about it.