[Lldb-commits] [PATCH] D55582: [Reproducers] Add command reproducer

Pavel Labath via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Fri Dec 14 05:28:20 PST 2018

labath added a comment.

In D55582#1330715 <https://reviews.llvm.org/D55582#1330715>, @JDevlieghere wrote:

> I played around with this today:
> - I'm totally convinced that we should replay by swapping out stdin with a file from the reproducer. This makes this better overall.
> - I'm not convinced that capturing just stdin is an improvement. What I like about the current approach is that we don't have to bother with the `-o`/`-S` commands when replaying. We already have a mechanism to deal with them so I don't think it's unreasonable to piggyback on it, especially because this is how we display it to the user.

Hm.. so the way, I'd imagine this working is that `-o` and friends (as well as pretty much every other command line argument) would be captured by the SB recorder, once they cross the SB boundary. For the `-o` commands that would be the moment the driver calls `m_debugger.SetInputFileHandle` https://github.com/llvm-mirror/lldb/blob/master/tools/driver/Driver.cpp#L697 , followed by `m_debugger.RunCommandInterpreter` a couple of lines lower. So, the SB recorder would notice that we're changing what the debugger considers as it's `stdin`, and direct the "stdin" recorder (or create a new instance of it, or whatever), to capture it.

Then, during replay, the SB replayer would notice that the driver called `SBDebugger::SetInputFileHandle`, so it would create a fake `FILE*` object (or maybe just open the file containing the captured commands from the disk?), and pass *that* as the stdin handle. Then it could just call `SBDebugger::RunCommandInterperer` the same way as the driver did. And I am hoping that pretty much everything below `RunCommandInterpreter` could run oblivious to the fact that replay is taking place.

> On the other hand, I generally try to keep the code path the same between the regular and reproducer case, and processing the command line options in the reproducer case would reuse more of the existing code.

In this (imaginary) world, the recording/replay would only deal with the things that happen below the SB API. Anything that happens above it could only be glimpsed through it's effects on the SB. So, when initializing replay, as soon the driver notices the `--replay` argument it would just load that file, call `RunReplay` and be done. There wouldn't be a need for any `command-line-argument` recorder, or making sure the command line arguments match in some other way.

> Finally, we'd have to figure out a way to test this, because currently we rely on the commands provided/sourced through the command line to test the replay. How would we test this functionality when only capturing from stdin?

By "capturing stdin" I meant capturing anything which the `RunCommandInterpreter` considers as it's "stdin", i.e., everything where the debugger gets its commands from.

So, if we assume everything I said above is true, then capturing the command stream produced by processing the command-line arguments should work the same way as capturing the commands given interactively. So, perhaps the first step would be to make sure you can capture the commands issued via command-line args. This should be easily testable via something like:

  RUN: %lldb --record %t -b -o cmd1 -o cmd2 -O cmd3 ...
  RUN: %lldb --replay %t | FileCheck %s
  CHECK: make sure cmd1, cmd2, cmd3 got executed

Of course, capturing *real* stdin will come with additional challenges, both for recording and testing. For recording, we'll have to decide whether to try to capture raw stdin with enough fidelity so libedit can be driven through it, or we go one level higher, and try to capture the "cooked" command stream coming out of libedit. The testing strategy will depend on decision made here. In case we capture cooked commands, the situation should be very similar to command line options, so it might be enough to test by just passing the commands to the driver via stdin (`%lldb <%t/my_commands.txt`)  instead of via command line args. In case of low-level recordings, we may need to test using something which can provide a realistic-looking fake terminal such as pexpect (yikes). But even in that case, that should be only necessary to test the handling of funny line-editing operations (such as backspaces, cursor keys, etc.), and for general functionality redirecting stdin from file should be enough.



More information about the lldb-commits mailing list