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

Jonas Devlieghere via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Fri Dec 14 09:39:37 PST 2018

JDevlieghere added a comment.

In D55582#1331145 <https://reviews.llvm.org/D55582#1331145>, @labath wrote:

> 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.

Yes, this is how SB record/replay will work. I don't disagree with this
approach, it's just that, as I said in my earlier reply, I was hoping to get
the driver working without the need for the SB reproducers. Maybe I should give
up on that?

> 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.
> 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.

This is the tricky part though. Where and how are you going to do this? In my
opinion this shouldn't be the responsibility of the SB recorder. The latter
should be concerned with "serializing" and "deserializing" its input and
tracking what SB layer calls are being made. It should be relatively agnostic
of what the debugger does with that at a lower level.

The `FILE*` is particularly annoying. For the sake of argument let's say that
"serializing" a `FILE*` means writing its content to the reproducer, how would
we accomplish this? Maybe there's an API I don't know about, but wouldn't we
have to do this at the `fgets` level? For the command interpreter this is
either in libedit or in the IO handler (depending on the fidelity you touched
on below).

> 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.

I don't think we really differentiate between *real* stdin and a file. Even
when sourcing a file go through the IOHandler, so that should be pretty
transparent, unless you actually want to differentiate which, if I understand
correctly, wouldn't be needed with your proposed approach?



More information about the lldb-commits mailing list