Slow reverse execution when many signals fire
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 10.7k
- Forks
- 662
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 2
Description
If you record Firefox with the Gecko profiler running, reverse execution is very slow. This is because a lot of async signals are delivered. Every time we encounter a signal during reverse execution, we restore the full session state to the point of signal delivery and return a signal-stop to gdb. This necessarily requires cloning a checkpoint, doing some execution to get to the signal-stop, and doing that tens of thousands of times is slow. This is a waste when those signals are ignored by gdb, which they are by default.
gdb has no way to tell the agent which signals it can ignore. The only way to fix this would be to lazily restore the state (like we do for reverse-stepping): i.e., report the signal-stop to gdb without actually restoring the program state. Then if gdb tells us to reverse-continue immediately, we never have to restore the state. In practice, for an ignored signal gdb doesn't tell us to reverse-continue immediately; it reads registers, reads the byte at the current PC (twice!), and then does reverse-continue. So ReplayTimeline::reverse_continue would do a forward execution, and for every signal encountered, store the current registers and the byte at the current PC. Then it would report the last signal to gdb without restoring the state. If gdb just does read-registers and read-byte-at-PC and then reverse-continue, we can proceed to report the previous signal-stop without restoring any state. If gdb does anything else, we restore the state normally and continue.
What makes it a little more complicated is that we need to report the state just before the signal is delivered because during reverse execution, that's the state we report after the signal-stop. Currently we implement that by doing a reverse-singlestep after the forward-execution signal-stop. We need to avoid that. That will require an extra feature in ReplaySession to report that a signal is about to be delivered.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ReplayTimeline::reverse_continue and the existing reverse-singlestep handling for signal stops, then inspect ReplaySession for the state-reporting interfaces involved. Trace how gdb reads registers and the byte at the current PC after a signal-stop. Done means ignored signals can be traversed without restoring state, while other gdb operations still receive the normal pre-signal state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, linux
- Domain
- devtools, operating-systems, reverse-engineering
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100