Skip to content

How to keep stopped threads stopped on attaching? #528

@cwalther

Description

@cwalther

Currently, when attaching to an inferior that already has some stopped threads, these threads are resumed by an indiscriminate continue command in the final continueIfNeeded call at the end of the configuration phase. This is a problem for us: our systems can have breakpoints even when no debugger is attached, and when a thread stops on such a breakpoint, we want to be able to attach a debugger and analyze the thread in this stopped state, and not have it continued. It’s also inconsistent: continueIfNeeded is supposed to be a counterpart to pauseIfNeeded, and pausing was not needed in this case because there was a paused thread already, so there shouldn’t be a matching continue either.

This is easy enough to fix, and I had done it locally months ago, but now that I wanted to prepare it for submission in a PR, I found that it breaks half the tests. Drat. Apparently the thing I had regarded as a deficiency may in fact have been a deliberate feature.

What breaks the tests is that both GDB with a native target and gdbserver (unlike our stub) stop all threads on attaching, but the tests expect the process to be running (and hit a breakpoint) after the configuration phase.

If the tests expect that behavior, then maybe some users expect it as well, so maybe we shouldn’t just change it? It even makes sense in a way from the point of a GDB native (local, type gdb) or gdbserver (remote, type gdbtarget) user, because the stop-on-attach behavior of those two destroys the original state of the inferior anyway, and there is no use preserving the destroyed state, rather what should be preserved is the state before it was destroyed, which was most likely “all running”.

I need it changed though, not just for the reason above, but also (and that’s why I hadn’t bothered submitting it until now), in a situation that I am currently working on, this change is not just nice to have, but things would not work at all without it. The situation is that the stub is not attached to an inferior yet at the time GDB connects to it, but I only issue a -target-attach 1 & command just before the end of the configuration phase, after receiving breakpoints. This is possible when using the extended-remote target in GDB. (I can go into details separately on why I am doing this, if anyone is interested.) In this case, there are no threads yet at the beginning of the configuration phase, so pausing is not needed, but they arrive before the end of the configuration phase and may all be running at that time. An indiscriminate continue in that case results in an error “Cannot execute this command while the selected thread is running.” from GDB that takes down the whole debug session.

Any opinions on how to handle this?

I can think of these ways:

  • (may violate user expectations) Change the behavior unconditionally.
  • (easy way out) Make it configurable using an option in the attach arguments.
  • (perhaps harebrained) Define a way for a stub to advertise to the adapter that it is capable of preserving the stopped/running state of inferior threads on attaching and doesn’t want an indiscriminate continue command. Perhaps through a monitor command, or is there any other way for the adapter to talk directly to a stub?

CC @jreineckearm, @jonahgraham, @asimgunes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions