labath wrote: > > I do want to spend some time discussing the relationship between stdout and > > stderr. The current implementation uses a separate mutex for each stream, > > which is not _un_reasonable, but I can see at least two other possible > > philosophies: > > > > 1. Since both of the streams will be going to the same terminal most of the > > time, it might make sense to use a single mutex for both of them, as that's > > sort of the only way to ensure consistent output. (Imagine the situation of > > printing the "stderr" of a CLI command while the status line is being > > updated) > > 2. Alternatively, we could say that stderr is for immediate and exceptional > > output where it is more important to get the message to the user than it > > being formatted beautifully. In this world, we could keep "stderr" as a > > regular unlocked stream. In specific cases, where synchronizing the output > > is particularly important to us (like the beforementioned case of "stderr" > > of a CLI command) we could synchronize its output by holding the "stdout" > > mutex while writing it. > > > > What do you think of that? I'm sort of leaning towards option two since > > stderr might be used in contexts where holding a mutex might not be > > completely safe (and the first option would make that even worse), and the > > current implementation with separate mutexes doesn't really guarantee > > "reasonable" stdout/err sequencing. > > I had a feeling this was going to come up... The tricky part is that, as you > pointed out, most of the time the output is going to same terminal. But on > the other hand, we totally support having those two streams go to totally > separate files and it feels wrong to force them to be synchronized. How about > a compromise between (1) and (2) where we use the same mutex when the > debugger is creating the StreamFile for stdout and stderr, but we use > separate murexes when they're set through the setter (and the SB API)?
How would that work? We'd check the value of the passed-in `FILE*` and choose a mutex based on whether it happens to be `stdout` ? I don't think I'd like that for several reasons: - it doesn't handle the case where `stdout/err` is redirected externally (it still locks even though it shouldn't) - it's doesn't let you create a terminal-like experience when embedding lldb-as-a-library (it doesn't lock even though it should) > Conceptually I'd also lean towards (2) but I worry about losing the benefits > the current approach brings. Deciding whether "the output is particularly > important" is a judgement call that we can't enforce at the API level. I like > how the current implementation makes it easy to do the right thing and hard > to do the wrong thing (or at least make you think about locking). If the > default is to not lock the stdout (the alternative of always locking is > equivalent to (1)) then I'm skeptical that we won't just end up with the same > outcome that we have with two mutexes. But with two mutexes you still don't get stdout<=>stderr synchronization, which means that stderr output can corrupt things you're writing to stdout. What the stderr mutex buys you is stderr<=>stderr synchronization, which is... maybe nice, but maybe also not necessary? FWIW, there is some precedent for unconditional stdout-stderr interaction: writes to `std::cerr` will automatically flush `std::cout` regardless of whether the two streams refer to the same terminal. And the `iostream` library allows you to connect arbitrary two streams in this way. So, I think we *could* say we "tie" debuggers output and error streams in this way, even if they are completely independent, because they are "our" stdout and stderr. https://github.com/llvm/llvm-project/pull/126630 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits