-
Notifications
You must be signed in to change notification settings - Fork 42
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
Add API to pause target and wait for debugger to be suspended #339
Add API to pause target and wait for debugger to be suspended #339
Conversation
Hey @jonahgraham, this is what I assume the issue was alluding to, and it works fine on our IDE. Let me know how the changes look. |
src/gdb/GDBDebugSessionBase.ts
Outdated
* Sends a pause command to GDBBackend, and resolves when the debugger is | ||
* actually paused | ||
*/ | ||
protected async pause(): Promise<void> { |
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.
I think this name is questionable, since there's also pauseRequest
and continueRequest
, but I'm not sure what a good name would be. Something like pauseAndWait
?
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.
This looks quite close to what I was talking about - but I was hoping the logic for "waitPauseNeeded" could be in the new method.
i.e. have a single call that is "pauseIfNeeded" that can be awaited, and then at the end of the block "resumeIfNeeded" that is perhaps passed a token pauseIfNeeded returned (or elsewhere stored in the state).
sort of related topic brain dump:
This is a place I really like Python's with
statement, because in Python I would write something like:
with this.targetPaused():
// do some operations on a paused target
which will pause if needed at the beginning and resume automatically when leaving the block.
Yeah that with statement would be really nice. What about method decorators? It's not really the same cause it would be the beginning and end of the function. Also probably not worth the trouble, but it would be something like: const paused = <T extends []>(
target: GDBDebugSessionBase,
propertyKey: string,
descriptor: TypedPropertyDescriptor<(...args: T[]) => void>
) => {
const originalMethod = descriptor.value; // Original function
descriptor.value = function (...args: T[]) {
target.pause();
originalMethod?.apply(this, args);
target.continue();
};
};
export abstract class GDBDebugSessionBase extends LoggingDebugSession {
@paused
protected async setBreakPointsRequest(
response: DebugProtocol.SetBreakpointsResponse,
args: DebugProtocol.SetBreakpointsArguments
): Promise<void> {}
} unfortunately it can only cover the entire function. |
Signed-off-by: Luke Zhang <luke.zhang@microchip.com>
This solution is similar to eclipse-cdt-cloud#287, except the pause method is not based on an arbitrary timeout, but an emitted event from GDB that indicates the target is actually suspended. Signed-off-by: Luke Zhang <luke.zhang@microchip.com>
a39a229
to
b092c12
Compare
continue is a reserved keyword Signed-off-by: Luke Zhang <luke.zhang@microchip.com>
Signed-off-by: Luke Zhang <luke.zhang@microchip.com>
Signed-off-by: Luke Zhang <luke.zhang@microchip.com>
My lack of experience with typescript means I don't know if this is a good idea or not in this case.
That is my instinct for now. |
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.
This change looks correct - but it also looks like it exposes some issues in the tests when async is off.
For example I can see in logpoints/remote gdb-async-off/hits a logpoint.log
that at the moment that the SIGINT is sent to gdb, inferior happens to be paused, leading to this output:
[21:00:09.996 UTC] GDB signal: SIGINT to pid 13380
[21:00:09.996 UTC] GDB notify async: breakpoint-modified,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x000055555555513f",func="main",file="count.c",fullname="/home/runner/work/cdt-gdb-adapter/cdt-gdb-adapter/src/integration-tests/test-programs/count.c",line="4",thread-groups=["i1"],times="2",original-location="-source /home/runner/work/cdt-gdb-adapter/cdt-gdb-adapter/src/integration-tests/test-programs/count.c -line 4"}
[21:00:09.996 UTC] To client: {"seq":0,"type":"event","event":"output","body":{"category":"log","output":"Quit\n"}}
What this means is that the adapter thought the inferior was running, so sent a SIGINT, but in the time between the test and SIGINT being delivered, the inferior hit a breakpoint, so the SIGINT was interpreted as Quit instead of pause.
This is a fundamental problem with async mode because this race condition can not be detected or avoided. What I don't know is if/why this change exposes this problem more, or if it was just bad luck. I have restarted the tests in the first instance.
With async on by default for the last couple of years I don't think this matters too much. But we do need to have a clean run. If the above isn't enough information to resolve the issue, let me know and I can try to fix up these problematic test cases.
Signed-off-by: Luke-zhang-04 <Luke_zhang_04@protonmail.com>
f611a68
to
8b3628e
Compare
Unreliable behaviour due to race conditions is a known issue in sync mode. See eclipse-cdt-cloud#339 for more details.
Includes: - Refactor code to allow web extension - eclipse-cdt-cloud/cdt-gdb-adapter#328 - Improved handling of ContinuedEvent - eclipse-cdt-cloud/cdt-gdb-adapter#335 - Ensure 'interrupt' and 'disconnect' signals are sent before '-gdb-exit' - eclipse-cdt-cloud/cdt-gdb-adapter#338 - Add API to pause target and wait for debugger to be suspended - eclipse-cdt-cloud/cdt-gdb-adapter#339
Includes: - Refactor code to allow web extension - eclipse-cdt-cloud/cdt-gdb-adapter#328 - Improved handling of ContinuedEvent - eclipse-cdt-cloud/cdt-gdb-adapter#335 - Ensure 'interrupt' and 'disconnect' signals are sent before '-gdb-exit' - eclipse-cdt-cloud/cdt-gdb-adapter#338 - Add API to pause target and wait for debugger to be suspended - eclipse-cdt-cloud/cdt-gdb-adapter#339
Closes #295.
Code to suspend/continue the debug session when setting breakpoints are moved to a reusable function
pause
andcontinue
methods. Thepause
methodawait
s a promise which gets resolves when the target is actually suspended.This
pause
method is also used inGDBTargetDebugSession::disconnectRequest
.