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

Reply via email to